[
  {
    "path": ".eslintignore",
    "content": "**/*.svg"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  root: true,\n  extends: [\"illa\"]\n}\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "# thx chakra ui template\nname: \"Bug Report\"\ndescription: \"File a bug report\"\nlabels: [\"bug\"]\nassignees:\n  - Aruseito\ntitle: \"[BUG] \"\nbody:\n  - type: \"markdown\"\n    attributes:\n      value: |\n        Thanks for creating an issue 😄!\n\n        Please search open/closed issues before submitting. Someone\n        might have asked the same thing before 😉!\n\n        If you want to discuss sth, please go to the [Discussion](https://github.com/illacloud/discussions)\n\n  - type: \"input\"\n    id: \"description\"\n    attributes:\n      label: \"Description\"\n      description: \"A brief description of the issue.\"\n      placeholder: |\n        When I ____, I expected ____ to happen but ____ happened instead.\n    validations:\n      required: true\n  - type: \"textarea\"\n    id: \"steps\"\n    attributes:\n      label: \"Steps to reproduce\"\n      description: |\n        Explain how to cause the issue in the provided reproduction.\n      value: |\n        1. Go to '...'\n        2. Click on '...'\n        3. Scroll down to '...'\n        4. See error\n  - type: dropdown\n    id: version\n    attributes:\n      label: Version\n      description: What version of our software are you running?\n      options:\n        - cloud\n        - self-host\n    validations:\n      required: true\n  - type: \"input\"\n    id: \"illa-builder-version\"\n    attributes:\n      label: \"ILLA Builder Version\"\n      description: \"The version of ILLA Builder you use.\"\n      placeholder: \"1.0.0\"\n    validations:\n      required: true\n  - type: \"input\"\n    id: \"browser\"\n    attributes:\n      label: \"Browser\"\n      description: \"The browser(s) this issue occurred with.\"\n      placeholder: \"Google Chrome 93\"\n  - type: \"checkboxes\"\n    id: \"operating-system\"\n    attributes:\n      label: \"Operating System\"\n      description: \"The operating system(s) this issue occurred with.\"\n      options:\n        - label: \"macOS\"\n        - label: \"Windows\"\n        - label: \"Linux\"\n  - type: \"textarea\"\n    id: \"additional-information\"\n    attributes:\n      label: \"Additional Information\"\n      description: |\n        Use this section to provide any additional information you might have\n        like screenshots, notes, or links to ideas.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Ask a question\n    url: https://github.com/orgs/illacloud/discussions\n    about: Ask questions and discuss topics with other community members\n  - name: Chat with other community members\n    url: https://discord.gg/illacloud\n    about: The official illa Cloud Discord community\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/custom.md",
    "content": "---\nname: Custom issue template\nabout: Describe this issue template's purpose here.\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: \"[Feature Requested] \"\nlabels: feature\nassignees: wenzhuo2022\n\n---\n\n**Is your feature request related to a problem? Please describe.** A clear and\nconcise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like** A clear and concise description of what you\nwant to happen.\n\n**Describe alternatives you've considered** A clear and concise description of\nany alternative solutions or features you've considered.\n\n**Additional context** Add any other context or screenshots about the feature\nrequest here.\n"
  },
  {
    "path": ".github/holopin.yml",
    "content": "organization: illa\ndefaultSticker: clnbuq0zt55350il7di08vxey\nstickers:\n  -\n    id: clnbuwccz20050il45drk120o\n    alias: Awesome ILLA App\n  -\n   id: clnbuz74g85880lkz0a5fyzis\n   alias: Awesome AI Agent\n  -\n    id: clnbv3uo903310fmgagvt713t\n    alias: AI Agent\n  -\n   id: clnbuq0zt55350il7di08vxey\n   alias: ILLA App\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "## 📝 Description\n\nAdd a brief description.\n\n## 💣 Is this a breaking change (Yes/No):\n\n- [ ] Yes\n- [x] No\n\n## 🚧 How to migrate?\n\nDon't need.\n\n## 📝 Additional Information\n\nlol"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 7\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 7\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - pinned\n  - security\n  - feature\n  - bug\n# Label to use when marking an issue as stale\nstaleLabel: stale\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  This issue has been automatically marked as stale because it has not had\n  recent activity. It will be closed if no further activity occurs. Thank you\n  for your contributions.\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: true\n"
  },
  {
    "path": ".github/workflows/build-all-in-one-image.yml",
    "content": "name: Build all in one image\n\non:\n  push:\n    branches:\n      - main\n  release:\n    types: [published]\n\nenv:\n  ILLA_MUI_LICENSE: ${{ secrets.ILLA_MUI_LICENSE }}\n  ILLA_BASE_PATH: /build\n\njobs:\n  build:\n    name: Build docker image\n    runs-on: ubuntu-latest\n    steps:\n      - name: Set build args\n        run: |\n          if [ \"${{ github.event_name }}\" = \"release\" ]; then\n            TAG=${{ github.event.release.tag_name }}\n            VERSION=v${TAG#illa-builder@}\n            echo \"IMAGE_TAG=${VERSION}\" >> $GITHUB_ENV\n            echo \"BUILD_SBE_BRANCH=main\" >> $GITHUB_ENV\n            echo \"BUILD_BE_BRANCH=main\" >> $GITHUB_ENV\n            echo \"BUILD_FE_BRANCH=${{ github.event.release.tag_name }}\" >> $GITHUB_ENV\n          else\n            echo \"IMAGE_TAG=${{ github.ref_name }}\" >> $GITHUB_ENV\n            echo \"BUILD_SBE_BRANCH=${{ github.ref_name }}\" >> $GITHUB_ENV\n            echo \"BUILD_BE_BRANCH=${{ github.ref_name }}\" >> $GITHUB_ENV\n            echo \"BUILD_FE_BRANCH=${{ github.ref_name }}\" >> $GITHUB_ENV\n          fi\n\n      - uses: actions/checkout@v4\n        with:\n          repository: illacloud/build-all-in-one-image\n          path: build-all-in-one-image\n\n      - uses: actions/checkout@v4\n        with:\n          repository: illacloud/illa-builder\n          path: illa-builder\n          submodules: true\n\n      - uses: actions/setup-node@v3\n        with:\n          node-version: 18.12.1\n\n      - uses: pnpm/action-setup@v2\n        with:\n          version: 8.7.0\n\n      - name: Build website\n        run: |\n          ls\n          cd illa-builder\n          pnpm install --frozen-lockfile\n          echo \"Building for $GITHUB_REF_NAME branch,ILLA APP ENV is $ILLA_APP_ENV\"\n          pnpm build-self\n          cp ./apps/builder/dist ../build-all-in-one-image/builder -r\n          cp ./apps/cloud/dist ../build-all-in-one-image/cloud -r\n          cd ..\n\n      - name: ls build-all-in-one\n        run: |\n          ls build-all-in-one-image\n\n      - name: ls cloud\n        run: |\n          ls build-all-in-one-image/cloud\n\n      - name: ls builder\n        run: |\n          ls build-all-in-one-image/builder\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v3\n\n      - name: Login to Docker Hub\n        uses: docker/login-action@v3\n        with:\n          username: ${{ secrets.DOCKER_LOGIN }}\n          password: ${{ secrets.DOCKER_PWD }}\n\n      - name: Build and push\n        uses: docker/build-push-action@v5\n        with:\n          context: ./build-all-in-one-image\n          platforms: linux/amd64,linux/arm64\n          push: true\n          tags: |\n            illasoft/illa-builder:${{ env.IMAGE_TAG }}\n            ${{ github.event_name == 'release' && startsWith(github.event.release.tag_name, 'illa-builder@') && 'illasoft/illa-builder:latest' || '' }}\n          build-args: |\n            FE=${{ env.BUILD_FE_BRANCH }}\n            BE=${{ env.BUILD_BE_BRANCH }}\n            SBE=${{ env.BUILD_SBE_BRANCH }}\n"
  },
  {
    "path": ".github/workflows/build-cname-docker.yml",
    "content": "name: Deploy cname image to k8s\n\non:\n  push:\n    branches:\n      - main\n\nenv:\n  ILLA_GOOGLE_MAP_KEY: ${{ secrets.ILLA_GOOGLE_MAP_KEY }}\n  ILLA_MIXPANEL_API_KEY: ${{ secrets.ILLA_MIXPANEL_API_KEY }}\n  ILLA_MUI_LICENSE: ${{ secrets.ILLA_MUI_LICENSE }}\n  ILLA_SENTRY_AUTH_TOKEN: ${{ secrets.ILLA_SENTRY_AUTH_TOKEN }}\n  DO_CLUSTER: ${{ secrets.DO_CLUSTER }}\n  DOCKER_LOGIN: ${{ secrets.DOCKER_LOGIN }}\n  DOCKER_PWD: ${{ secrets.DOCKER_PWD }}\n  ILLA_BASE_PATH: /builder\n\njobs:\n  build:\n    name: Build website\n    runs-on: ubuntu-latest\n    environment:\n      name:\n        ${{ (github.ref == 'refs/heads/main') && 'production' || (github.ref ==\n        'refs/heads/develop') && 'test' || (github.ref == 'refs/heads/beta') &&\n        'beta' }}\n    env:\n      ILLA_API_BASE_URL: ${{ vars.ILLA_API_BASE_URL }}\n      ILLA_APP_ENV: ${{ vars.ILLA_APP_ENV }}\n      ILLA_BUILDER_URL: ${{ vars.ILLA_BUILDER_URL }}\n      ILLA_CLOUD_URL: ${{ vars.ILLA_CLOUD_URL }}\n      ILLA_MARKET_URL: ${{ vars.ILLA_MARKET_URL }}\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          submodules: true\n\n      - uses: actions/setup-node@v3\n        with:\n          node-version: 18.12.1\n\n      - uses: pnpm/action-setup@v2\n        with:\n          version: 8.7.0\n\n      - name: Install dependencies\n        run: pnpm install --frozen-lockfile\n\n      - name: Install doctl\n        uses: digitalocean/action-doctl@v2\n        with:\n          token: ${{ secrets.DO_TOKEN }}\n\n      - name: Install kubectl\n        run: |\n          sudo snap install kubectl --classic\n\n      - name: Setup kubectl\n        run: |\n          doctl kubernetes cluster kubeconfig save $DO_CLUSTER\n          kubectl version\n\n      - name: Build website\n        run: |\n          echo \"Building for $GITHUB_REF_NAME branch,ILLA APP ENV is $ILLA_APP_ENV\"\n          pnpm build-cloud\n      - name: Build Docker\n        run: |\n          docker build --cache-from=illa-builder-cname-frontend -f Dockerfile -t illa-builder-cname-frontend .\n\n      - name: Push application Docker image\n        run: |\n          docker login -u $DOCKER_LOGIN -p $DOCKER_PWD\n          docker tag illa-builder-cname-frontend \"illasoft/illa-builder-cname-frontend:$GITHUB_REF_NAME\"\n          docker push \"illasoft/illa-builder-cname-frontend:$GITHUB_REF_NAME\"\n\n      - uses: actions/checkout@v4\n        with:\n          repository: illacloud/k8s-application-do\n          token: ${{ secrets.ILLA_BOT_TOKEN }}\n          path: k8s-application-do\n\n      - name: Deploy to Kubernetes\n        run: |\n          cd k8s-application-do/namespace-$ILLA_APP_ENV\n          kubectl apply -f ./illa-builder-cname-frontend/ -n $ILLA_APP_ENV\n          kubectl -n $ILLA_APP_ENV rollout restart deployment illa-builder-cname-frontend\n"
  },
  {
    "path": ".github/workflows/close-stale-issues-and-PRs.yml",
    "content": "name: \"Close stale issues and PR\"\non:\n  schedule:\n    - cron: \"30 1 * * *\"\n\njobs:\n  stale:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/stale@v7\n        with:\n          stale-issue-message:\n            \"This issue is stale because it has been open 5 days with no\n            activity. Remove stale label or comment or this will be closed in 2\n            days.\"\n          stale-pr-message:\n            \"This PR is stale because it has been open 5 days with no activity.\n            Remove stale label or comment or this will be closed in 2 days.\"\n          close-issue-message:\n            \"This issue was closed because it has been stalled for 2 days with\n            no activity.\"\n          days-before-issue-stale: 5\n          days-before-pr-stale: 5\n          days-before-issue-close: 2\n          days-before-pr-close: 2\n          exempt-issue-labels:\n            \"bug,feature,help wanted,invalid,hacktoberfest,hacktoberfest\n            developing\"\n          exempt-all-assignees: true\n"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "content": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# You may wish to alter this file to override the set of languages analyzed,\n# or to provide custom queries or build logic.\n#\n# ******** NOTE ********\n# We have attempted to detect the languages in your repository. Please check\n# the `language` matrix defined below to confirm you have the correct set of\n# supported CodeQL languages.\n#\nname: \"CodeQL\"\n\non:\n  push:\n    branches: [ main, develop ]\n  pull_request:\n    # The branches below must be a subset of the branches above\n    branches: [ main ]\n  schedule:\n    - cron: '40 0 * * 3'\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ 'javascript' ]\n        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]\n        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v3\n\n      # Initializes the CodeQL tools for scanning.\n      - name: Initialize CodeQL\n        uses: github/codeql-action/init@v2\n        with:\n          languages: ${{ matrix.language }}\n          # If you wish to specify custom queries, you can do so here or in a config file.\n          # By default, queries listed here will override any specified in a config file.\n          # Prefix the list here with \"+\" to use these queries and those in the config file.\n\n          # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs\n          # queries: security-extended,security-and-quality\n\n\n      # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).\n      # If this step fails, then you should remove it and run the build manually (see below)\n      - name: Autobuild\n        uses: github/codeql-action/autobuild@v2\n\n      # ℹ️ Command-line programs to run using the OS shell.\n      # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun\n\n      #   If the Autobuild fails above, remove it and uncomment the following three lines.\n      #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.\n\n      # - run: |\n      #   echo \"Run, Build Application using script\"\n      #   ./location_of_script_within_repo/buildscript.sh\n\n      - name: Perform CodeQL Analysis\n        uses: github/codeql-action/analyze@v2\n"
  },
  {
    "path": ".github/workflows/deploy-to-flyio.yml",
    "content": "name: Deploy to flyio\n\non:\n  push:\n    branches:\n      - main\n\nenv:\n  ILLA_GOOGLE_MAP_KEY: ${{ secrets.ILLA_GOOGLE_MAP_KEY }}\n  ILLA_MIXPANEL_API_KEY: ${{ secrets.ILLA_MIXPANEL_API_KEY }}\n  ILLA_AMPLITUDE_API_KEY: ${{ secrets.ILLA_AMPLITUDE_API_KEY }}\n  ILLA_MUI_LICENSE: ${{ secrets.ILLA_MUI_LICENSE }}\n  ILLA_SENTRY_AUTH_TOKEN: ${{ secrets.ILLA_SENTRY_AUTH_TOKEN }}\n\njobs:\n  build:\n    name: Build website\n    runs-on: ubuntu-latest\n    environment:\n      name: \"production\"\n    env:\n      ILLA_API_BASE_URL: ${{ vars.ILLA_API_BASE_URL }}\n      ILLA_APP_ENV: ${{ vars.ILLA_APP_ENV }}\n      ILLA_BUILDER_URL: ${{ vars.ILLA_BUILDER_URL }}\n      ILLA_CLOUD_URL: ${{ vars.ILLA_CLOUD_URL }}\n      ILLA_MARKET_URL: ${{ vars.ILLA_MARKET_URL }}\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          submodules: true\n\n      - uses: actions/setup-node@v3\n        with:\n          node-version: 18.12.1\n\n      - uses: pnpm/action-setup@v2\n        with:\n          version: 8.7.0\n\n      - name: Install dependencies\n        run: pnpm install --frozen-lockfile\n\n      - name: Build website\n        run: |\n          echo \"Building for $GITHUB_REF_NAME branch,ILLA APP ENV is $ILLA_APP_ENV\"\n          pnpm build-cloud\n\n      - uses: superfly/flyctl-actions/setup-flyctl@master\n      - run: flyctl deploy --remote-only\n        env:\n          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/issue-mark-assignees.yml",
    "content": "name: Issue Mark Assignees\n\non:\n  issue_comment:\n    types: [created, edited]\n\njobs:\n  mark-assignees:\n    runs-on: ubuntu-latest\n    steps:\n      - name: mark-assignees\n        uses: actions-cool/issues-helper@v3\n        with:\n          actions: 'mark-assignees'\n          token: ${{ secrets.ILLA_BOT_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n.idea\n.DS_Store\n.vscode\n.turbo"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"packages/illa-public-component\"]\n\tpath = packages/illa-public-component\n\turl = https://github.com/illacloud/illa-public-component.git\n\tbranch = beta\n[submodule \"packages/illa-design\"]\n\tpath = packages/illa-design\n\turl = https://github.com/illacloud/illa-design.git\n"
  },
  {
    "path": ".husky/commit-msg",
    "content": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\npnpm commitlint --edit \"${1}\""
  },
  {
    "path": ".husky/pre-commit",
    "content": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\npnpm ts-check && pnpm lint && pnpm lint-staged\n"
  },
  {
    "path": ".lintstagedrc.mjs",
    "content": "export default {\n  \"*.{ts,tsx}\": [\"prettier --write\"],\n}\n"
  },
  {
    "path": ".npmrc",
    "content": "registry = https://registry.npmjs.org/"
  },
  {
    "path": ".prettierignore",
    "content": "# snapchat\n__snapshots__/**\n*.test.tsx.snap\nILLA_PROTO.*\n*.md\n*.mdx\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"bracketSpacing\": true,\n  \"jsxBracketSameLine\": false,\n  \"jsxSingleQuote\": false,\n  \"printWidth\": 80,\n  \"proseWrap\": \"always\",\n  \"semi\": false,\n  \"singleQuote\": false,\n  \"tabWidth\": 2,\n  \"trailingComma\": \"all\",\n  \"arrowParens\": \"always\",\n  \"plugins\": [\"@trivago/prettier-plugin-sort-imports\"],\n  \"importOrder\": [\"<THIRD_PARTY_MODULES>\",\"^@illa-design/(.*)$\", \"^@/(.*)$\", \"^[./]\"],\n  \"importOrderSeparation\": false,\n  \"importOrderSortSpecifiers\": true\n}"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the\n  overall community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct is in effect in all community spaces and applies when someone is officially representing the community in public. Representation includes activities like using an official email, posting from an official social media account, or acting as a designated representative at online or offline events.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\nopensource@illasoft.com.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series\nof actions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior, harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within\nthe community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\nhttps://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct\nenforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at\nhttps://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# How to Contribute\n\nIlla-builder is one of Illa’s open-source projects that is under very active development. We’re still working out the kinks to make contributing to this project as easy and transparent as possible, \nbut we’re not quite there yet. Hopefully this document makes the process for contributing clear and answers some questions that you may have.\n\n## Open Development\n\nAll work on Illa-builder happens directly on GitHub. Both core team members and external contributors send pull requests which go through the same review process.\n\n## Your First Pull Request\n\nWorking on your first Pull Request? You can learn how from this free video series:\n\n[How to Contribute to an Open-Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)\n\n## Sending a Pull Request\n\nThe core team is monitoring pull requests. We will review your pull request and either merge it, request changes to it, or close it with an explanation. For API changes we may need to fix our \ninternal uses at Illa, which could cause some delay. We’ll do our best to provide updates and feedback throughout the process.\n\n**Before submitting a pull request**, please make sure the following is done:\n\n1. Fork the repository and create your branch from `beta`.\n2. Run `git submodule init && git submodule update` in the repository root.\n3. Run `pnpm install` in the repository root.\n4. If you’ve fixed a bug or added code that should be tested!\n5. Format your code with prettier `pnpm format`.\n6. Make sure your code lint’s `pnpm lint`.\n\nFor additional information on contributing, you can check out our landing page [Hacktoberfest2023 | Illa Cloud](https://www.illacloud.com/hacktoberfest2023?utm_medium=social&utm_source=twitter&utm_campaign=twitter-social-hacktoberfest2023-illa-0925).\n\n## Utilizing Docker (Recommended)\n\nIlla recommends utilizing a docker all-in-one image for making contributions towards illa-builder: \n\n### Creating an Official Image\nTo create an official illa-soft image, execute command:\n\n`docker pull illasoft/illa-builder:latest`\n\nThis command will pull the illa-soft official image and run it in your docker environment.\nBy default, all configurations are for running a production environment. When successfully pulled, Logs will display the ILLA BUILDER BANNER in your docker environment. \n\nNote: You must have the docker image configured for self-host prerequisites.\n\nFor more information on running an Image, check out [Docker all-in-one Image](https://www.illacloud.com/docs/docker-all-in-one-image).\n\n### Deploying Illa Builder via Docker\n\nAll deploys default auto-config settings for a production environment unless your deployment is customized. It's highly recommended deploying with our auto-deploy tools, ILLA CLI.\n\nTo install ILLA-CLI:\n\n```\n#### download illa cli binary file\n> wget https://github.com/illacloud/illa/releases/latest/download/illa-x86_64-linux.tar.gz\n\n#### unpack the file\n> tar -zxvf illa-x86_64-linux.tar.gz\n\n> cd illa-x86_64-linux\n\n> chmod +x illa\n\n#### run the illa cli\n> ./illa\n```\n\n### Contribution Self-host Prerequisites\n\n- You have the latest version of [Node.js LTS](https://nodejs.org/en/download) and [pnpm](https://pnpm.io/installation) installed.\n- You are familiar with Git.\n- You have docker-all-in-one, illa-cli installed, and illa-builder-backend running on your local machine.\n \n### Confirm self-host prerequisites\n\nNext, check the prerequisites of self-host, execute command:\n\n`./illa doctor`\n\nWhen it's run is complete you should receive a message in green stating \"Success! The minimum requirement for deploying ILLA has been satisfied.\"\nPorts 5432, 9999, 8000, should remain open for deploying ILLA Builder.\n\nFor more information on ILLA CLI and Other Operations check out [ILLA-CLI](https://www.illacloud.com/docs/illa-cli).\n\n### Deploy self-host locally\n\nAfter you have confirmed you meet the minimum requirements for deploying Illa Builder, deploy via either port 5432, 8000, 9345, 9999, or 10000. \nTo deploy Illa Builder via self-host locally, execute command:\n\n`./illa deploy --self --port <PORT>` change `<PORT>` with port number\n\nThis will deploy illa-builder-backend at port `<PORT>`. Then execute command:\n\n`docker run -d -p <PORT>:2022 illasoft/illa-builder:latest` change `<PORT>` with port number\n\nCheck your docker containers and you should find an illasoft/illabuilder container running at Port `<PORT>`:2022.\n\nIf you deploy executing the deploy command as:\n\n`./illa deploy --self`\n\nThis will auto-deploy illa-builder on port 80; you'll be able to access illa-builder at `http://localhost:80`.\n\nOnce you have successfully deployed illa builder and have received the Illa Builder Started, please visit `http://localhost:<PORT>` response,\ngo to the website and login using the credentials:\n\nUsername: root \n\nPassword: password (self-host mode only). \n\nAlternatively, you can deploy/ or change the port by which Illa Builder can be accessed; execute command:\n\n```\n# the port which ILLA Builder can be accessed on can be changed\n# the <MOUNT_PATH> is the custom mount path of ILLA Builder, the default value is a path under the user home directory if not filled\n> illa deploy --self --port=10000 --mount=<MOUNT_PATH>\n```\n\nThe Docker all-in-one Image is built based on the official Debian Image, which makes the username and password for the container the same as the image, \nyou have the option to omit or change the username and password at your discretion.\n\nFor more information on other operations, check out [ILLA-CLI](https://www.illacloud.com/docs/illa-cli).\n\nIf needing to run a self-host production workflow environment version based on deployment at port `<PORT>`, input the following to `apps/builder/env.self`\n\n```\nILLA_API_BASE_URL=localhost:<PORT>  # this is your backend address, if this is not present, it will use the default backend address, location.origin, update <PORT> to port number\nILLA_INSTANCE_ID=SELF_HOST_CLOUD\nILLA_APP_VERSION=0.0.0\nILLA_APP_ENV=production\n```\n\nOnce illa-builder-backend services are running, you can utilize several commands such as:\n\n- `pnpm build-self` creates a self-host production version for the illa-builder frontend repository.\n- `pnpm lint` checks the code style.\n- `pnpm format` format your code with prettier\n- `pnpm dev` preview in real time while coding with cloud version\n- `pnpm dev:self` preview in real time while coding with self-host version\n- `pnpm build-cloud` creates a cloud production version with illa-builder.\n\nFor more information on contributing to illa-builder-frontend check out our [Build All-In-One-Image Dockerfile](https://github.com/illacloud/build-all-in-one-image/blob/main/dockerfile).\n\n\n### Modifying an Image\n\nBy default, all configuration settings for a Docker all-in-one Image are for running a production environment. To modify a created Image, execute command:\n\n`docker exec -it illa_builder /bin/bash`\n\nThe default configuration settings for the Docker all-in-one Image include all environment parameters. You have the option to modify these parameters when you run the container to \naccommodate specific needs or to connect to a database instance. You can review the default configuration parameters at [config.go](https://github.com/illacloud/builder-backend/blob/main/src/utils/config/config.go). \n\n\n### Additional Self-hosting Information\n\nYou can self-host locally with ILLA CLI, Docker compose, k8s helm etc. We’ve repeatedly optimized the self-host process to enable you to make self-host and software deployments in just a few minutes. \nCompared to the cloud, you can use ILLA products more securely and reliably, and you can use ILLA Builder by simply visiting the deployment site after hosting and deploying Builder locally.\n\n### Customized Development Workflow Example\n\nLatest version of Node.js LTS and pnpm are installed/ running. Install from links above following instructions.\n\nClone the illa-builder repository, and run `pnpm install` to fetch its dependencies. Customize your language parameter, i.e. NEXT.js, and create a development workflow environment; input the following to `apps/builder/.env.development.local` And `apps/cloud/.env.development.local`\n\n```\nILLA_API_BASE_URL=localhost:<PORT>  # this is your backend address, if this is not present, it will use the default backend address, location.origin, update <PORT> to port number\nILLA_INSTANCE_ID=SELF_HOST_CLOUD\nILLA_APP_VERSION=0.0.0\nILLA_APP_ENV=development\nILLA_USE_HTTPS=false\nILLA_BUILDER_URL=http://localhost:3000\nILLA_CLOUD_URL=http://localhost:5173\n```\n\n\n### Deploying Manually\n\nAlternatively, you can deploy Illa Builder manually using Docker Compose and Kubernetes.\n\nCheck out instructions for deploying with [Docker Compose](https://github.com/illacloud/deploy-illa-manually/blob/main/docker-compose/README.md), and Instructions for deploying with [Kubernetes](https://github.com/illacloud/deploy-illa-manually/blob/main/kubernetes/README.md).\n\nFor more information on self-hosting, please see the ILA CLI, Docker Compose, and k8s helm boot pages. If you have difficulties with your self-deployment, please review the \n[Deploy Introduction](https://www.illacloud.com/docs/deploy-introduction) Self-host/ Deploy Manually instructions; you can also contact us on GitHub or at business@illasoft.com.\n\n\n## For Rust Developer's\n\nAs a Rust Developer, you can easily build+install the latest ILLA CLI release with cargo, execute command:\n\n`cargo install illa`\n\nThe cargo tool will download the ILLA CLI with its source dependencies, build and install it into the cargo bin path so that we can run it. \n\nOnce installed, you can run the ILLA CLI utilizing the illa command:\n\n`./illa <COMMAND>`\n\nIlla CLI is a tool for hosting ILLA Builder in your local environment. Once installed, execute command `./illa deploy --self --port <PORT>`, update `<PORT>` to port number. Again, this will deploy illa-builder-backend at port `<PORT>`. \nIf needing to modify your `.env.self`, input:\n\n```\nILLA_API_BASE_URL=localhost:<PORT> # update <PORT> to port number\nILLA_INSTANCE_ID=SELF_HOST_CLOUD\nILLA_APP_VERSION=0.0.0\nILLA_APP_ENV=development\nILLA_USE_HTTPS=false\n```\n\n## For GO Developer's\n\nThere is currently no formal documentation for setup with GO, however you're encouraged to check out and contribute to builder-backend here [illa-builder-backend](https://github.com/illacloud/builder-backend).\n"
  },
  {
    "path": "Dockerfile",
    "content": "# -------------------\n# build runner images\nFROM nginx:stable-alpine as runner\nRUN ls -alh /etc/nginx/\n\nRUN apk add --no-cache \\\n    bash \\\n    sed\n\n\n## copy frontend\nCOPY nginx.conf /etc/nginx/nginx.conf\nCOPY illa-builder-frontend.conf /etc/nginx/conf.d/illa-builder-frontend.conf\nCOPY ./apps/builder/dist /opt/illa/illa-builder-frontend\nRUN rm /etc/nginx/conf.d/default.conf\n\n# test nginx\nRUN nginx -t\n\n# HEALTHCHECK --interval=5s --timeout=3s CMD curl -fs http://127.0.0.1:80/status?src=docker_health_check -H\"Host:localhost\" || exit 1\n\n# run\nEXPOSE 80\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README-CN.md",
    "content": "\n<div align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img alt=\"ILLA Design Logo\" width=\"120px\" height=\"120px\" src=\"https://github.com/illacloud/.github/blob/main/assets/images/illa-logo.svg\"/>\n  </a>\n</div>\n\n<h1 align=\"center\"><a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">ILLA Builder</a></h1>\n\n<p align=\"center\">ILLA 是一个强大的开源低代码平台，供开发人员构建内部工具。 通过使用 ILLA 的组件和操作库，开发人员可以节省大量构建工具的时间。 </p>\n\n<div align=\"center\">\n<a href=\"https://github.com/illacloud/illa-builder/blob/beta/README.md\">English</a> | 简体中文 | <a href=\"https://github.com/illacloud/illa-builder/blob/beta/README-DE.md\">Deutsch</a> | <a href=\"https://github.com/illacloud/illa-builder/blob/beta/README-JP.md\">日本語</a>\n</div>\n\n<br>\n<p align=\"center\">\n<a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n  <img width=\"800\" alt=\"GitHub - Readme - jp\" src=\"https://github.com/illacloud/illa-builder/assets/112603073/f3e7105a-b50d-461b-b3b7-a031c43d9465\">\n</a>\n</p>\n\n[![Discord](https://img.shields.io/badge/chat-Discord-7289DA?logo=discord)](https://discord.gg/illacloud)\n[![Twitter](https://img.shields.io/badge/Twitter-1DA1F2?logo=x&logoColor=white)](https://twitter.com/illa_cloud)\n[![Discussions](https://img.shields.io/badge/discussions-GitHub-333333?logo=github)](https://github.com/orgs/illacloud/discussions)\n[![Crowdin](https://badges.crowdin.net/illa-builder/localized.svg)](https://crowdin.com/project/illa-builder)\n[![CI (Rolling and Humble)](https://github.com/illacloud/illa-builder/actions/workflows/build-docker.yml/badge.svg?query=branch%3Amain)](https://github.com/illacloud/illa-builder/actions/workflows/build-docker.yml?query=branch%3Amain)\n[![PR:s Welcome](https://img.shields.io/badge/PR:s-welcome-brightgreen.svg)](https://github.com/illacloud/illa-builder/pulls)\n[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=socialflat-square&)](https://www.apache.org/licenses/LICENSE-2.0.html)\n\n## 🚀开始体验ILLA\n试用ILLA的最方便的方式是注册并登录 [ILLA Cloud](https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme)。\n\n您还可以[本地部署](https://github.com/illacloud/illa-builder/blob/main/README-CN.md#%E6%9C%AC%E5%9C%B0%E9%83%A8%E7%BD%B2)ILLA工具（Docker、Docker Compose和Kubernetes）。\n<p>\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\"><img src=\"https://raw.githubusercontent.com/illacloud/.github/main/assets/images/ILLA%20Cloud.png\" height=120 />\n</p>\n\n\n\n## ✨ 特色功能\n\n1. ⚽ **实时协作：** 我们可以一起实时创建内容。\n2. 🤖 **自动化支持：** 连接一切组件，并在 5 秒内实现自动化。\n3. 🖥 **本地部署：** 支持Docker和k8s\n4. 📝 **Page支持：** 创建内容丰富且 UI 友好的工具的基础。\n5. 🎨 **由 [ILLA Design](https://github.com/illacloud/illa-design) 提供支持：** 组件不应限制您的想象力。\n\n## 本地部署\n    \nILLA CLI 使您能够以超乎想象的速度部署 ILLA Builder。 [单击此处](https://docs.illacloud.com/self-hosted-deployment) 了解更多详细信息。\n</br>部署成功后，您可以使用邮箱注册或使用以下信息登录：\n<p align=\"left\">Username (email): root</p>\n<p align=\"left\">Password: password</p>\n    \n## 使用指南\n\n#### 🎯 第 1 步：连接到您的数据库\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/sql.jpeg\">\n  </a>\n</p>\n\n#### 🎨 第 2 步：使用内置组件构建 UI\n将组件拖动到画布来构建您的 UI。我们在 Illa Builder 和 Illa Design 中提供了数十种组件，包括图表、表格、表单等。当组件重叠时，它们的位置会自动调整，使得布局开发变得简单灵活。\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/edit-ui-with-components.gif\">\n  </a>\n</p>\n\n#### 🔌 第 3 步：连接您的数据\n通过我们的 GUI 数据连接器连接到 MySQL 或 REST API。我们未来将添加10多个数据库和API。\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/connect-your-data.gif\">\n  </a>\n</p>\n\n#### 🚀 第 4 步：部署您的应用\n部署您的应用程序并自行托管。\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/deploy.gif\">\n  </a>\n</p>\n\n\n## 💬 社区\n\n加入 ILLA 社区，分享您的想法、建议或问题，并与其他用户和贡献者交流。\n\n加入微信群：  \n![IMG_8665](https://github.com/user-attachments/assets/eeb23db8-d42f-45b2-be65-bce74a8c8b85)\n\n\n\n\nDiscord与Github社区入口\n\n[![Chat on Discord](https://img.shields.io/badge/chat-Discord-7289DA?logo=discord)](https://discord.gg/illacloud)   [![Discuss on GitHub](https://img.shields.io/badge/discussions-GitHub-333333?logo=github)](https://github.com/orgs/illacloud/discussions)   \n\n## 🌱 贡献\n\n考虑为ILLA社区作出贡献？非常感谢和欢迎大家对ILLA的各种贡献！查看[贡献指南](./CONTRIBUTING.md)，了解有关如何参与的详细信息。\n<p>感谢 ❤︎  <a href=\"https://github.com/illacloud/illa-builder/graphs/contributors\">贡献者们</a> 为ILLA做出的贡献</p>\n\n## 📢 翻译\n\n`apps/builder/src/i18n/locale/*`目录是通过Crowdin自动更新的。如果你想作出贡献，请查看我们的[官方翻译页面](https://crowdin.com/project/illa-builder)。\n\n## 版权说明\n\nILLA是 [Apache License 2.0](./LICENSE)。\n"
  },
  {
    "path": "README-DE.md",
    "content": "\n<div align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img alt=\"ILLA Design Logo\" width=\"120px\" height=\"120px\" src=\"https://github.com/illacloud/.github/blob/main/assets/images/illa-logo.svg\"/>\n  </a>\n</div>\n\n<h1 align=\"center\"><a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">ILLA Builder</a></h1>\n\n<p align=\"center\">ILLA ist eine robuste, quelloffene Low-Code-Plattform für Entwickler zur Erstellung interner Tools. Durch die Verwendung der ILLA-Bibliothek von Komponenten und Aktionen können Entwickler viel Zeit bei der Erstellung von Tools sparen. </p>\n\n<div align=\"center\">\n<a href=\"https://github.com/illacloud/illa-builder/blob/beta/README.md\">English</a> | <a href=\"https://github.com/illacloud/illa-builder/blob/beta/README-CN.md\">简体中文</a> | Deutsch | <a href=\"https://github.com/illacloud/illa-builder/blob/beta/README-JP.md\">日本語</a>\n</div>\n<br>\n<p align=\"center\">\n<a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n  <img width=\"800\" alt=\"GitHub - Readme - jp\" src=\"https://github.com/illacloud/illa-builder/assets/112603073/1a4b64ac-1384-4eaf-9b3c-9b0b278b40fe\">\n</a>\n</p>\n\n[![Discord](https://img.shields.io/badge/chat-Discord-7289DA?logo=discord)](https://discord.gg/illacloud)\n[![Twitter](https://img.shields.io/badge/Twitter-1DA1F2?logo=x&logoColor=white)](https://twitter.com/illa_cloud)\n[![Discussions](https://img.shields.io/badge/discussions-GitHub-333333?logo=github)](https://github.com/orgs/illacloud/discussions)\n[![Crowdin](https://badges.crowdin.net/illa-builder/localized.svg)](https://crowdin.com/project/illa-builder)\n[![CI (Rolling and Humble)](https://github.com/illacloud/illa-builder/actions/workflows/build-docker.yml/badge.svg?query=branch%3Amain)](https://github.com/illacloud/illa-builder/actions/workflows/build-docker.yml?query=branch%3Amain)\n[![PR:s Welcome](https://img.shields.io/badge/PR:s-welcome-brightgreen.svg)](https://github.com/illacloud/illa-builder/pulls)\n[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=socialflat-square&)](https://www.apache.org/licenses/LICENSE-2.0.html)\n\n## 🚀Starten Sie\nUm ILLA auszuprobieren, ist es am bequemsten, sich zu registrieren und einzuloggen bei[ILLA Cloud](https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme)\n\nSie können ILLA-Utilities auch manuell bereitstellen und selbst hosten [Docker, docker-compose, und k8s](https://github.com/illacloud/illa-builder/blob/main/README-KR.md#%EC%9E%90%EC%B2%B4-%ED%98%B8%EC%8A%A4%ED%8C%85).\n\n<p>\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\"><img src=\"https://raw.githubusercontent.com/illacloud/.github/main/assets/images/ILLA%20Cloud.png\" height=120 />\n</p>\n\n\n\n## ✨ Eigenschaften\n\n1. ⚽ **Kollaboration in Echtzeit:** Wir können alles gemeinsam in Echtzeit erstellen.\n2. 🤖 **Automatisierte Unterstützung:** Verbinden Sie alles und automatisieren Sie es in 5 Sekunden\n3. 🖥 **Selbst gehostet:** unterstützt Docker & k8s\n4. 📝 **eitenunterstützung:** Die Basis für die Erstellung eines inhaltsreichen und UI-freundlichen Tools.\n5. 🎨 ** [Angetrieben von ILLA Design](https://github.com/illacloud/illa-design):** : Komponenten sollten Ihre Fantasie nicht einschränken.\n\n## Selbst gehostet\n    \nThe ILLA CLI enables you to deploy ILLA Builder faster than your imagination. [Click here](https://docs.illacloud.com/self-hosted-deployment) \n for more details. After successfully deployed, you can register with email address or log in with the following information:\n\n<p align=\"left\">Benutzername (E-Mail): root</p>\n<p align=\"left\">Kennwort: password</p>\n\n\n    \n## Wie Sie Ihr Werkzeug bauen\n\n#### 🎯 Schritt 1: Verbinden Sie sich mit Ihrer Datenbank\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/sql.jpeg\">\n  </a>\n</p>\n\n#### 🎨 Schritt 2: Erstellen der Benutzeroberfläche mit integrierten Komponenten\nErstellen Sie Ihre Benutzeroberfläche, indem Sie Komponenten auf die Leinwand ziehen. Wir bieten Dutzende von Komponenten wie Diagramme, Tabellen, Formulare und viele mehr in Illa Builder und Illa Design. Wenn sich Komponenten überschneiden, wird ihre Position automatisch angepasst, was die Layoutentwicklung einfach und flexibel macht.\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/edit-ui-with-components.gif\">\n  </a>\n</p>\n\n#### 🔌 Schritt 3: Verbindung zu Ihren Daten\nStellen Sie eine Verbindung zu MySQL oder REST API über unsere GUI-Datenkonnektoren her. Wir werden bald mehr als 10 Datenbanken und APIs hinzufügen.\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/connect-your-data.gif\">\n  </a>\n</p>\n\n#### 🚀 Schritt 4: Bereitstellen der Anwendung\nStellen Sie Ihre Anwendung bereit oder hosten Sie sie selbst.\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/deploy.gif\">\n  </a>\n</p>\n\n\n## 💬 Gemeinschaft\n\nJoin ILLA Community to share your ideas, suggestions, or questions and connect with other users and contributors.\n[![Chat on Discord](https://img.shields.io/badge/chat-Discord-7289DA?logo=discord)](https://discord.gg/illacloud)   [![Discuss on GitHub](https://img.shields.io/badge/discussions-GitHub-333333?logo=github)](https://github.com/orgs/illacloud/discussions)   \n\n## 🌱 Beitragender\nDenken Sie über eine Spende nach? Alle Arten von Beiträgen zur ILLA werden sehr geschätzt und sind willkommen! In unserem Beitragsleitfaden finden Sie Einzelheiten darüber, wie Sie sich beteiligen können.\n\nWir freuen uns über alle Beiträge unserer <a href=\"https://github.com/illacloud/illa-builder/graphs/contributors\">❤︎ Mitwirkenden!</a>\n\n## 📢 Übersetzen\n\nDie Verzeichnisse `apps/builder/src/i18n/locale/*` werden automatisch über Crowdin auf dem neuesten Stand gehalten. Sehen Sie sich unsere  [offizielle Übersetzungsseite](https://crowdin.com/project/illa-builder). an, falls Sie dazu beitragen möchten.\n    \n\n## LIZENZ\n\nDieses Projekt ist derzeit lizenziert unter [Apache License 2.0](./LICENSE).\n"
  },
  {
    "path": "README-JP.md",
    "content": "\n<div align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img alt=\"ILLA Design Logo\" width=\"120px\" height=\"120px\" src=\"https://github.com/illacloud/.github/blob/main/assets/images/illa-logo.svg\"/>\n  </a>\n</div>\n\n<h1 align=\"center\"><a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">ILLA Builder</a></h1>\n\n<p align=\"center\">ILLA は、開発者が内部ツールを構築するための堅牢なオープン ソースのローコード プラットフォームです。 コンポーネントとアクションのILLAのライブラリを使用することで、開発者はツールの構築にかかる時間を大幅に節約できます。 </p>\n\n<div align=\"center\">\n<a href=\"https://github.com/illacloud/illa-builder/blob/beta/README.md\">English</a> | <a href=\"https://github.com/illacloud/illa-builder/blob/beta/README-CN.md\">简体中文</a> | <a href=\"https://github.com/illacloud/illa-builder/blob/beta/README-DE.md\">Deutsch</a> | 日本語\n</div>\n\n<br>\n<p align=\"center\">\n<a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n  <img width=\"800\" alt=\"GitHub - Readme - jp\" src=\"https://github.com/illacloud/illa-builder/assets/112603073/eeb65cb6-e307-4f16-9a7a-2fcb9d3a37a3\">\n</a>\n</p>\n\n[![Discord](https://img.shields.io/badge/chat-Discord-7289DA?logo=discord)](https://discord.gg/illacloud)\n[![Twitter](https://img.shields.io/badge/Twitter-1DA1F2?logo=x&logoColor=white)](https://twitter.com/illa_cloud)\n[![Discussions](https://img.shields.io/badge/discussions-GitHub-333333?logo=github)](https://github.com/orgs/illacloud/discussions)\n[![Crowdin](https://badges.crowdin.net/illa-builder/localized.svg)](https://crowdin.com/project/illa-builder)\n[![CI (Rolling and Humble)](https://github.com/illacloud/illa-builder/actions/workflows/build-docker.yml/badge.svg?query=branch%3Amain)](https://github.com/illacloud/illa-builder/actions/workflows/build-docker.yml?query=branch%3Amain)\n[![PR:s Welcome](https://img.shields.io/badge/PR:s-welcome-brightgreen.svg)](https://github.com/illacloud/illa-builder/pulls)\n[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=socialflat-square&)](https://www.apache.org/licenses/LICENSE-2.0.html)\n\n## 🚀始めましょう\n[ILLA Cloud](https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme) にサインアップしてログインするのが最も便利です。招待コードを入手するには、この [Google Form](https://forms.gle/XFRSUc3yFpzbCdcWA) に記入し、できるだけ多くの情報を提供してください。ご提出いただいた内容は、最大2営業日以内にレビューし、できるだけ早くご連絡いたします。\nレビュープロセスを迅速化するために、[Discordコミュニティ](https://discord.gg/illacloud) に参加して、より迅速に招待コードを入手できるようにすることもできます。\n\nまた、ILLAユーティリティを手動で（Docker、docker-compose、k8s）展開および自己ホストすることもできます。\n\n<p>\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\"><img src=\"https://raw.githubusercontent.com/illacloud/.github/main/assets/images/ILLA%20Cloud.png\" height=120 />\n</p>\n\n\n\n## ✨ 特徴\n\n1. ⚽ **リアルタイム コラボレーション:** すべてをリアルタイムで一緒に作成できます。\n2. 🤖 **サポートの自動化:** すべてを接続して 5 秒で自動化します。\n3. 🖥 **自己ホスト型:** Docker と k8s をサポート\n4. 📝 **ページのサポート:** コンテンツが豊富で UI に適したツールを作成するための基盤。\n5. 🎨 **[ILLA Design](https://github.com/illacloud/illa-design) を利用:** コンポーネントによって想像力が制約されることはありません。\n## Self-hosted\n    \nILLA CLI を使用すると、ILLA Builder を想像よりも速く展開できます。 [ここをクリック](https://docs.illacloud.com/self-hosted-deployment) 詳細については。\nデプロイが正常に完了したら、電子メール アドレスで登録するか、次の情報でログインできます。\n<p align=\"left\">Username (email): root</p>\n<p align=\"left\">Password: password</p>\n\n    \n    \n## ツールの作成方法\n\n#### 🎯 Step 1: Connect to your database\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/sql.jpeg\">\n  </a>\n</p>\n\n#### 🎨 ステップ 2: 組み込みコンポーネントを使用して UI を構築する\nコンポーネントをキャンバスにドラッグして、UI を構築します。 Illa Builder および Illa Design には、チャート、テーブル、フォームなど、多数のコンポーネントが用意されています。 コンポーネントが重なっている場合、それらの位置は自動的に調整されるため、レイアウト開発が容易かつ柔軟になります。\n    \n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/edit-ui-with-components.gif\">\n  </a>\n</p>\n\n#### 🔌 ステップ 3: データに接続する\nGUI データ コネクタを介して MySQL または REST API に接続します。 また、近日中に 10 を超えるデータベースと API を追加する予定です。\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/connect-your-data.gif\">\n  </a>\n</p>\n\n#### 🚀 ステップ 4: アプリをデプロイする\nアプリをデプロイして自己ホストします。\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/deploy.gif\">\n  </a>\n</p>\n\n\n## 💬 コミュニティ\n\nILLA コミュニティに参加して、アイデア、提案、質問を共有し、他のユーザーや貢献者とつながりましょう。\n</br>[![Chat on Discord](https://img.shields.io/badge/chat-Discord-7289DA?logo=discord)](https://discord.gg/illacloud)   [![Discuss on GitHub](https://img.shields.io/badge/discussions-GitHub-333333?logo=github)](https://github.com/orgs/illacloud/discussions)   \n\n## 🌱 貢献\n\n貢献を考えていますか？ ILLA へのあらゆる種類の貢献を歓迎します。 参加方法の詳細については、[貢献ガイド](./CONTRIBUTING.md) をご覧ください。\n<p>からのすべての貢献に感謝します ❤︎  <a href=\"https://github.com/illacloud/illa-builder/graphs/contributors\">貢献者</a></p>\n\n## 📢 翻訳\n\n`apps/builder/src/i18n/locale/*` ディレクトリは Crowdin によって自動的に更新されます。貢献したい場合は、[公式翻訳ページ](https://crowdin.com/project/illa-builder) を参照してください。\n\n## ライセンス\n\nこのプロジェクトは [Apache License 2.0](./LICENSE) です。\n"
  },
  {
    "path": "README.md",
    "content": "\n<div align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img alt=\"ILLA Design Logo\" width=\"120px\" height=\"120px\" src=\"https://github.com/illacloud/.github/blob/main/assets/images/illa-logo.svg\"/>\n  </a>\n</div>\n\n<h1 align=\"center\"><a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">ILLA Builder</a> </h1>\n\n<p align=\"center\">ILLA is a robust open source low-code platform for developers to build internal tools. By using ILLA's library of Components and Actions, developers can save massive amounts of time on building tools. </p>\n\n<div align=\"center\">\nEnglish | <a href=\"https://github.com/illacloud/illa-builder/blob/beta/README-CN.md\">简体中文</a> | <a href=\"https://github.com/illacloud/illa-builder/blob/beta/README-DE.md\">Deutsch</a> | <a href=\"https://github.com/illacloud/illa-builder/blob/beta/README-JP.md\">日本語</a>\n</div>\n\n<br>\n<p align=\"center\">\n<a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n  <img width=\"800\" alt=\"Github(1)\" src=\"https://github.com/illacloud/illa-builder/assets/112603073/fdc4c02b-e412-4c41-8240-8077d4447ebc\">\n</a>\n</p>\n\n[![PR:s Welcome](https://img.shields.io/badge/PR:s-welcome-brightgreen.svg)](https://github.com/illacloud/illa-builder/pulls)\n[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=socialflat-square&)](https://www.apache.org/licenses/LICENSE-2.0.html)\n\n\n## 🚀Get Started\nTo try ILLA, the most convenient way is to sign up and log in to [ILLA Cloud](https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme). \n\nYou can also deploy and [self-host](https://docs.illacloud.com/self-hosted-deployment/) ILLA utils manually([Docker](https://www.docker.com/), [docker-compose](https://docs.docker.com/compose/), and [k8s](https://kubernetes.io/)).\n\n\n## ✨ Features\n\n1. ⚽ **Real-time Collaboration:** We can create everything in real-time together.\n2. 🤖 **Automate Support:** Connect everything and automate them in 5 seconds.\n3. 🖥 **Self-hosted:** supports Docker & k8s\n4. 📝 **Page Support:** The base of creating a content-rich and UI-friendly tool.\n5. 🎨 **Powered by [ILLA Design](https://github.com/illacloud/illa-design):** Components should not constrain your imagination.\n\n## Self-hosted\n    \nThe ILLA CLI enables you to deploy ILLA Builder faster than your imagination. [Click here](https://docs.illacloud.com/self-hosted-deployment) for more details.\nAfter successfully deployed, you can register with email address or log in with the following information: \n<p align=\"left\">Username (email): root</p>\n<p align=\"left\">Password: password</p>\n\n    \n    \n## How to build your tool\n\n#### 🎯 Step 1: Connect to your database\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/sql.jpeg\">\n  </a>\n</p>\n\n#### 🎨 Step 2: Build UI with built-in components\nBuild your UI by dragging components to the canvas. We provide dozens of components including charts, tables, forms, and many more in Illa Builder and Illa Design. When components overlap, their position will be automatically adjusted, which makes the layout development easy and flexible.\n\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/edit-ui-with-components.gif\">\n  </a>\n</p>\n\n#### 🔌 Step 3: Connect to your data\nConnect to MySQL or REST API through our GUI data connectors. We will add more than 10 databases and APIs soon.\n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/connect-your-data.gif\">\n  </a>\n</p>\n\n#### 🚀 Step 4: Deploy your app\nDeploy your app and self-host it. \n<p align=\"center\">\n  <a href=\"https://cloud.illacloud.com?utm_source=github&utm_medium=readme&utm_campaign=github-readme\">\n    <img src=\"https://github.com/illacloud/.github/blob/main/assets/images/deploy.gif\">\n  </a>\n</p>\n\n## 🌱 Contributing\n\nThinking about contributing? All kinds of contributions to ILLA are greatly appreciated and welcomed! Check out our [Contribution Guide](./CONTRIBUTING.md) for details about how you can get involved.\n<p>Appreciate all the contributions from our ❤︎  <a href=\"https://github.com/illacloud/illa-builder/graphs/contributors\">Contributors!</a></p>\n\n## 📢 Translating\n\nThe `apps/builder/src/i18n/locale/*` dirs are kept up-to-date automatically via Crowdin. See our [official translation page](https://crowdin.com/project/illa-builder) in case you would like to contribute.\n\n## LICENSE\n\nThis project is currently licensed under [Apache License 2.0](./LICENSE).\n"
  },
  {
    "path": "apps/builder/.eslintrc.js",
    "content": "module.exports = {\n  root: true,\n  settings: {\n    \"import/resolver\": {\n      typescript: {\n        project: \"./tsconfig.json\",\n      }\n    },\n  },\n  extends: [\"illa\"],\n}\n"
  },
  {
    "path": "apps/builder/.gitignore",
    "content": "# local changelog cache (lerna-changelog)\n.changelog/\n\n# website public/ folder (temporary; copied to root for docs:build and vercel compat)\n# public/\n\nnode_modules/\nlerna-debug.log\nnpm-debug.log\nnpm-debug.log*\npackages/*/.env\n*.log\n*.cache\nyarn-error.log\n.next\n.idea\ndist\nsrc/i18n/locale/*.json\n\n# Local Netlify folder\n.netlify\n.idea\n\ndraft*\n.yarn\n.vercel\n\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\ncypress-coverage\njest-coverage\nreports\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (http://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# Typescript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# dotenv environment variables file\n.env.*.local\n.env.local\n\n# Mac files\n.DS_Store\n\n# Yarn\nyarn-error.log\n.pnp/\n.pnp.js\n# Yarn Integrity file\n.yarn-integrity\n\nreport.*\n\n# turbo\n.turbo\n\n# cypress\ncypress/videos\ncypress/screenshots\n\nstats.html\n\npublic/appInfo.json\ni18n/locales/*.json\n"
  },
  {
    "path": "apps/builder/Dockerfile",
    "content": "FROM nginx:alpine\nADD docker-config/nginx-root.conf /etc/nginx/nginx.conf\nADD docker-config/illa-builder.conf /etc/nginx/conf.d/app.conf\nADD dist/index.html /usr/share/nginx/html/index.html\nADD dist/assets /usr/share/nginx/html/assets"
  },
  {
    "path": "apps/builder/docker-config/illa-builder.conf",
    "content": "server {\n    listen 80;\n    server_name localhost;\n    root /opt/illa/illa-builder/;\n    index index.html;\n    gzip on;\n\n    proxy_ssl_server_name on;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection \"upgrade\";\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_set_header X-Forwarded-Host $host;\n    proxy_set_header Accept-Encoding \"\";\n\n    sub_filter_once off;\n    location / {\n        try_files $uri $uri/ /index.html;\n        expires -1;\n    }\n\n    location /assets {\n        expires 1y;\n    }\n}\n\n"
  },
  {
    "path": "apps/builder/docker-config/nginx-root.conf",
    "content": "user  nginx;\nworker_processes  1;\n\nerror_log  /var/log/nginx/error.log warn;\npid        /var/run/nginx.pid;\n\nevents {\n    worker_connections  1024;\n}\n\n\nhttp {\n    include       /etc/nginx/mime.types;\n    default_type  application/octet-stream;\n\n    log_format main '\"$time_local\" client=$remote_addr '\n               'method=$request_method request=\"$request\" '\n               'request_length=$request_length '\n               'status=$status bytes_sent=$bytes_sent '\n               'body_bytes_sent=$body_bytes_sent '\n               'referer=$http_referer '\n               'http_x_forwarded_for=$http_x_forwarded_for '\n               'user_agent=\"$http_user_agent\" '\n               'upstream_addr=$upstream_addr '\n               'upstream_status=$upstream_status '\n               'request_time=$request_time '\n               'upstream_response_time=$upstream_response_time '\n               'upstream_connect_time=$upstream_connect_time '\n               'upstream_header_time=$upstream_header_time';\n\n    access_log  /var/log/nginx/access.log  main;\n\n    sendfile        on;\n\n    keepalive_timeout  65;\n\n    include /etc/nginx/conf.d/*.conf;\n}\n"
  },
  {
    "path": "apps/builder/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n\n    <link href=\"/favicon.png\" rel=\"icon\" type=\"image/svg+xml\" />\n    <meta\n      name=\"viewport\"\n      content=\"width=device-width, initial-scale=1.0, maximum-scale=1\"\n    />\n    <meta\n      key=\"twitter:title\"\n      name=\"twitter:title\"\n      content=\"ILLA Builder - An open-source low-code Platform for Developers.\"\n    />\n    <meta\n      key=\"og:title\"\n      property=\"og:title\"\n      content=\"ILLA Builder - An open-source low-code Platform for Developers.\"\n    />\n    <link href=\"/public/font-family/Fira-code/fira_code.css\" rel=\"stylesheet\" />\n    <link href=\"/public/font-family/Inter/inter.css\" rel=\"stylesheet\" />\n    <title>Loading...</title>\n    <script>\n      function createFavicon() {\n        const newFavicon = document.createElement(\"link\")\n        newFavicon.rel = \"icon\"\n        document.getElementsByTagName(\"head\")[0].appendChild(newFavicon)\n        return newFavicon\n      }\n\n      function setFavicon(faviconHref) {\n        const linkElements = document.getElementsByTagName(\"link\")\n\n        const faviconElements = []\n\n        for (let i = 0; i < linkElements.length; i++) {\n          const link = linkElements[i]\n          if (link.rel.toLowerCase() === \"icon\") {\n            faviconElements.push(link)\n          }\n        }\n\n        if (faviconElements.length === 0) {\n          const element = createFavicon()\n          element.href = faviconHref\n        } else {\n          faviconElements.forEach((faviconElement) => {\n            faviconElement.href = faviconHref\n          })\n        }\n      }\n\n      async function validateCustomDomain() {\n        const origin = location.origin\n        if (\n          \"%ILLA_INSTANCE_ID%\" === \"CLOUD\" &&\n          origin !== \"%ILLA_BUILDER_URL%\"\n        ) {\n          window.customDomain = location.host\n          try {\n            const response = await fetch(\n              `https://%ILLA_API_BASE_URL%/supervisor/api/v1/domain/validate`,\n              {\n                method: \"POST\",\n                headers: {\n                  \"Content-Type\": \"application/json\",\n                },\n                body: JSON.stringify({ customDomain: location.host }),\n              },\n            )\n            const data = await response.json()\n            window.currentTeamIdentifier = data.teamIdentifier\n            if (!data.customDomainAvaliable) {\n              const redirectURL = window.location.href.replace(\n                `https://${window.location.host}/cloud`,\n                \"%ILLA_CLOUD_URL%\",\n              )\n              window.location.href = `%ILLA_CLOUD_URL%/redirect-expired?redirectURL=${redirectURL}`\n              return\n            }\n            if (data.favicon) {\n              setFavicon(data.favicon)\n            } else {\n              setFavicon(\"/ILLAFavicon.ico\")\n            }\n          } catch {\n            setFavicon(\"/ILLAFavicon.ico\")\n          }\n        } else {\n          setFavicon(\"/ILLAFavicon.ico\")\n        }\n      }\n      validateCustomDomain()\n    </script>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/src/main.tsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "apps/builder/package.json",
    "content": "{\n  \"name\": \"illa-builder\",\n  \"description\": \"Help every Developer as fast as to build Business Tools\",\n  \"repository\": \"git@github.com:illacloud/illa-builder.git\",\n  \"private\": true,\n  \"author\": \"ILLA Cloud <opensource@illasoft.com>\",\n  \"license\": \"Apache-2.0\",\n  \"version\": \"4.8.3\",\n  \"scripts\": {\n    \"dev\": \"vite --strictPort --force\",\n    \"build-cloud\": \"NODE_OPTIONS=--max-old-space-size=12288  vite build --mode cloud\",\n    \"build-self\": \"NODE_OPTIONS=--max-old-space-size=12288  vite build --mode self\",\n    \"preview\": \"vite preview\",\n    \"ts-check\": \"tsc --noEmit\",\n    \"gen:protobuf\": \"pnpm protoc --ts_out ./src/api/ws/ --proto_path protos protos/ILLA_PROTO.proto\"\n  },\n  \"dependencies\": {\n    \"@chatscope/chat-ui-kit-react\": \"^1.10.1\",\n    \"@chatscope/chat-ui-kit-styles\": \"^1.4.0\",\n    \"@codemirror/autocomplete\": \"^6.4.0\",\n    \"@codemirror/commands\": \"^6.1.3\",\n    \"@codemirror/lang-html\": \"^6.4.0\",\n    \"@codemirror/lang-javascript\": \"^6.1.2\",\n    \"@codemirror/lang-json\": \"^6.0.1\",\n    \"@codemirror/lang-sql\": \"^6.3.3\",\n    \"@codemirror/lang-xml\": \"^6.0.1\",\n    \"@codemirror/language\": \"^6.3.2\",\n    \"@codemirror/lint\": \"^6.1.0\",\n    \"@codemirror/search\": \"^6.2.3\",\n    \"@codemirror/state\": \"^6.2.0\",\n    \"@codemirror/view\": \"^6.7.2\",\n    \"@dnd-kit/core\": \"^6.0.8\",\n    \"@dnd-kit/modifiers\": \"^6.0.1\",\n    \"@dnd-kit/sortable\": \"^7.0.2\",\n    \"@dnd-kit/utilities\": \"^3.2.1\",\n    \"@editorjs/checklist\": \"^1.5.0\",\n    \"@editorjs/code\": \"^2.8.0\",\n    \"@editorjs/editorjs\": \"^2.27.2\",\n    \"@editorjs/embed\": \"^2.5.3\",\n    \"@editorjs/header\": \"^2.7.0\",\n    \"@editorjs/image\": \"^2.8.1\",\n    \"@editorjs/inline-code\": \"^1.4.0\",\n    \"@editorjs/list\": \"^1.8.0\",\n    \"@editorjs/marker\": \"^1.3.0\",\n    \"@emotion/cache\": \"^11.11.0\",\n    \"@emotion/styled\": \"^11.11.0\",\n    \"@illa-design/react\": \"workspace:*\",\n    \"@illa-public/avatar\": \"workspace:*\",\n    \"@illa-public/code-editor\": \"workspace:*\",\n    \"@illa-public/create-app\": \"workspace:*\",\n    \"@illa-public/cropper\": \"workspace:*\",\n    \"@illa-public/dynamic-string\": \"workspace:^\",\n    \"@illa-public/icon\": \"workspace:*\",\n    \"@illa-public/icon-hot-spot\": \"workspace:^\",\n    \"@illa-public/illa-net\": \"workspace:*\",\n    \"@illa-public/illa-storage\": \"workspace:*\",\n    \"@illa-public/invite-modal\": \"workspace:*\",\n    \"@illa-public/layout-auto-change\": \"workspace:*\",\n    \"@illa-public/market-agent\": \"workspace:*\",\n    \"@illa-public/market-app\": \"workspace:*\",\n    \"@illa-public/missing-resource-module\": \"workspace:^\",\n    \"@illa-public/mixpanel-utils\": \"workspace:*\",\n    \"@illa-public/public-configs\": \"workspace:*\",\n    \"@illa-public/public-types\": \"workspace:*\",\n    \"@illa-public/record-editor\": \"workspace:*\",\n    \"@illa-public/resource-generator\": \"workspace:*\",\n    \"@illa-public/sso-module\": \"workspace:*\",\n    \"@illa-public/styleis-plugin\": \"workspace:*\",\n    \"@illa-public/text-link\": \"workspace:*\",\n    \"@illa-public/upgrade-modal\": \"workspace:*\",\n    \"@illa-public/user-data\": \"workspace:*\",\n    \"@illa-public/user-role-utils\": \"workspace:*\",\n    \"@illa-public/utils\": \"workspace:*\",\n    \"@mui/icons-material\": \"^5.14.18\",\n    \"@mui/material\": \"^5.14.18\",\n    \"@mui/x-data-grid-premium\": \"^6.20.0\",\n    \"@protobuf-ts/runtime\": \"^2.8.3\",\n    \"@react-google-maps/api\": \"^2.18.1\",\n    \"@reduxjs/toolkit\": \"^2.0.1\",\n    \"@rjsf/core\": \"^5.10.0\",\n    \"@rjsf/utils\": \"^5.10.0\",\n    \"@rjsf/validator-ajv8\": \"^5.10.0\",\n    \"@sentry/react\": \"^7.54.0\",\n    \"@tanstack/react-table\": \"^8.9.1\",\n    \"@tanstack/table-core\": \"^8.9.1\",\n    \"@uiw/codemirror-theme-github\": \"^4.19.8\",\n    \"@uiw/color-convert\": \"^1.4.2\",\n    \"@uiw/react-codemirror\": \"^4.20.2\",\n    \"@uiw/react-color-sketch\": \"^1.4.2\",\n    \"axios\": \"^1.6.2\",\n    \"chart.js\": \"^3.9.1\",\n    \"chroma-js\": \"^2.4.2\",\n    \"copy-to-clipboard\": \"^3.3.2\",\n    \"dayjs\": \"^1.11.10\",\n    \"deep-diff\": \"^1.0.2\",\n    \"downloadjs\": \"^1.4.7\",\n    \"editorjs-html\": \"^3.4.3\",\n    \"editorjs-md-parser\": \"^0.0.3\",\n    \"fflate\": \"^0.8.1\",\n    \"framer-motion\": \"^10.16.4\",\n    \"fuse.js\": \"^6.6.2\",\n    \"html5-qrcode\": \"^2.3.8\",\n    \"i18next\": \"^23.7.6\",\n    \"i18next-browser-languagedetector\": \"^7.0.1\",\n    \"klona\": \"^2.0.6\",\n    \"lodash-es\": \"^4.17.21\",\n    \"lottie-react\": \"^2.4.0\",\n    \"mammoth\": \"^1.7.0\",\n    \"numbro\": \"^2.4.0\",\n    \"overlap-area\": \"^1.1.0\",\n    \"papaparse\": \"^5.4.1\",\n    \"pdfjs-dist\": \"2.16.105\",\n    \"qrcode.react\": \"^3.1.0\",\n    \"qs\": \"^6.11.2\",\n    \"rc-virtual-list\": \"^3.4.2\",\n    \"re-resizable\": \"^6.9.9\",\n    \"react-big-calendar\": \"^1.6.9\",\n    \"react-chartjs-2\": \"^4.3.1\",\n    \"react-code-blocks\": \"^0.1.4\",\n    \"react-dnd\": \"^16.0.1\",\n    \"react-dnd-touch-backend\": \"^16.0.1\",\n    \"react-helmet-async\": \"^1.3.0\",\n    \"react-hook-form\": \"^7.30.0\",\n    \"react-hotkeys-hook\": \"^4.4.1\",\n    \"react-i18next\": \"^13.5.0\",\n    \"react-icons\": \"^4.7.1\",\n    \"react-markdown\": \"^8.0.3\",\n    \"react-pdf\": \"^6.2.2\",\n    \"react-player\": \"^2.11.2\",\n    \"react-redux\": \"^9.0.4\",\n    \"react-rnd\": \"^10.3.7\",\n    \"react-router-dom\": \"^6.14.0\",\n    \"react-selecto\": \"^1.22.0\",\n    \"react-slick\": \"^0.29.0\",\n    \"react-syntax-highlighter\": \"^15.5.0\",\n    \"react-use\": \"^17.4.0\",\n    \"react-use-measure\": \"^2.1.1\",\n    \"react-virtuoso\": \"^4.3.11\",\n    \"react-window\": \"^1.8.9\",\n    \"react-window-infinite-loader\": \"^1.0.9\",\n    \"rehype-raw\": \"^6.1.1\",\n    \"rehype-sanitize\": \"^5.0.1\",\n    \"remark-breaks\": \"^4.0.0\",\n    \"remark-gfm\": \"^3.0.1\",\n    \"streamsaver\": \"^2.0.6\",\n    \"tern\": \"^0.24.3\",\n    \"toposort\": \"^2.0.2\",\n    \"ts-key-enum\": \"^2.0.12\",\n    \"uuid\": \"^8.3.2\",\n    \"xlsx\": \"https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz\"\n  },\n  \"devDependencies\": {\n    \"@mdx-js/rollup\": \"^2.3.0\",\n    \"@protobuf-ts/plugin\": \"^2.8.3\",\n    \"@sentry/vite-plugin\": \"^2.4.0\",\n    \"@types/chroma-js\": \"^2.4.1\",\n    \"@types/codemirror\": \"^5.60.5\",\n    \"@types/deep-diff\": \"^1.0.1\",\n    \"@types/downloadjs\": \"^1.4.4\",\n    \"@types/google.maps\": \"^3.53.2\",\n    \"@types/gtag.js\": \"^0.0.18\",\n    \"@types/lodash-es\": \"^4.17.12\",\n    \"@types/mdx\": \"^2.0.3\",\n    \"@types/papaparse\": \"^5.3.9\",\n    \"@types/qs\": \"^6.9.8\",\n    \"@types/react-big-calendar\": \"^1.6.4\",\n    \"@types/react-pdf\": \"^6.2.0\",\n    \"@types/react-slick\": \"^0.23.10\",\n    \"@types/react-syntax-highlighter\": \"^15.5.11\",\n    \"@types/react-window\": \"^1.8.5\",\n    \"@types/react-window-infinite-loader\": \"^1.0.6\",\n    \"@types/streamsaver\": \"^2.0.1\",\n    \"@types/tern\": \"^0.23.5\",\n    \"@types/toposort\": \"^2.0.4\",\n    \"@types/uuid\": \"^9.0.4\",\n    \"@types/ws\": \"^8.5.5\",\n    \"cross-env\": \"^7.0.3\",\n    \"eslint-config-illa\": \"workspace:*\",\n    \"protoc\": \"1.0.4\",\n    \"rollup-plugin-copy\": \"^3.5.0\",\n    \"rollup-plugin-visualizer\": \"^5.12.0\",\n    \"tsconfig\": \"workspace:*\"\n  }\n}\n"
  },
  {
    "path": "apps/builder/protos/ILLA_PROTO.proto",
    "content": "syntax = \"proto3\";\npackage tutorial;\n\nenum Signal {\n  SIGNAL_PING = 0;\n  SIGNAL_ENTER = 1;\n  SIGNAL_LEAVE = 2;\n  SIGNAL_CREATE_STATE = 3;\n  SIGNAL_DELETE_STATE = 4;\n  SIGNAL_UPDATE_STATE = 5;\n  SIGNAL_MOVE_STATE = 6;\n  SIGNAL_CREATE_OR_UPDATE_STATE = 7;\n  SIGNAL_BROADCAST_ONLY = 8;\n  SIGNAL_PUT_STATE = 9;\n  SIGNAL_GLOBAL_BROADCAST_ONLY = 10;\n  SIGNAL_COOPERATE_ATTACH = 11;\n  SIGNAL_COOPERATE_DISATTACH = 12;\n  SIGNAL_MOVE_CURSOR = 13;\n  SIGNAL_FORCE_REFRESH = 14;\n  SIGNAL_TAKE_APP_SNAPSHOT = 15;\n  SIGNAL_RECOVER_APP_SNAPSHOT = 16;\n}\n\nenum Target {\n  TARGET_NOTHING = 0;            // placeholder for nothing\n  TARGET_COMPONENTS = 1;         // ComponentsState\n  TARGET_DEPENDENCIES = 2;       // DependenciesState\n  TARGET_DRAG_SHADOW = 3;        // DragShadowState\n  TARGET_DOTTED_LINE_SQUARE = 4; // DottedLineSquareState\n  TARGET_DISPLAY_NAME = 5;       // DisplayNameState\n  TARGET_APPS = 6;               // only for broadcast\n  TARGET_RESOURCE = 7;           // only for broadcast\n  TARGET_ACTION = 8;             // only for broadcast\n  TARGET_CURSOR = 9;             // only for broadcast\n  TARGET_WINDOW = 10;            // only for broadcast\n}\n\nmessage MovingMessageBin {\n  Signal  signal            = 1;  // see package ws const define\n  Target  target            = 2;  //\n  string  clientID          = 3;  // message sender client ID\n  bool    needBroadcast     = 4;\n  string  userID            = 5;  // message sender user ID\n  string  nickname          = 6;  // message sender nickname\n  int32   status            = 7;  // set instance to status, 0 for empty status\n  string  parentDisplayName = 8;  // parent component displayname\n  string  displayNames      = 9;  // message affected component display names, separate with comma \",\"\n  uint32  cursorXInteger    = 10; //  cursor's position with dot number\n  uint32  cursorYInteger    = 11; //  cursor's position with dot number\n  float   cursorXMod        = 12; //  cursor's position with dot number\n  float   cursorYMod        = 13; //  cursor's position with dot number\n  uint32  widgetX           = 14; //  widget'position with dot number\n  uint32  widgetY           = 15; //  widget'position with dot number\n  uint32  widgetW           = 16; //  widget'shape with dot number\n  uint32  widgetH           = 17; //  widget'shape with dot number\n}"
  },
  {
    "path": "apps/builder/public/font-family/Fira-code/fira_code.css",
    "content": "@font-face {\n    font-family: 'Fira Code';\n    src: url('woff2/FiraCode-Light.woff2') format('woff2'),\n    url(\"woff/FiraCode-Light.woff\") format(\"woff\");\n    font-weight: 300;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'Fira Code';\n    src: url('woff2/FiraCode-Regular.woff2') format('woff2'),\n    url(\"woff/FiraCode-Regular.woff\") format(\"woff\");\n    font-weight: 400;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'Fira Code';\n    src: url('woff2/FiraCode-Medium.woff2') format('woff2'),\n    url(\"woff/FiraCode-Medium.woff\") format(\"woff\");\n    font-weight: 500;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'Fira Code';\n    src: url('woff2/FiraCode-SemiBold.woff2') format('woff2'),\n    url(\"woff/FiraCode-SemiBold.woff\") format(\"woff\");\n    font-weight: 600;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'Fira Code';\n    src: url('woff2/FiraCode-Bold.woff2') format('woff2'),\n    url(\"woff/FiraCode-Bold.woff\") format(\"woff\");\n    font-weight: 700;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'Fira Code VF';\n    src: url('woff2/FiraCode-VF.woff2') format('woff2-variations'),\n    url('woff/FiraCode-VF.woff') format('woff-variations');\n    /* font-weight requires a range: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide#Using_a_variable_font_font-face_changes */\n    font-weight: 300 700;\n    font-style: normal;\n}"
  },
  {
    "path": "apps/builder/public/font-family/Inter/inter.css",
    "content": "@font-face {\n  font-family: 'Inter';\n  font-style:  normal;\n  font-weight: 100;\n  font-display: swap;\n  src: url(\"Inter-Thin.woff2\") format(\"woff2\"),\n       url(\"Inter-Thin.woff\") format(\"woff\");\n}\n@font-face {\n  font-family: 'Inter';\n  font-style:  italic;\n  font-weight: 100;\n  font-display: swap;\n  src: url(\"Inter-ThinItalic.woff2\") format(\"woff2\"),\n       url(\"Inter-ThinItalic.woff\") format(\"woff\");\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style:  normal;\n  font-weight: 200;\n  font-display: swap;\n  src: url(\"Inter-ExtraLight.woff2\") format(\"woff2\"),\n       url(\"Inter-ExtraLight.woff\") format(\"woff\");\n}\n@font-face {\n  font-family: 'Inter';\n  font-style:  italic;\n  font-weight: 200;\n  font-display: swap;\n  src: url(\"Inter-ExtraLightItalic.woff2\") format(\"woff2\"),\n       url(\"Inter-ExtraLightItalic.woff\") format(\"woff\");\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style:  normal;\n  font-weight: 300;\n  font-display: swap;\n  src: url(\"Inter-Light.woff2\") format(\"woff2\"),\n       url(\"Inter-Light.woff\") format(\"woff\");\n}\n@font-face {\n  font-family: 'Inter';\n  font-style:  italic;\n  font-weight: 300;\n  font-display: swap;\n  src: url(\"Inter-LightItalic.woff2\") format(\"woff2\"),\n       url(\"Inter-LightItalic.woff\") format(\"woff\");\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style:  normal;\n  font-weight: 400;\n  font-display: swap;\n  src: url(\"Inter-Regular.woff2\") format(\"woff2\"),\n       url(\"Inter-Regular.woff\") format(\"woff\");\n}\n@font-face {\n  font-family: 'Inter';\n  font-style:  italic;\n  font-weight: 400;\n  font-display: swap;\n  src: url(\"Inter-Italic.woff2\") format(\"woff2\"),\n       url(\"Inter-Italic.woff\") format(\"woff\");\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style:  normal;\n  font-weight: 500;\n  font-display: swap;\n  src: url(\"Inter-Medium.woff2\") format(\"woff2\"),\n       url(\"Inter-Medium.woff\") format(\"woff\");\n}\n@font-face {\n  font-family: 'Inter';\n  font-style:  italic;\n  font-weight: 500;\n  font-display: swap;\n  src: url(\"Inter-MediumItalic.woff2\") format(\"woff2\"),\n       url(\"Inter-MediumItalic.woff\") format(\"woff\");\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style:  normal;\n  font-weight: 600;\n  font-display: swap;\n  src: url(\"Inter-SemiBold.woff2\") format(\"woff2\"),\n       url(\"Inter-SemiBold.woff\") format(\"woff\");\n}\n@font-face {\n  font-family: 'Inter';\n  font-style:  italic;\n  font-weight: 600;\n  font-display: swap;\n  src: url(\"Inter-SemiBoldItalic.woff2\") format(\"woff2\"),\n       url(\"Inter-SemiBoldItalic.woff\") format(\"woff\");\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style:  normal;\n  font-weight: 700;\n  font-display: swap;\n  src: url(\"Inter-Bold.woff2\") format(\"woff2\"),\n       url(\"Inter-Bold.woff\") format(\"woff\");\n}\n@font-face {\n  font-family: 'Inter';\n  font-style:  italic;\n  font-weight: 700;\n  font-display: swap;\n  src: url(\"Inter-BoldItalic.woff2\") format(\"woff2\"),\n       url(\"Inter-BoldItalic.woff\") format(\"woff\");\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style:  normal;\n  font-weight: 800;\n  font-display: swap;\n  src: url(\"Inter-ExtraBold.woff2\") format(\"woff2\"),\n       url(\"Inter-ExtraBold.woff\") format(\"woff\");\n}\n@font-face {\n  font-family: 'Inter';\n  font-style:  italic;\n  font-weight: 800;\n  font-display: swap;\n  src: url(\"Inter-ExtraBoldItalic.woff2\") format(\"woff2\"),\n       url(\"Inter-ExtraBoldItalic.woff\") format(\"woff\");\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style:  normal;\n  font-weight: 900;\n  font-display: swap;\n  src: url(\"Inter-Black.woff2\") format(\"woff2\"),\n       url(\"Inter-Black.woff\") format(\"woff\");\n}\n@font-face {\n  font-family: 'Inter';\n  font-style:  italic;\n  font-weight: 900;\n  font-display: swap;\n  src: url(\"Inter-BlackItalic.woff2\") format(\"woff2\"),\n       url(\"Inter-BlackItalic.woff\") format(\"woff\");\n}\n\n/* -------------------------------------------------------\nVariable font.\nUsage:\n\n  html { font-family: 'Inter', sans-serif; }\n  @supports (font-variation-settings: normal) {\n    html { font-family: 'Inter var', sans-serif; }\n  }\n*/\n@font-face {\n  font-family: 'Inter var';\n  font-weight: 100 900;\n  font-display: swap;\n  font-style: normal;\n  font-named-instance: 'Regular';\n  src: url(\"Inter-roman.var.woff2\") format(\"woff2\");\n}\n@font-face {\n  font-family: 'Inter var';\n  font-weight: 100 900;\n  font-display: swap;\n  font-style: italic;\n  font-named-instance: 'Italic';\n  src: url(\"Inter-italic.var.woff2\") format(\"woff2\");\n}\n\n\n/* --------------------------------------------------------------------------\n[EXPERIMENTAL] Multi-axis, single variable font.\n\nSlant axis is not yet widely supported (as of February 2019) and thus this\nmulti-axis single variable font is opt-in rather than the default.\n\nWhen using this, you will probably need to set font-variation-settings\nexplicitly, e.g.\n\n  * { font-variation-settings: \"slnt\" 0deg }\n  .italic { font-variation-settings: \"slnt\" 10deg }\n\n*/\n@font-face {\n  font-family: 'Inter var experimental';\n  font-weight: 100 900;\n  font-display: swap;\n  font-style: oblique 0deg 10deg;\n  src: url(\"Inter.var.woff2\") format(\"woff2\");\n}\n"
  },
  {
    "path": "apps/builder/src/App.tsx",
    "content": "import { Global } from \"@emotion/react\"\nimport {\n  ILLA_MIXPANEL_EVENT_TYPE,\n  ILLA_MIXPANEL_PUBLIC_PAGE_NAME,\n} from \"@illa-public/mixpanel-utils\"\nimport { UpgradeModalGroup } from \"@illa-public/upgrade-modal\"\nimport { getCurrentTranslateLanguage } from \"@illa-public/user-data\"\nimport { useEffect, useMemo } from \"react\"\nimport { DndProvider } from \"react-dnd\"\nimport { TouchBackend } from \"react-dnd-touch-backend\"\nimport { HelmetProvider } from \"react-helmet-async\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { RouterProvider } from \"react-router-dom\"\nimport {\n  ConfigProvider,\n  MessageGroup,\n  ModalGroup,\n  NotificationGroup,\n  enUS,\n  jaJP,\n  koKR,\n  zhCN,\n} from \"@illa-design/react\"\nimport { illaCodeMirrorTooltipStyle } from \"@/components/CodeEditor/CodeMirror/theme\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport { ILLARoute } from \"@/router\"\nimport { globalStyle } from \"./style\"\nimport { track } from \"./utils/mixpanelHelper\"\n\nconst dragOptions = {\n  enableTouchEvents: true,\n  enableMouseEvents: true,\n}\n\nfunction App() {\n  const currentUserLanguage = useSelector(getCurrentTranslateLanguage)\n  const configLanguage = useMemo(() => {\n    switch (currentUserLanguage) {\n      case \"en-US\":\n        return enUS\n      case \"zh-CN\":\n        return zhCN\n      case \"ja-JP\":\n        return jaJP\n      case \"ko-KR\":\n        return koKR\n      default:\n        return enUS\n    }\n  }, [currentUserLanguage])\n  const { i18n } = useTranslation()\n  const isProductMode = useSelector(getIsILLAProductMode)\n\n  useEffect(() => {\n    if (!!currentUserLanguage) {\n      i18n.changeLanguage(currentUserLanguage)\n    }\n  }, [currentUserLanguage, i18n])\n\n  useEffect(() => {\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.ILLA_ACTIVE,\n      ILLA_MIXPANEL_PUBLIC_PAGE_NAME.PLACEHOLDER,\n    )\n  }, [])\n\n  return (\n    <HelmetProvider>\n      <DndProvider backend={TouchBackend} options={dragOptions}>\n        <ConfigProvider locale={configLanguage}>\n          <Global styles={globalStyle} />\n          <MessageGroup pt={!isProductMode ? \"46px\" : \"0\"} />\n          <UpgradeModalGroup />\n          <NotificationGroup pt={!isProductMode ? \"46px\" : \"0\"} />\n          <ModalGroup />\n          <RouterProvider router={ILLARoute} />\n          <div\n            className=\"illaCodeMirrorWrapper\"\n            css={illaCodeMirrorTooltipStyle}\n          />\n        </ConfigProvider>\n      </DndProvider>\n    </HelmetProvider>\n  )\n}\n\nexport default App\n"
  },
  {
    "path": "apps/builder/src/api/actions/index.ts",
    "content": "import { builderRequest } from \"@illa-public/illa-net\"\nimport {\n  ActionContent,\n  Resource,\n  ResourceContent,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { ResourceInitialConfig } from \"@/redux/resource/resourceState\"\nimport store from \"@/store\"\nimport { getCurrentTeamID } from \"@/utils/team\"\n\nexport const createResource = async (\n  data: ResourceInitialConfig<ResourceContent>,\n) => {\n  const response = await builderRequest<Resource<ResourceContent>>(\n    {\n      method: \"POST\",\n      url: \"/resources\",\n      data,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n  store.dispatch(resourceActions.addResourceItemReducer(response.data))\n  return response.data.resourceID\n}\n\nexport const createAction = async (\n  appId: string,\n  data: Partial<ActionItem<ActionContent>>,\n) => {\n  const response = await builderRequest<ActionItem<ActionContent>>(\n    {\n      url: `/apps/${appId}/actions`,\n      method: \"POST\",\n      data,\n    },\n    { teamID: getCurrentTeamID() },\n  )\n  return response.data.actionID\n}\n"
  },
  {
    "path": "apps/builder/src/api/http/base.ts",
    "content": "import {\n  actionRuntimeAxios,\n  authInterceptor,\n  errorHandlerInterceptor,\n  needAuthAxios,\n} from \"@illa-public/illa-net\"\n\nneedAuthAxios.interceptors.request.use(authInterceptor)\nneedAuthAxios.interceptors.response.use(undefined, errorHandlerInterceptor)\n\nactionRuntimeAxios.interceptors.request.use(authInterceptor)\n"
  },
  {
    "path": "apps/builder/src/api/ws/ILLA_PROTO.ts",
    "content": "// @generated by protobuf-ts 2.8.3\n// @generated from protobuf file \"ILLA_PROTO.proto\" (package \"tutorial\", syntax proto3)\n// tslint:disable\nimport type { BinaryWriteOptions } from \"@protobuf-ts/runtime\";\nimport type { IBinaryWriter } from \"@protobuf-ts/runtime\";\nimport { WireType } from \"@protobuf-ts/runtime\";\nimport type { BinaryReadOptions } from \"@protobuf-ts/runtime\";\nimport type { IBinaryReader } from \"@protobuf-ts/runtime\";\nimport { UnknownFieldHandler } from \"@protobuf-ts/runtime\";\nimport type { PartialMessage } from \"@protobuf-ts/runtime\";\nimport { reflectionMergePartial } from \"@protobuf-ts/runtime\";\nimport { MESSAGE_TYPE } from \"@protobuf-ts/runtime\";\nimport { MessageType } from \"@protobuf-ts/runtime\";\n/**\n * @generated from protobuf message tutorial.MovingMessageBin\n */\nexport interface MovingMessageBin {\n    /**\n     * @generated from protobuf field: tutorial.Signal signal = 1;\n     */\n    signal: Signal; // see package ws const define\n    /**\n     * @generated from protobuf field: tutorial.Target target = 2;\n     */\n    target: Target;\n    /**\n     * @generated from protobuf field: string clientID = 3;\n     */\n    clientID: string; // message sender client ID\n    /**\n     * @generated from protobuf field: bool needBroadcast = 4;\n     */\n    needBroadcast: boolean;\n    /**\n     * @generated from protobuf field: string userID = 5;\n     */\n    userID: string; // message sender user ID\n    /**\n     * @generated from protobuf field: string nickname = 6;\n     */\n    nickname: string; // message sender nickname\n    /**\n     * @generated from protobuf field: int32 status = 7;\n     */\n    status: number; // set instance to status, 0 for empty status\n    /**\n     * @generated from protobuf field: string parentDisplayName = 8;\n     */\n    parentDisplayName: string; // parent component displayname\n    /**\n     * @generated from protobuf field: string displayNames = 9;\n     */\n    displayNames: string; // message affected component display names, separate with comma \",\"\n    /**\n     * @generated from protobuf field: uint32 cursorXInteger = 10;\n     */\n    cursorXInteger: number; //  cursor's position with dot number\n    /**\n     * @generated from protobuf field: uint32 cursorYInteger = 11;\n     */\n    cursorYInteger: number; //  cursor's position with dot number\n    /**\n     * @generated from protobuf field: float cursorXMod = 12;\n     */\n    cursorXMod: number; //  cursor's position with dot number\n    /**\n     * @generated from protobuf field: float cursorYMod = 13;\n     */\n    cursorYMod: number; //  cursor's position with dot number\n    /**\n     * @generated from protobuf field: uint32 widgetX = 14;\n     */\n    widgetX: number; //  widget'position with dot number\n    /**\n     * @generated from protobuf field: uint32 widgetY = 15;\n     */\n    widgetY: number; //  widget'position with dot number\n    /**\n     * @generated from protobuf field: uint32 widgetW = 16;\n     */\n    widgetW: number; //  widget'shape with dot number\n    /**\n     * @generated from protobuf field: uint32 widgetH = 17;\n     */\n    widgetH: number; //  widget'shape with dot number\n}\n/**\n * @generated from protobuf enum tutorial.Signal\n */\nexport enum Signal {\n    /**\n     * @generated from protobuf enum value: SIGNAL_PING = 0;\n     */\n    PING = 0,\n    /**\n     * @generated from protobuf enum value: SIGNAL_ENTER = 1;\n     */\n    ENTER = 1,\n    /**\n     * @generated from protobuf enum value: SIGNAL_LEAVE = 2;\n     */\n    LEAVE = 2,\n    /**\n     * @generated from protobuf enum value: SIGNAL_CREATE_STATE = 3;\n     */\n    CREATE_STATE = 3,\n    /**\n     * @generated from protobuf enum value: SIGNAL_DELETE_STATE = 4;\n     */\n    DELETE_STATE = 4,\n    /**\n     * @generated from protobuf enum value: SIGNAL_UPDATE_STATE = 5;\n     */\n    UPDATE_STATE = 5,\n    /**\n     * @generated from protobuf enum value: SIGNAL_MOVE_STATE = 6;\n     */\n    MOVE_STATE = 6,\n    /**\n     * @generated from protobuf enum value: SIGNAL_CREATE_OR_UPDATE_STATE = 7;\n     */\n    CREATE_OR_UPDATE_STATE = 7,\n    /**\n     * @generated from protobuf enum value: SIGNAL_BROADCAST_ONLY = 8;\n     */\n    BROADCAST_ONLY = 8,\n    /**\n     * @generated from protobuf enum value: SIGNAL_PUT_STATE = 9;\n     */\n    PUT_STATE = 9,\n    /**\n     * @generated from protobuf enum value: SIGNAL_GLOBAL_BROADCAST_ONLY = 10;\n     */\n    GLOBAL_BROADCAST_ONLY = 10,\n    /**\n     * @generated from protobuf enum value: SIGNAL_COOPERATE_ATTACH = 11;\n     */\n    COOPERATE_ATTACH = 11,\n    /**\n     * @generated from protobuf enum value: SIGNAL_COOPERATE_DISATTACH = 12;\n     */\n    COOPERATE_DISATTACH = 12,\n    /**\n     * @generated from protobuf enum value: SIGNAL_MOVE_CURSOR = 13;\n     */\n    MOVE_CURSOR = 13,\n    /**\n     * @generated from protobuf enum value: SIGNAL_FORCE_REFRESH = 14;\n     */\n    FORCE_REFRESH = 14,\n    /**\n     * @generated from protobuf enum value: SIGNAL_TAKE_APP_SNAPSHOT = 15;\n     */\n    TAKE_APP_SNAPSHOT = 15,\n    /**\n     * @generated from protobuf enum value: SIGNAL_RECOVER_APP_SNAPSHOT = 16;\n     */\n    RECOVER_APP_SNAPSHOT = 16\n}\n/**\n * @generated from protobuf enum tutorial.Target\n */\nexport enum Target {\n    /**\n     * placeholder for nothing\n     *\n     * @generated from protobuf enum value: TARGET_NOTHING = 0;\n     */\n    NOTHING = 0,\n    /**\n     * ComponentsState\n     *\n     * @generated from protobuf enum value: TARGET_COMPONENTS = 1;\n     */\n    COMPONENTS = 1,\n    /**\n     * DependenciesState\n     *\n     * @generated from protobuf enum value: TARGET_DEPENDENCIES = 2;\n     */\n    DEPENDENCIES = 2,\n    /**\n     * DragShadowState\n     *\n     * @generated from protobuf enum value: TARGET_DRAG_SHADOW = 3;\n     */\n    DRAG_SHADOW = 3,\n    /**\n     * DottedLineSquareState\n     *\n     * @generated from protobuf enum value: TARGET_DOTTED_LINE_SQUARE = 4;\n     */\n    DOTTED_LINE_SQUARE = 4,\n    /**\n     * DisplayNameState\n     *\n     * @generated from protobuf enum value: TARGET_DISPLAY_NAME = 5;\n     */\n    DISPLAY_NAME = 5,\n    /**\n     * only for broadcast\n     *\n     * @generated from protobuf enum value: TARGET_APPS = 6;\n     */\n    APPS = 6,\n    /**\n     * only for broadcast\n     *\n     * @generated from protobuf enum value: TARGET_RESOURCE = 7;\n     */\n    RESOURCE = 7,\n    /**\n     * only for broadcast\n     *\n     * @generated from protobuf enum value: TARGET_ACTION = 8;\n     */\n    ACTION = 8,\n    /**\n     * only for broadcast\n     *\n     * @generated from protobuf enum value: TARGET_CURSOR = 9;\n     */\n    CURSOR = 9,\n    /**\n     * only for broadcast\n     *\n     * @generated from protobuf enum value: TARGET_WINDOW = 10;\n     */\n    WINDOW = 10\n}\n// @generated message type with reflection information, may provide speed optimized methods\nclass MovingMessageBin$Type extends MessageType<MovingMessageBin> {\n    constructor() {\n        super(\"tutorial.MovingMessageBin\", [\n            { no: 1, name: \"signal\", kind: \"enum\", T: () => [\"tutorial.Signal\", Signal, \"SIGNAL_\"] },\n            { no: 2, name: \"target\", kind: \"enum\", T: () => [\"tutorial.Target\", Target, \"TARGET_\"] },\n            { no: 3, name: \"clientID\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n            { no: 4, name: \"needBroadcast\", kind: \"scalar\", T: 8 /*ScalarType.BOOL*/ },\n            { no: 5, name: \"userID\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n            { no: 6, name: \"nickname\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n            { no: 7, name: \"status\", kind: \"scalar\", T: 5 /*ScalarType.INT32*/ },\n            { no: 8, name: \"parentDisplayName\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n            { no: 9, name: \"displayNames\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n            { no: 10, name: \"cursorXInteger\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n            { no: 11, name: \"cursorYInteger\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n            { no: 12, name: \"cursorXMod\", kind: \"scalar\", T: 2 /*ScalarType.FLOAT*/ },\n            { no: 13, name: \"cursorYMod\", kind: \"scalar\", T: 2 /*ScalarType.FLOAT*/ },\n            { no: 14, name: \"widgetX\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n            { no: 15, name: \"widgetY\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n            { no: 16, name: \"widgetW\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n            { no: 17, name: \"widgetH\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ }\n        ]);\n    }\n    create(value?: PartialMessage<MovingMessageBin>): MovingMessageBin {\n        const message = { signal: 0, target: 0, clientID: \"\", needBroadcast: false, userID: \"\", nickname: \"\", status: 0, parentDisplayName: \"\", displayNames: \"\", cursorXInteger: 0, cursorYInteger: 0, cursorXMod: 0, cursorYMod: 0, widgetX: 0, widgetY: 0, widgetW: 0, widgetH: 0 };\n        globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });\n        if (value !== undefined)\n            reflectionMergePartial<MovingMessageBin>(this, message, value);\n        return message;\n    }\n    internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: MovingMessageBin): MovingMessageBin {\n        let message = target ?? this.create(), end = reader.pos + length;\n        while (reader.pos < end) {\n            let [fieldNo, wireType] = reader.tag();\n            switch (fieldNo) {\n                case /* tutorial.Signal signal */ 1:\n                    message.signal = reader.int32();\n                    break;\n                case /* tutorial.Target target */ 2:\n                    message.target = reader.int32();\n                    break;\n                case /* string clientID */ 3:\n                    message.clientID = reader.string();\n                    break;\n                case /* bool needBroadcast */ 4:\n                    message.needBroadcast = reader.bool();\n                    break;\n                case /* string userID */ 5:\n                    message.userID = reader.string();\n                    break;\n                case /* string nickname */ 6:\n                    message.nickname = reader.string();\n                    break;\n                case /* int32 status */ 7:\n                    message.status = reader.int32();\n                    break;\n                case /* string parentDisplayName */ 8:\n                    message.parentDisplayName = reader.string();\n                    break;\n                case /* string displayNames */ 9:\n                    message.displayNames = reader.string();\n                    break;\n                case /* uint32 cursorXInteger */ 10:\n                    message.cursorXInteger = reader.uint32();\n                    break;\n                case /* uint32 cursorYInteger */ 11:\n                    message.cursorYInteger = reader.uint32();\n                    break;\n                case /* float cursorXMod */ 12:\n                    message.cursorXMod = reader.float();\n                    break;\n                case /* float cursorYMod */ 13:\n                    message.cursorYMod = reader.float();\n                    break;\n                case /* uint32 widgetX */ 14:\n                    message.widgetX = reader.uint32();\n                    break;\n                case /* uint32 widgetY */ 15:\n                    message.widgetY = reader.uint32();\n                    break;\n                case /* uint32 widgetW */ 16:\n                    message.widgetW = reader.uint32();\n                    break;\n                case /* uint32 widgetH */ 17:\n                    message.widgetH = reader.uint32();\n                    break;\n                default:\n                    let u = options.readUnknownField;\n                    if (u === \"throw\")\n                        throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);\n                    let d = reader.skip(wireType);\n                    if (u !== false)\n                        (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);\n            }\n        }\n        return message;\n    }\n    internalBinaryWrite(message: MovingMessageBin, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {\n        /* tutorial.Signal signal = 1; */\n        if (message.signal !== 0)\n            writer.tag(1, WireType.Varint).int32(message.signal);\n        /* tutorial.Target target = 2; */\n        if (message.target !== 0)\n            writer.tag(2, WireType.Varint).int32(message.target);\n        /* string clientID = 3; */\n        if (message.clientID !== \"\")\n            writer.tag(3, WireType.LengthDelimited).string(message.clientID);\n        /* bool needBroadcast = 4; */\n        if (message.needBroadcast !== false)\n            writer.tag(4, WireType.Varint).bool(message.needBroadcast);\n        /* string userID = 5; */\n        if (message.userID !== \"\")\n            writer.tag(5, WireType.LengthDelimited).string(message.userID);\n        /* string nickname = 6; */\n        if (message.nickname !== \"\")\n            writer.tag(6, WireType.LengthDelimited).string(message.nickname);\n        /* int32 status = 7; */\n        if (message.status !== 0)\n            writer.tag(7, WireType.Varint).int32(message.status);\n        /* string parentDisplayName = 8; */\n        if (message.parentDisplayName !== \"\")\n            writer.tag(8, WireType.LengthDelimited).string(message.parentDisplayName);\n        /* string displayNames = 9; */\n        if (message.displayNames !== \"\")\n            writer.tag(9, WireType.LengthDelimited).string(message.displayNames);\n        /* uint32 cursorXInteger = 10; */\n        if (message.cursorXInteger !== 0)\n            writer.tag(10, WireType.Varint).uint32(message.cursorXInteger);\n        /* uint32 cursorYInteger = 11; */\n        if (message.cursorYInteger !== 0)\n            writer.tag(11, WireType.Varint).uint32(message.cursorYInteger);\n        /* float cursorXMod = 12; */\n        if (message.cursorXMod !== 0)\n            writer.tag(12, WireType.Bit32).float(message.cursorXMod);\n        /* float cursorYMod = 13; */\n        if (message.cursorYMod !== 0)\n            writer.tag(13, WireType.Bit32).float(message.cursorYMod);\n        /* uint32 widgetX = 14; */\n        if (message.widgetX !== 0)\n            writer.tag(14, WireType.Varint).uint32(message.widgetX);\n        /* uint32 widgetY = 15; */\n        if (message.widgetY !== 0)\n            writer.tag(15, WireType.Varint).uint32(message.widgetY);\n        /* uint32 widgetW = 16; */\n        if (message.widgetW !== 0)\n            writer.tag(16, WireType.Varint).uint32(message.widgetW);\n        /* uint32 widgetH = 17; */\n        if (message.widgetH !== 0)\n            writer.tag(17, WireType.Varint).uint32(message.widgetH);\n        let u = options.writeUnknownFields;\n        if (u !== false)\n            (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);\n        return writer;\n    }\n}\n/**\n * @generated MessageType for protobuf message tutorial.MovingMessageBin\n */\nexport const MovingMessageBin = new MovingMessageBin$Type();\n"
  },
  {
    "path": "apps/builder/src/api/ws/illaBinaryWS.ts",
    "content": "import {\n  ILLA_WEBSOCKET_CONTEXT,\n  ILLA_WEBSOCKET_STATUS,\n} from \"@/api/ws/interface\"\nimport { getIsOnline } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { cursorActions } from \"@/redux/currentApp/cursor/cursorSlice\"\nimport { dragShadowActions } from \"@/redux/currentApp/dragShadow/dragShadowSlice\"\nimport store from \"@/store\"\nimport { MovingMessageBin, Signal } from \"./ILLA_PROTO\"\n\n// const HEARTBEAT_PING_TIMEOUT = 2 * 1000\n// const HEARTBEAT_PONG_TIMEOUT = 5 * 1000\nconst RECONNECT_TIMEOUT = 5 * 1000\nconst REPEAT_LIMIT = 5\n\nexport class ILLABinaryWebsocket {\n  url: string\n  ws: WebSocket | null = null\n  repeat: number = 0\n  lockReconnect: boolean = false\n  forbidReconnect: boolean = false\n  pingTimeoutId: number = -1\n  pongTimeoutId: number = -1\n  isOnline: boolean = getIsOnline(store.getState())\n  // messageQueue: Uint8Array[] = []\n  status: ILLA_WEBSOCKET_STATUS = ILLA_WEBSOCKET_STATUS.INIT\n  context: ILLA_WEBSOCKET_CONTEXT = ILLA_WEBSOCKET_CONTEXT.DASHBOARD\n\n  constructor(url: string, context: ILLA_WEBSOCKET_CONTEXT) {\n    this.url = url\n    this.context = context\n    this.createWebsocket()\n  }\n\n  private createWebsocket() {\n    try {\n      store.dispatch(\n        configActions.updateWSStatusReducer({\n          context: this.context,\n          wsStatus: ILLA_WEBSOCKET_STATUS.CONNECTING,\n        }),\n      )\n      this.ws = new WebSocket(this.url)\n      this.ws.binaryType = \"arraybuffer\"\n\n      this.initEventHandle()\n    } catch (e) {\n      this.reconnect()\n      throw e\n    }\n  }\n\n  private initEventHandle() {\n    if (this.ws) {\n      this.ws.onclose = () => {\n        this.reconnect()\n        store.dispatch(\n          configActions.updateWSStatusReducer({\n            context: this.context,\n            wsStatus: ILLA_WEBSOCKET_STATUS.CLOSED,\n          }),\n        )\n      }\n      this.ws.onerror = () => {\n        this.reconnect()\n        store.dispatch(\n          configActions.updateWSStatusReducer({\n            context: this.context,\n            wsStatus: ILLA_WEBSOCKET_STATUS.FAILED,\n          }),\n        )\n      }\n      this.ws.onopen = () => {\n        console.log(`[WS OPENED](${this.url}) connection succeeded`)\n\n        store.dispatch(configActions.updateDevicesOnlineStatusReducer(true))\n        store.dispatch(\n          configActions.updateWSStatusReducer({\n            context: this.context,\n            wsStatus: ILLA_WEBSOCKET_STATUS.CONNECTED,\n          }),\n        )\n        this.isOnline = true\n        this.repeat = 0\n        // this.heartCheck()\n        // while (this.messageQueue.length > 0) {\n        //   this.send(this.messageQueue.shift() as Uint8Array)\n        // }\n      }\n      this.ws.onmessage = (event) => {\n        this.onMessage(event)\n        // this.heartCheck()\n      }\n    }\n  }\n\n  private split(byteBuf: Uint8Array) {\n    const result = []\n    let start = 0\n\n    for (let i = 0; i < byteBuf.length; i++) {\n      if (\n        byteBuf[i] === 30 &&\n        byteBuf[i + 1] === 30 &&\n        byteBuf[i + 2] === 30 &&\n        byteBuf[i + 3] === 30\n      ) {\n        result.push(byteBuf.slice(start, i))\n        start = i + 4\n      }\n    }\n\n    if (start < byteBuf.length) {\n      result.push(byteBuf.slice(start))\n    }\n\n    return result\n  }\n\n  private reconnect() {\n    if (this.forbidReconnect) return\n    if (this.isOnline) {\n      store.dispatch(configActions.updateDevicesOnlineStatusReducer(false))\n      this.isOnline = false\n    }\n    if (REPEAT_LIMIT <= this.repeat) return\n    if (this.lockReconnect) return\n    this.lockReconnect = true\n    this.repeat++\n    setTimeout(() => {\n      this.createWebsocket()\n      this.lockReconnect = false\n    }, RECONNECT_TIMEOUT)\n  }\n\n  // private heartCheck() {\n  //   this.heartReset()\n  //   this.heartStart()\n  // }\n\n  // private heartStart() {\n  //   if (this.forbidReconnect) return\n  //   this.pingTimeoutId = window.setTimeout(() => {\n  //     this.ws?.send(pingMessage)\n  //     this.pongTimeoutId = window.setTimeout(() => {\n  //       if (this.isOnline) {\n  //         store.dispatch(configActions.updateDevicesOnlineStatusReducer(false))\n  //         this.isOnline = false\n  //       }\n  //       this.ws?.close()\n  //     }, HEARTBEAT_PONG_TIMEOUT)\n  //   }, HEARTBEAT_PING_TIMEOUT)\n  // }\n\n  // private heartReset() {\n  //   clearTimeout(this.pingTimeoutId)\n  //   clearTimeout(this.pongTimeoutId)\n  // }\n  public close() {\n    this.forbidReconnect = true\n    // this.heartReset()\n    this.ws?.close()\n  }\n  public onMessage(event: MessageEvent) {\n    const message = event.data\n    if (!(message instanceof ArrayBuffer)) {\n      return\n    }\n\n    const unit8ArrayMessage = new Uint8Array(message)\n    const updateDate = new Date()\n    const lastUpdateTime = updateDate.getTime()\n    const groupUnit8ArrayMessage = this.split(unit8ArrayMessage)\n    groupUnit8ArrayMessage.forEach((message) => {\n      try {\n        const payload = MovingMessageBin.fromBinary(message)\n        switch (payload.signal) {\n          case Signal.MOVE_CURSOR: {\n            store.dispatch(\n              cursorActions.updateCursorReducer({\n                userID: payload.userID,\n                nickname: payload.nickname,\n                parentDisplayName: payload.parentDisplayName,\n                status: payload.status,\n                xInteger: payload.cursorXInteger,\n                yInteger: payload.cursorYInteger,\n                xMod: payload.cursorXMod,\n                yMod: payload.cursorYMod,\n                lastUpdateTime,\n              }),\n            )\n            break\n          }\n          case Signal.MOVE_STATE: {\n            const lastUpdateTime = new Date().getTime()\n            store.dispatch(\n              dragShadowActions.updateDragShadowInfoReducer({\n                userID: payload.userID,\n                nickname: payload.nickname,\n                displayNames: payload.displayNames,\n                parentDisplayName: payload.parentDisplayName,\n                status: payload.status,\n                xInteger: payload.cursorXInteger,\n                yInteger: payload.cursorYInteger,\n                xMod: payload.cursorXMod,\n                yMod: payload.cursorYMod,\n                rectX: payload.widgetX,\n                rectY: payload.widgetY,\n                rectW: payload.widgetW,\n                rectH: payload.widgetH,\n                lastUpdateTime,\n              }),\n            )\n          }\n        }\n      } catch (e) {\n        console.debug(\"[debug] message is not a MovingMessageBin\", e)\n      }\n    })\n  }\n\n  public send(message: Uint8Array) {\n    if (this.ws?.readyState !== 1) {\n      // this.messageQueue.push(message)\n      return\n    }\n    try {\n      this.ws?.send(message)\n    } catch (e) {\n      console.error(e)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/api/ws/illaWS.ts",
    "content": "import { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { getAuthToken } from \"@illa-public/utils\"\nimport { getTextMessagePayload } from \"@/api/ws/index\"\nimport {\n  Callback,\n  ILLA_WEBSOCKET_CONTEXT,\n  ILLA_WEBSOCKET_STATUS,\n} from \"@/api/ws/interface\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\nimport { getIsOnline } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport store from \"@/store\"\nimport {\n  ADD_DISPLAY_NAME,\n  DisplayNameGenerator,\n  GENERATE_OR_UPDATE_DISPLAYNAME,\n  REMOVE_DISPLAY_NAME,\n  UPDATE_DISPLAY_NAME,\n} from \"@/utils/generators/generateDisplayName\"\n\nconst HEARTBEAT_PING_TIMEOUT = 10 * 1000\nconst HEARTBEAT_PONG_TIMEOUT = 10 * 1000\nconst RECONNECT_TIMEOUT = 5 * 1000\nconst REPEAT_LIMIT = 5\nconst MESSAGE_QUEUE_MAX_LENGTH = 20\n\nconst pingMessage = JSON.stringify({\n  signal: 0,\n  option: 0,\n  target: 0,\n  payload: [],\n  broadcast: null,\n})\n\nexport interface WSMessageListener {\n  onMessage: (\n    event: MessageEvent,\n    context: ILLA_WEBSOCKET_CONTEXT,\n    ws: ILLAWebsocket,\n  ) => void\n  onError?: (context: ILLA_WEBSOCKET_CONTEXT, ws: ILLAWebsocket) => void\n  onClosed?: (context: ILLA_WEBSOCKET_CONTEXT, ws: ILLAWebsocket) => void\n}\n\nexport const ReduxMessageListener: WSMessageListener = {\n  onMessage: (\n    event: MessageEvent,\n    context: ILLA_WEBSOCKET_CONTEXT,\n    ws: ILLAWebsocket,\n  ) => {\n    const message = event.data\n    if (typeof message !== \"string\") {\n      return\n    }\n\n    const dataList = message.split(\"\\n\")\n    dataList.forEach((data: string) => {\n      let callback: Callback<unknown> = JSON.parse(data)\n      if (callback.errorCode === 0) {\n        if (callback.broadcast != null) {\n          let broadcast = callback.broadcast\n          let type = broadcast.type\n          let payload = broadcast.payload\n          switch (type) {\n            case `${ADD_DISPLAY_NAME}/remote`: {\n              ;(payload as string[]).forEach((name) => {\n                DisplayNameGenerator.displayNameList.add(name)\n              })\n              break\n            }\n            case `${REMOVE_DISPLAY_NAME}/remote`: {\n              ;(payload as string[]).forEach((name) => {\n                DisplayNameGenerator.displayNameList.delete(name)\n              })\n              break\n            }\n            case `${UPDATE_DISPLAY_NAME}/remote`: {\n              DisplayNameGenerator.displayNameList.delete(payload[0])\n              DisplayNameGenerator.displayNameList.add(payload[1])\n              break\n            }\n            case `${GENERATE_OR_UPDATE_DISPLAYNAME}/remote`: {\n              DisplayNameGenerator.displayNameList.add(payload)\n            }\n            default: {\n              try {\n                store.dispatch({\n                  type,\n                  payload,\n                })\n              } catch (ignore) {}\n            }\n          }\n        }\n      } else if (callback.errorCode === 14) {\n        // signal for recover app snapshot\n        store.dispatch(\n          configActions.updateWSStatusReducer({\n            context: context,\n            wsStatus: ILLA_WEBSOCKET_STATUS.LOCKING,\n          }),\n        )\n        ws.reconnect()\n      }\n    })\n  },\n}\n\nexport class ILLAWebsocket {\n  url: string\n  ws: WebSocket | null = null\n  repeat: number = 0\n  lockReconnect: boolean = false\n  forbidReconnect: boolean = false\n  pingTimeoutId: number = -1\n  pongTimeoutId: number = -1\n  isOnline: boolean = getIsOnline(store.getState())\n  messageQueue: string[] = []\n  status: ILLA_WEBSOCKET_STATUS = ILLA_WEBSOCKET_STATUS.INIT\n  context: ILLA_WEBSOCKET_CONTEXT = ILLA_WEBSOCKET_CONTEXT.DASHBOARD\n  listeners: WSMessageListener[] = []\n\n  constructor(url: string, context: ILLA_WEBSOCKET_CONTEXT) {\n    this.url = url\n    this.context = context\n  }\n\n  public initWebsocket() {\n    try {\n      store.dispatch(\n        configActions.updateWSStatusReducer({\n          context: this.context,\n          wsStatus: ILLA_WEBSOCKET_STATUS.CONNECTING,\n        }),\n      )\n      this.ws = new WebSocket(this.url)\n      this.initEventHandle()\n    } catch (e) {\n      this.reconnect()\n      throw e\n    }\n  }\n\n  public registerListener(listener: WSMessageListener) {\n    this.listeners.push(listener)\n  }\n\n  public unRegisterListener(listener: WSMessageListener) {\n    const index = this.listeners.findIndex((value) => value === listener)\n    if (index != -1) {\n      this.listeners.splice(index, 1)\n    }\n  }\n\n  public clearListener() {\n    if (this.ws) {\n      this.ws.onclose = null\n      this.ws.onerror = null\n      this.ws.onopen = null\n      this.ws.onmessage = null\n    }\n    this.listeners = []\n  }\n\n  private initEventHandle() {\n    if (this.ws) {\n      this.ws.onclose = () => {\n        store.dispatch(\n          configActions.updateWSStatusReducer({\n            context: this.context,\n            wsStatus: ILLA_WEBSOCKET_STATUS.CLOSED,\n          }),\n        )\n        this.listeners.forEach((listener) => {\n          listener.onClosed?.(this.context, this)\n        })\n        this.reconnect()\n      }\n      this.ws.onerror = () => {\n        store.dispatch(\n          configActions.updateWSStatusReducer({\n            context: this.context,\n            wsStatus: ILLA_WEBSOCKET_STATUS.FAILED,\n          }),\n        )\n        this.listeners.forEach((listener) => {\n          listener.onError?.(this.context, this)\n        })\n        this.reconnect()\n      }\n      this.ws.onopen = () => {\n        const { id: teamID = \"\", uid = \"\" } =\n          getCurrentTeamInfo(store.getState()) ?? {}\n        store.dispatch(configActions.updateDevicesOnlineStatusReducer(true))\n        store.dispatch(\n          configActions.updateWSStatusReducer({\n            context: this.context,\n            wsStatus: ILLA_WEBSOCKET_STATUS.CONNECTED,\n          }),\n        )\n\n        this.send(\n          getTextMessagePayload(\n            TextSignal.ENTER,\n            TextTarget.NOTHING,\n            false,\n            {\n              type: \"enter\",\n              payload: [],\n            },\n            teamID,\n            uid,\n            [\n              {\n                authToken: getAuthToken(),\n              },\n            ],\n          ),\n        )\n        this.isOnline = true\n        this.repeat = 0\n        this.heartCheck()\n        while (this.messageQueue.length > 0) {\n          this.send(this.messageQueue.shift() as string)\n        }\n      }\n      this.ws.onmessage = (event) => {\n        this.listeners.forEach((listener) => {\n          listener.onMessage(event, this.context, this)\n        })\n        this.heartCheck()\n      }\n    }\n  }\n\n  public reconnect() {\n    if (this.forbidReconnect) return\n    if (this.isOnline) {\n      store.dispatch(configActions.updateDevicesOnlineStatusReducer(false))\n      this.isOnline = false\n    }\n    if (REPEAT_LIMIT <= this.repeat) return\n    if (this.lockReconnect) return\n    this.lockReconnect = true\n    this.repeat++\n    setTimeout(() => {\n      this.initWebsocket()\n      this.lockReconnect = false\n    }, RECONNECT_TIMEOUT)\n  }\n\n  private heartCheck() {\n    this.heartReset()\n    this.heartStart()\n  }\n\n  private heartStart() {\n    if (this.forbidReconnect) {\n      return\n    }\n    this.pingTimeoutId = window.setTimeout(() => {\n      this.ws?.send(pingMessage)\n      this.pongTimeoutId = window.setTimeout(() => {\n        if (this.isOnline) {\n          store.dispatch(configActions.updateDevicesOnlineStatusReducer(false))\n          this.isOnline = false\n        }\n        this.ws?.close()\n      }, HEARTBEAT_PONG_TIMEOUT)\n    }, HEARTBEAT_PING_TIMEOUT)\n  }\n\n  private heartReset() {\n    clearTimeout(this.pingTimeoutId)\n    clearTimeout(this.pongTimeoutId)\n  }\n\n  public close() {\n    this.forbidReconnect = true\n    this.clearListener()\n    this.heartReset()\n    this.ws?.close()\n  }\n\n  public send(message: string) {\n    if (this.ws?.readyState !== 1) {\n      this.messageQueue.push(message)\n      while (this.messageQueue.length > MESSAGE_QUEUE_MAX_LENGTH) {\n        this.messageQueue.shift()\n      }\n      return\n    }\n    try {\n      this.ws?.send(message)\n    } catch (e) {\n      console.error(e)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/api/ws/index.ts",
    "content": "import { HTTP_REQUEST_PUBLIC_BASE_URL } from \"@illa-public/illa-net/constant\"\nimport { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport {\n  ILLAWebsocket,\n  ReduxMessageListener,\n  WSMessageListener,\n} from \"@/api/ws/illaWS\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\nimport store from \"@/store\"\nimport { MovingMessageBin, Signal, Target } from \"./ILLA_PROTO\"\nimport { ILLABinaryWebsocket } from \"./illaBinaryWS\"\nimport {\n  Broadcast,\n  ILLAWebSocketComponentPayload,\n  ILLA_WEBSOCKET_CONTEXT,\n  RoomType,\n} from \"./interface\"\n\nexport function transformComponentReduxPayloadToWsPayload(\n  componentNodes: ComponentTreeNode[] | ComponentTreeNode,\n): ILLAWebSocketComponentPayload[] {\n  if (Array.isArray(componentNodes)) {\n    return componentNodes.map((node) => {\n      return {\n        before: {\n          displayName: node.displayName,\n        },\n        after: node,\n      }\n    })\n  }\n  if (!componentNodes) return []\n  return [\n    {\n      before: {\n        displayName: componentNodes.displayName,\n      },\n      after: componentNodes,\n    },\n  ]\n}\n\nexport function getTextMessagePayload<T>(\n  signal: TextSignal,\n  target: TextTarget,\n  broadcast: boolean,\n  reduxBroadcast: Broadcast | null,\n  teamID: string,\n  uid: string,\n  payload: T[],\n): string {\n  return JSON.stringify({\n    signal,\n    target,\n    option: broadcast ? 1 : 0,\n    broadcast: reduxBroadcast,\n    payload,\n    teamID,\n    uid,\n  })\n}\n\nexport const getBinaryMessagePayload = (\n  signal: Signal,\n  target: Target,\n  needBroadcast: boolean,\n  userID: string,\n  nickname: string,\n  status: number,\n  parentDisplayName: string,\n  displayNames: string,\n  cursorXInteger: number,\n  cursorYInteger: number,\n  cursorXMod: number,\n  cursorYMod: number,\n  widgetX: number,\n  widgetY: number,\n  widgetW: number,\n  widgetH: number,\n) => {\n  const payloadObject: MovingMessageBin = {\n    signal,\n    target,\n    clientID: \"\",\n    needBroadcast,\n    userID,\n    nickname,\n    status,\n    parentDisplayName,\n    displayNames,\n    cursorXInteger,\n    cursorYInteger,\n    cursorXMod,\n    cursorYMod,\n    widgetX,\n    widgetY,\n    widgetW,\n    widgetH,\n  }\n  return MovingMessageBin.toBinary(payloadObject)\n}\n\nexport const fixedWsURL = (wsURL: string) => {\n  const protocol = isCloudVersion\n    ? location.protocol\n    : new URL(HTTP_REQUEST_PUBLIC_BASE_URL).protocol\n  const wsProtocol = protocol === \"https:\" ? \"wss://\" : \"ws://\"\n\n  if (!isCloudVersion) {\n    const wsPREFIX = `${wsProtocol}${\n      new URL(HTTP_REQUEST_PUBLIC_BASE_URL).host\n    }`\n    wsURL = `${wsPREFIX}${wsURL}`\n  }\n  return wsURL\n}\n\nexport class Connection {\n  static roomMap: Map<string, ILLAWebsocket | ILLABinaryWebsocket> = new Map()\n\n  static enterDashboardRoom(wsURL: string) {\n    let ws = generateTextMessageWs(wsURL, ILLA_WEBSOCKET_CONTEXT.DASHBOARD)\n    ws.registerListener(ReduxMessageListener)\n    ws.initWebsocket()\n    this.roomMap.set(\"dashboard/\", ws)\n  }\n\n  static enterAppRoom(wsURL: string, binaryWsURL: string, appID: string) {\n    let ws = generateTextMessageWs(wsURL, ILLA_WEBSOCKET_CONTEXT.APP)\n    ws.registerListener(ReduxMessageListener)\n    ws.initWebsocket()\n    let binaryWs = generateBinaryMessageWs(binaryWsURL)\n    this.roomMap.set(`app/${appID}`, ws)\n    this.roomMap.set(`app/${appID}/binary`, binaryWs)\n  }\n\n  static enterAgentRoom(wsURL: string, messageListener: WSMessageListener) {\n    let ws = generateTextMessageWs(wsURL, ILLA_WEBSOCKET_CONTEXT.AI_AGENT)\n    ws.registerListener(messageListener)\n    ws.initWebsocket()\n    this.roomMap.set(\"ai-agent/\", ws)\n  }\n\n  static getTextRoom(\n    type: RoomType,\n    roomId: string,\n  ): ILLAWebsocket | undefined {\n    return this.roomMap.get(`${type}/${roomId}`) as ILLAWebsocket\n  }\n\n  static getBinaryRoom(\n    type: RoomType,\n    roomId: string,\n  ): ILLABinaryWebsocket | undefined {\n    return this.roomMap.get(`${type}/${roomId}/binary`) as ILLABinaryWebsocket\n  }\n\n  static leaveRoom(type: RoomType, roomId: string) {\n    const { id: teamID = \"\", uid = \"\" } =\n      getCurrentTeamInfo(store.getState()) ?? {}\n    let textWS = this.roomMap.get(`${type}/${roomId}`) as ILLAWebsocket\n    let binaryWS = this.roomMap.get(`app/${roomId}/binary`)\n    if (textWS != undefined) {\n      textWS.send(\n        getTextMessagePayload(\n          TextSignal.LEAVE,\n          TextTarget.NOTHING,\n          false,\n          {\n            type: \"leave\",\n            payload: [],\n          },\n          teamID,\n          uid,\n          [],\n        ),\n      )\n      textWS.close()\n    }\n    if (binaryWS != undefined) {\n      binaryWS.close()\n    }\n  }\n}\n\nexport function generateTextMessageWs(\n  url: string,\n  context: ILLA_WEBSOCKET_CONTEXT,\n) {\n  return new ILLAWebsocket(url, context)\n}\n\nexport function generateBinaryMessageWs(url: string) {\n  return new ILLABinaryWebsocket(url, ILLA_WEBSOCKET_CONTEXT.APP_BINARY)\n}\n"
  },
  {
    "path": "apps/builder/src/api/ws/interface.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\n\nexport type RoomType = \"dashboard\" | \"app\" | \"ai-agent\"\n\nexport interface Room {\n  wsURL: string\n}\n\nexport interface Broadcast {\n  type: string\n  payload: any\n}\n\nexport interface Callback<T> {\n  broadcast: Broadcast\n  // extra data\n  data: T\n  // string\n  errorMessage: string\n  // 0 success, not zero error\n  errorCode: number\n  target: TextTarget\n  signal: TextSignal\n}\n\nexport interface ILLAWebSocketComponentPayload {\n  before: {\n    displayName: string\n  }\n  after: ComponentTreeNode\n}\n\nexport enum ILLA_WEBSOCKET_STATUS {\n  INIT = \"INIT\",\n  CONNECTING = \"CONNECTING\",\n  CONNECTED = \"CONNECTED\",\n  CLOSED = \"CLOSED\",\n  FAILED = \"FAILED\",\n  LOCKING = \"LOCKING\",\n}\n\nexport enum ILLA_WEBSOCKET_CONTEXT {\n  DASHBOARD = \"DASHBOARD\",\n  APP = \"APP\",\n  APP_BINARY = \"APP_BINARY\",\n  AI_AGENT = \"AI_AGENT\",\n}\n"
  },
  {
    "path": "apps/builder/src/api/ws/textSignal.ts",
    "content": "export enum TextSignal {\n  PING = 0,\n  ENTER = 1,\n  LEAVE = 2,\n  CREATE_STATE = 3,\n  DELETE_STATE = 4,\n  UPDATE_STATE = 5,\n  MOVE_STATE = 6,\n  CREATE_OR_UPDATE_STATE = 7,\n  BROADCAST_ONLY = 8,\n  PUT_STATE = 9,\n  GLOBAL_BROADCAST_ONLY = 10,\n  COOPERATE_ATTACH = 11,\n  COOPERATE_DISATTACH = 12,\n  MOVE_CURSOR = 13,\n  FORCE_REFRESH = 14,\n  TAKE_APP_SNAPSHOT = 15,\n  RECOVER_APP_SNAPSHOT = 16,\n  RUN = 17,\n  STOP_ALL = 18,\n  CLEAN = 19,\n}\n\nexport enum TextTarget {\n  NOTHING = 0,\n  COMPONENTS = 1,\n  DEPENDENCIES = 2,\n  DRAG_SHADOW = 3,\n  DOTTED_LINE_SQUARE = 4,\n  DISPLAY_NAME = 5,\n  APPS = 6,\n  RESOURCE = 7,\n  ACTION = 8,\n  CURSOR = 9,\n  WINDOW = 10,\n}\n\nexport enum ErrorCode {\n  ERROR_CODE_OK = 0,\n  ERROR_CODE_FAILED = 1,\n  ERROR_CODE_NEED_ENTER = 2,\n  ERROR_CODE_PONG = 3,\n  ERROR_CODE_LOGIN_FAILED = 4,\n  ERROR_CREATE_STATE_FAILED = 5,\n  ERROR_DELETE_STATE_FAILED = 6,\n  ERROR_UPDATE_STATE_FAILED = 7,\n  ERROR_MOVE_STATE_FAILED = 8,\n  ERROR_CREATE_OR_UPDATE_STATE_FAILED = 9,\n  ERROR_CAN_NOT_MOVE_KVSTATE = 10,\n  ERROR_CAN_NOT_MOVE_SETSTATE = 11,\n  ERROR_CREATE_SNAPSHOT_MODIFY_HISTORY_FAILED = 12,\n  ERROR_UPDATE_SNAPSHOT_MODIFY_HISTORY_FAILED = 13,\n  ERROR_FORCE_REFRESH_WINDOW = 14,\n  ERROR_MESSAGE_END = 15,\n}\n"
  },
  {
    "path": "apps/builder/src/assets/animationForLottie/celebrate.json",
    "content": "{\"v\":\"5.5.6\",\"fr\":70,\"ip\":0,\"op\":370,\"w\":609,\"h\":812,\"nm\":\"lottie (mobile)\",\"ddd\":0,\"assets\":[{\"id\":\"comp_0\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":0,\"nm\":\"_small-side\",\"refId\":\"comp_1\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[218,320,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[400,400,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[-100,100,100],\"ix\":6}},\"ao\":0,\"w\":800,\"h\":800,\"ip\":15,\"op\":234,\"st\":15,\"bm\":0}]},{\"id\":\"comp_1\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"streamer b\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":166,\"ix\":10},\"p\":{\"a\":0,\"k\":[554,664,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-157,-245,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],\"o\":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],\"v\":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":9,\"s\":[4]},{\"t\":57,\"s\":[0.5]}],\"ix\":5},\"lc\":2,\"lj\":2,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":14,\"s\":[0]},{\"t\":57,\"s\":[100]}],\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":9,\"s\":[0]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":14,\"s\":[35]},{\"t\":57,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":9,\"op\":58,\"st\":9,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":4,\"nm\":\"streamer a\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":167,\"ix\":10},\"p\":{\"a\":0,\"k\":[532,582,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-157,-245,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[-100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],\"o\":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],\"v\":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":5,\"s\":[4]},{\"t\":48,\"s\":[0.5]}],\"ix\":5},\"lc\":2,\"lj\":2,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":10,\"s\":[0]},{\"t\":48,\"s\":[100]}],\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":5,\"s\":[0]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":10,\"s\":[35]},{\"t\":48,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":5,\"op\":49,\"st\":5,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":4,\"nm\":\"circle a\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":1,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":29,\"s\":[321.019]},{\"t\":158,\"s\":[1800]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":1,\"s\":[599.5,838,0],\"to\":[-30,-106.667,0],\"ti\":[46.667,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":29,\"s\":[419.5,198,0],\"to\":[-46.667,0,0],\"ti\":[0,0,0]},{\"t\":158,\"s\":[319.5,838,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0,0]},\"t\":1,\"s\":[50,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[1,0.833,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":29,\"s\":[100,100,100]},{\"t\":128,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":1,\"op\":159,\"st\":1,\"bm\":0},{\"ddd\":0,\"ind\":4,\"ty\":4,\"nm\":\"circle b\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":3,\"s\":[0]},{\"t\":128,\"s\":[1440]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":3,\"s\":[599.5,838,0],\"to\":[-26.667,-93.333,0],\"ti\":[66.667,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":21,\"s\":[439.5,278,0],\"to\":[-66.667,0,0],\"ti\":[0,0,0]},{\"t\":128,\"s\":[199.5,838,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0,0]},\"t\":3,\"s\":[50,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[1,0.833,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":21,\"s\":[100,100,100]},{\"t\":98,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":3,\"op\":129,\"st\":3,\"bm\":0},{\"ddd\":0,\"ind\":5,\"ty\":4,\"nm\":\"star a\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":1,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":31,\"s\":[343.949]},{\"t\":158,\"s\":[1800]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":1,\"s\":[596.087,836.292,0],\"to\":[-36.098,-100,0],\"ti\":[52.765,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":31,\"s\":[379.5,236.292,0],\"to\":[-52.765,0,0],\"ti\":[0,0,0]},{\"t\":158,\"s\":[279.5,836.292,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0,0]},\"t\":1,\"s\":[50,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[1,0.833,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":31,\"s\":[100,100,100]},{\"t\":128,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":1,\"d\":1,\"pt\":{\"a\":0,\"k\":5,\"ix\":3},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"r\":{\"a\":0,\"k\":0,\"ix\":5},\"ir\":{\"a\":0,\"k\":5,\"ix\":6},\"is\":{\"a\":0,\"k\":0,\"ix\":8},\"or\":{\"a\":0,\"k\":12,\"ix\":7},\"os\":{\"a\":0,\"k\":0,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\",\"mn\":\"ADBE Vector Shape - Star\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":1,\"op\":159,\"st\":1,\"bm\":0},{\"ddd\":0,\"ind\":6,\"ty\":4,\"nm\":\"star b\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":3,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":23,\"s\":[288]},{\"t\":128,\"s\":[1800]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":3,\"s\":[596.087,836.292,0],\"to\":[-39.431,-113.333,0],\"ti\":[66.098,1.667,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":23,\"s\":[359.5,156.292,0],\"to\":[-66.098,-1.667,0],\"ti\":[0,0,0]},{\"t\":128,\"s\":[199.5,826.292,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0,0]},\"t\":3,\"s\":[50,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[1,0.833,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":23,\"s\":[100,100,100]},{\"t\":98,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":1,\"d\":1,\"pt\":{\"a\":0,\"k\":5,\"ix\":3},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"r\":{\"a\":0,\"k\":0,\"ix\":5},\"ir\":{\"a\":0,\"k\":5,\"ix\":6},\"is\":{\"a\":0,\"k\":0,\"ix\":8},\"or\":{\"a\":0,\"k\":12,\"ix\":7},\"os\":{\"a\":0,\"k\":0,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\",\"mn\":\"ADBE Vector Shape - Star\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9921568627450981,0.4980392156862745,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":3,\"op\":129,\"st\":3,\"bm\":0},{\"ddd\":0,\"ind\":7,\"ty\":4,\"nm\":\"rec a\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":0,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":33,\"s\":[381.468]},{\"t\":218,\"s\":[2520]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":0,\"s\":[599.5,842,0],\"to\":[-23.333,-100,0],\"ti\":[41.333,1.333,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":33,\"s\":[459.5,242,0],\"to\":[-41.333,-1.333,0],\"ti\":[0,0,0]},{\"t\":218,\"s\":[351.5,834,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0,0]},\"t\":0,\"s\":[50,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[1,0.833,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":33,\"s\":[100,100,100]},{\"t\":188,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,8],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[1,0.8313725490196079,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":219,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":8,\"ty\":4,\"nm\":\"rec b\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":2,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":25,\"s\":[262.857]},{\"t\":191,\"s\":[2160]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":2,\"s\":[599.5,842,0],\"to\":[-23.333,-113.333,0],\"ti\":[74,5,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":25,\"s\":[459.5,162,0],\"to\":[-74,-5,0],\"ti\":[0,0,0]},{\"t\":191,\"s\":[155.5,812,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0,0]},\"t\":2,\"s\":[50,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[1,0.833,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":25,\"s\":[100,100,100]},{\"t\":161,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,8],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":2,\"op\":192,\"st\":2,\"bm\":0},{\"ddd\":0,\"ind\":9,\"ty\":4,\"nm\":\"square a\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":0,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":35,\"s\":[462.385]},{\"t\":218,\"s\":[2880]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":0,\"s\":[599.5,838,0],\"to\":[-43.333,-123.333,0],\"ti\":[60,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":35,\"s\":[339.5,98,0],\"to\":[-60,0,0],\"ti\":[0,0,0]},{\"t\":218,\"s\":[239.5,838,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0,0]},\"t\":0,\"s\":[50,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[1,0.833,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":35,\"s\":[100,100,100]},{\"t\":188,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9921568627450981,0.4980392156862745,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":219,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":10,\"ty\":4,\"nm\":\"square b\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":2,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":27,\"s\":[285.714]},{\"t\":191,\"s\":[2160]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":2,\"s\":[599.5,838,0],\"to\":[-30,-120,0],\"ti\":[75,3.333,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":27,\"s\":[419.5,118,0],\"to\":[-75,-3.333,0],\"ti\":[0,0,0]},{\"t\":191,\"s\":[149.5,818,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0,0]},\"t\":2,\"s\":[50,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[1,0.833,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":27,\"s\":[100,100,100]},{\"t\":161,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":2,\"op\":192,\"st\":2,\"bm\":0},{\"ddd\":0,\"ind\":11,\"ty\":4,\"nm\":\"streamer b 2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":171,\"ix\":10},\"p\":{\"a\":0,\"k\":[543,427,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-157,-245,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],\"o\":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],\"v\":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.9686274509803922,0.37254901960784315,0.023529411764705882,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":13,\"s\":[4]},{\"t\":61,\"s\":[0.5]}],\"ix\":5},\"lc\":2,\"lj\":2,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":18,\"s\":[0]},{\"t\":61,\"s\":[100]}],\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":13,\"s\":[0]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":18,\"s\":[35]},{\"t\":61,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":13,\"op\":62,\"st\":13,\"bm\":0},{\"ddd\":0,\"ind\":12,\"ty\":4,\"nm\":\"streamer a 2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":151,\"ix\":10},\"p\":{\"a\":0,\"k\":[454,444,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-157,-245,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[-100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],\"o\":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],\"v\":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":10,\"s\":[4]},{\"t\":53,\"s\":[0.5]}],\"ix\":5},\"lc\":2,\"lj\":2,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":15,\"s\":[0]},{\"t\":53,\"s\":[100]}],\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":10,\"s\":[0]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":15,\"s\":[35]},{\"t\":53,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":10,\"op\":54,\"st\":10,\"bm\":0},{\"ddd\":0,\"ind\":13,\"ty\":4,\"nm\":\"circle a 2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":1,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":29,\"s\":[-371.368]},{\"t\":191,\"s\":[-2520]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":1,\"s\":[599.5,838,0],\"to\":[-53.333,-113.333,0],\"ti\":[56.667,-3.333,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":29,\"s\":[279.5,158,0],\"to\":[-56.667,3.333,0],\"ti\":[0,0,0]},{\"t\":191,\"s\":[259.5,858,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0.167,0]},\"t\":1,\"s\":[100,50,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,1,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":29,\"s\":[100,100,100]},{\"t\":161,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[1,0.8313725490196079,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":1,\"op\":192,\"st\":1,\"bm\":0},{\"ddd\":0,\"ind\":14,\"ty\":4,\"nm\":\"circle b 2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":3,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":21,\"s\":[-250.839]},{\"t\":158,\"s\":[-2160]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":3,\"s\":[599.5,838,0],\"to\":[-53.333,-100,0],\"ti\":[63,-7,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":21,\"s\":[279.5,238,0],\"to\":[-63,7,0],\"ti\":[0,0,0]},{\"t\":158,\"s\":[221.5,880,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0.167,0]},\"t\":3,\"s\":[100,50,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,1,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":21,\"s\":[100,100,100]},{\"t\":128,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9921568627450981,0.4980392156862745,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":3,\"op\":159,\"st\":3,\"bm\":0},{\"ddd\":0,\"ind\":15,\"ty\":4,\"nm\":\"star a 2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":1,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":31,\"s\":[-397.895]},{\"t\":191,\"s\":[-2520]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":1,\"s\":[596.087,836.292,0],\"to\":[-9.431,-113.333,0],\"ti\":[42.765,-3.333,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":31,\"s\":[539.5,156.292,0],\"to\":[-42.765,3.333,0],\"ti\":[0,0,0]},{\"t\":191,\"s\":[339.5,856.292,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0.167,0]},\"t\":1,\"s\":[100,50,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,1,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":31,\"s\":[100,100,100]},{\"t\":161,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":1,\"d\":1,\"pt\":{\"a\":0,\"k\":5,\"ix\":3},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"r\":{\"a\":0,\"k\":0,\"ix\":5},\"ir\":{\"a\":0,\"k\":5,\"ix\":6},\"is\":{\"a\":0,\"k\":0,\"ix\":8},\"or\":{\"a\":0,\"k\":12,\"ix\":7},\"os\":{\"a\":0,\"k\":0,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\",\"mn\":\"ADBE Vector Shape - Star\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":1,\"op\":192,\"st\":1,\"bm\":0},{\"ddd\":0,\"ind\":16,\"ty\":4,\"nm\":\"star b 2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":3,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":23,\"s\":[-278.71]},{\"t\":158,\"s\":[-2160]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":3,\"s\":[596.087,836.292,0],\"to\":[-12.765,-96.667,0],\"ti\":[52.765,-3.333,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":23,\"s\":[519.5,256.292,0],\"to\":[-52.765,3.333,0],\"ti\":[0,0,0]},{\"t\":158,\"s\":[279.5,856.292,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0.167,0]},\"t\":3,\"s\":[100,50,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,1,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":23,\"s\":[100,100,100]},{\"t\":128,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":1,\"d\":1,\"pt\":{\"a\":0,\"k\":5,\"ix\":3},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"r\":{\"a\":0,\"k\":0,\"ix\":5},\"ir\":{\"a\":0,\"k\":5,\"ix\":6},\"is\":{\"a\":0,\"k\":0,\"ix\":8},\"or\":{\"a\":0,\"k\":12,\"ix\":7},\"os\":{\"a\":0,\"k\":0,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\",\"mn\":\"ADBE Vector Shape - Star\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":3,\"op\":159,\"st\":3,\"bm\":0},{\"ddd\":0,\"ind\":17,\"ty\":4,\"nm\":\"rec a 2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":0,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":33,\"s\":[-556.875]},{\"t\":128,\"s\":[-2160]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":0,\"s\":[599.5,842,0],\"to\":[-16.667,-120,0],\"ti\":[66.667,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":33,\"s\":[499.5,122,0],\"to\":[-66.667,0,0],\"ti\":[0,0,0]},{\"t\":128,\"s\":[199.5,842,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0.167,0]},\"t\":0,\"s\":[100,50,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[1,0.833,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":33,\"s\":[100,100,100]},{\"t\":98,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,8],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9921568627450981,0.4980392156862745,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":129,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":18,\"ty\":4,\"nm\":\"rec b 2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":2,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":25,\"s\":[-306.667]},{\"t\":218,\"s\":[-2880]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":2,\"s\":[599.5,842,0],\"to\":[-22.62,-109.87,0],\"ti\":[2.877,-2.055,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":25,\"s\":[339.5,262,0],\"to\":[-51.333,36.667,0],\"ti\":[0,0,0]},{\"t\":218,\"s\":[219.5,862,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0.167,0]},\"t\":2,\"s\":[100,50,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,1,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":25,\"s\":[100,100,100]},{\"t\":188,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,8],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9686274509803922,0.37254901960784315,0.023529411764705882,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":2,\"op\":219,\"st\":2,\"bm\":0},{\"ddd\":0,\"ind\":19,\"ty\":4,\"nm\":\"square a 2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":0,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":35,\"s\":[-590.625]},{\"t\":128,\"s\":[-2160]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":0,\"s\":[599.5,838,0],\"to\":[-20,-90,0],\"ti\":[36.667,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":35,\"s\":[479.5,298,0],\"to\":[-36.667,0,0],\"ti\":[0,0,0]},{\"t\":128,\"s\":[379.5,838,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0.167,0]},\"t\":0,\"s\":[100,50,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,1,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":35,\"s\":[100,100,100]},{\"t\":98,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":129,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":20,\"ty\":4,\"nm\":\"square b 2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":2,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"t\":27,\"s\":[-333.333]},{\"t\":218,\"s\":[-2880]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":2,\"s\":[599.5,838,0],\"to\":[-10,-103.333,0],\"ti\":[50,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"t\":27,\"s\":[539.5,218,0],\"to\":[-50,0,0],\"ti\":[0,0,0]},{\"t\":218,\"s\":[299.5,838,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0.167,0]},\"t\":2,\"s\":[100,50,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,1,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"t\":27,\"s\":[100,100,100]},{\"t\":188,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":2,\"op\":219,\"st\":2,\"bm\":0}]},{\"id\":\"comp_2\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":0,\"nm\":\"_small-side\",\"refId\":\"comp_1\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[260,320,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[400,400,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":800,\"h\":800,\"ip\":0,\"op\":219,\"st\":0,\"bm\":0}]},{\"id\":\"comp_3\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":0,\"nm\":\"left\",\"refId\":\"comp_4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[400,400,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[400,400,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":800,\"h\":800,\"ip\":13,\"op\":313,\"st\":13,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":0,\"nm\":\"right\",\"refId\":\"comp_4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[400,400,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[400,400,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[-100,100,100],\"ix\":6}},\"ao\":0,\"w\":800,\"h\":800,\"ip\":30,\"op\":330,\"st\":30,\"bm\":0}]},{\"id\":\"comp_4\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"streamer a 4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":14,\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":13,\"s\":[219.178,-190.096,0],\"to\":[-95.333,426.667,0],\"ti\":[167.333,-560.667,0]},{\"t\":173,\"s\":[179.178,989.904,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[-157,-245,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[-100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],\"o\":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],\"v\":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":13,\"s\":[4]},{\"t\":176,\"s\":[0.5]}],\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":18,\"s\":[0]},{\"t\":176,\"s\":[100]}],\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":13,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":18,\"s\":[40]},{\"t\":176,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":13,\"op\":174,\"st\":13,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":4,\"nm\":\"streamer b 4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-1.458,\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":5,\"s\":[269.863,-175.455,0],\"to\":[-110,415.333,0],\"ti\":[216,-599.333,0]},{\"t\":173,\"s\":[69.863,984.545,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[-157,-245,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],\"o\":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],\"v\":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":5,\"s\":[4]},{\"t\":173,\"s\":[0.5]}],\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":10,\"s\":[0]},{\"t\":173,\"s\":[100]}],\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":5,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":10,\"s\":[40]},{\"t\":173,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":5,\"op\":174,\"st\":5,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":4,\"nm\":\"circle a 4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":8,\"s\":[0]},{\"t\":155,\"s\":[1800]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":8,\"s\":[325.643,-26.292,0],\"to\":[-101.333,75.667,0],\"ti\":[15.333,-507.667,0]},{\"t\":155,\"s\":[125.643,835.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":8,\"s\":[50,100,100]},{\"t\":155,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":8,\"op\":156,\"st\":-7,\"bm\":0},{\"ddd\":0,\"ind\":4,\"ty\":4,\"nm\":\"circle b 4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":2,\"s\":[0]},{\"t\":215,\"s\":[2520]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":2,\"s\":[619.5,-26.292,0],\"to\":[-138,77.667,0],\"ti\":[-2,-497.667,0]},{\"t\":215,\"s\":[259.5,835.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":2,\"s\":[50,100,100]},{\"t\":215,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":2,\"op\":216,\"st\":-13,\"bm\":0},{\"ddd\":0,\"ind\":5,\"ty\":4,\"nm\":\"star a 4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":6,\"s\":[0]},{\"t\":245,\"s\":[2880]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":6,\"s\":[376.929,-28,0],\"to\":[-213.333,157.667,0],\"ti\":[173.333,-127.667,0]},{\"t\":245,\"s\":[116.929,834,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":6,\"s\":[50,100,100]},{\"t\":245,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":1,\"d\":1,\"pt\":{\"a\":0,\"k\":5,\"ix\":3},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"r\":{\"a\":0,\"k\":0,\"ix\":5},\"ir\":{\"a\":0,\"k\":5,\"ix\":6},\"is\":{\"a\":0,\"k\":0,\"ix\":8},\"or\":{\"a\":0,\"k\":12,\"ix\":7},\"os\":{\"a\":0,\"k\":0,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\",\"mn\":\"ADBE Vector Shape - Star\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":6,\"op\":246,\"st\":-9,\"bm\":0},{\"ddd\":0,\"ind\":6,\"ty\":4,\"nm\":\"star b 4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":2,\"s\":[0]},{\"t\":125,\"s\":[1800]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":2,\"s\":[171.786,-28,0],\"to\":[0,0,0],\"ti\":[-161.333,-275.667,0]},{\"t\":125,\"s\":[251.786,834,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":2,\"s\":[50,100,100]},{\"t\":125,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":1,\"d\":1,\"pt\":{\"a\":0,\"k\":5,\"ix\":3},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"r\":{\"a\":0,\"k\":0,\"ix\":5},\"ir\":{\"a\":0,\"k\":5,\"ix\":6},\"is\":{\"a\":0,\"k\":0,\"ix\":8},\"or\":{\"a\":0,\"k\":12,\"ix\":7},\"os\":{\"a\":0,\"k\":0,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\",\"mn\":\"ADBE Vector Shape - Star\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9921568627450981,0.4980392156862745,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":2,\"op\":126,\"st\":-13,\"bm\":0},{\"ddd\":0,\"ind\":7,\"ty\":4,\"nm\":\"rec a 4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":4,\"s\":[0]},{\"t\":185,\"s\":[2520]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":4,\"s\":[428.214,-22.292,0],\"to\":[-167.333,119.667,0],\"ti\":[-130.667,-315.667,0]},{\"t\":185,\"s\":[228.214,839.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":4,\"s\":[50,100,100]},{\"t\":185,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,8],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[1,0.8313725490196079,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":4,\"op\":186,\"st\":-11,\"bm\":0},{\"ddd\":0,\"ind\":8,\"ty\":4,\"nm\":\"rec b 4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":6,\"s\":[0]},{\"t\":245,\"s\":[2880]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":6,\"s\":[223.071,-22.292,0],\"to\":[0,0,0],\"ti\":[-92.571,-383.708,0]},{\"t\":245,\"s\":[223.071,839.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":6,\"s\":[50,100,100]},{\"t\":245,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,8],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":6,\"op\":246,\"st\":-9,\"bm\":0},{\"ddd\":0,\"ind\":9,\"ty\":4,\"nm\":\"square a 4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":4,\"s\":[0]},{\"t\":217,\"s\":[2520]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":4,\"s\":[120.5,-26.292,0],\"to\":[13,430.305,0],\"ti\":[52.221,-418.892,0]},{\"t\":217,\"s\":[198.5,833.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":4,\"s\":[50,100,100]},{\"t\":217,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9921568627450981,0.4980392156862745,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":4,\"op\":218,\"st\":-11,\"bm\":0},{\"ddd\":0,\"ind\":10,\"ty\":4,\"nm\":\"square b 4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":8,\"s\":[0]},{\"t\":215,\"s\":[2520]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":8,\"s\":[274.357,-26.292,0],\"to\":[157.333,415.667,0],\"ti\":[22.667,-253.667,0]},{\"t\":215,\"s\":[114.357,835.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":8,\"s\":[50,100,100]},{\"t\":215,\"s\":[100,50,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9921568627450981,0.4980392156862745,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":8,\"op\":216,\"st\":-7,\"bm\":0},{\"ddd\":0,\"ind\":11,\"ty\":4,\"nm\":\"streamer a 3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":3,\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":0,\"s\":[275.178,-173.096,0],\"to\":[-87.333,413.333,0],\"ti\":[177.333,-643.333,0]},{\"t\":185,\"s\":[219.178,974.904,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[-157,-245,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[-100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],\"o\":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],\"v\":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":0,\"s\":[4]},{\"t\":177,\"s\":[0.5]}],\"ix\":5},\"lc\":2,\"lj\":2,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":5,\"s\":[0]},{\"t\":177,\"s\":[100]}],\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":0,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":5,\"s\":[40]},{\"t\":177,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":0,\"op\":186,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":12,\"ty\":4,\"nm\":\"streamer b 3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":9,\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":11,\"s\":[199.863,74.545,0],\"to\":[-13.363,405.455,0],\"ti\":[179.333,-430.667,0]},{\"t\":217,\"s\":[139.863,834.545,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[-157,-245,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-1.685,-13.314],[0,-14.907],[0,-15.206],[0,-14.907],[0,-14.907],[0,-15.206],[1.754,-14.206],[-3.934,-9.465]],\"o\":[[-3.895,8.562],[1.872,14.789],[0,15.206],[0,14.907],[0,14.907],[0,15.206],[0,14.314],[-1.803,14.605],[0,0]],\"v\":[[-156.5,-406],[-166.5,-367],[-146.5,-327],[-166.5,-286],[-146.5,-246],[-166.5,-206],[-146.5,-165],[-166.5,-127],[-156.5,-84]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.9686274509803922,0.37254901960784315,0.023529411764705882,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":11,\"s\":[4]},{\"t\":199,\"s\":[0.5]}],\"ix\":5},\"lc\":2,\"lj\":2,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":16,\"s\":[0]},{\"t\":199,\"s\":[100]}],\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":11,\"s\":[0]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":16,\"s\":[40]},{\"t\":199,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":11,\"op\":218,\"st\":11,\"bm\":0},{\"ddd\":0,\"ind\":13,\"ty\":4,\"nm\":\"circle a 3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":2,\"s\":[0]},{\"t\":125,\"s\":[-1800]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":2,\"s\":[365.643,-26.292,0],\"to\":[-101.333,75.667,0],\"ti\":[15.333,-507.667,0]},{\"t\":125,\"s\":[165.643,835.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":2,\"s\":[100,50,100]},{\"t\":125,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[1,0.8313725490196079,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":2,\"op\":126,\"st\":-13,\"bm\":0},{\"ddd\":0,\"ind\":14,\"ty\":4,\"nm\":\"circle b 3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":8,\"s\":[0]},{\"t\":245,\"s\":[-2880]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":8,\"s\":[519.5,-26.292,0],\"to\":[-138,77.667,0],\"ti\":[-2,-497.667,0]},{\"t\":245,\"s\":[159.5,835.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":8,\"s\":[100,50,100]},{\"t\":245,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9921568627450981,0.4980392156862745,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":8,\"op\":246,\"st\":-7,\"bm\":0},{\"ddd\":0,\"ind\":15,\"ty\":4,\"nm\":\"star a 3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":6,\"s\":[0]},{\"t\":245,\"s\":[-2880]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":6,\"s\":[416.929,-28,0],\"to\":[-213.333,157.667,0],\"ti\":[173.333,-127.667,0]},{\"t\":245,\"s\":[156.929,834,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":6,\"s\":[100,50,100]},{\"t\":245,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":1,\"d\":1,\"pt\":{\"a\":0,\"k\":5,\"ix\":3},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"r\":{\"a\":0,\"k\":0,\"ix\":5},\"ir\":{\"a\":0,\"k\":5,\"ix\":6},\"is\":{\"a\":0,\"k\":0,\"ix\":8},\"or\":{\"a\":0,\"k\":12,\"ix\":7},\"os\":{\"a\":0,\"k\":0,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\",\"mn\":\"ADBE Vector Shape - Star\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":6,\"op\":246,\"st\":-9,\"bm\":0},{\"ddd\":0,\"ind\":16,\"ty\":4,\"nm\":\"star b 3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":8,\"s\":[0]},{\"t\":155,\"s\":[-2160]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":8,\"s\":[211.786,-28,0],\"to\":[0,0,0],\"ti\":[-161.333,-275.667,0]},{\"t\":155,\"s\":[291.786,834,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":8,\"s\":[100,50,100]},{\"t\":155,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":1,\"d\":1,\"pt\":{\"a\":0,\"k\":5,\"ix\":3},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"r\":{\"a\":0,\"k\":0,\"ix\":5},\"ir\":{\"a\":0,\"k\":5,\"ix\":6},\"is\":{\"a\":0,\"k\":0,\"ix\":8},\"or\":{\"a\":0,\"k\":12,\"ix\":7},\"os\":{\"a\":0,\"k\":0,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\",\"mn\":\"ADBE Vector Shape - Star\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":8,\"op\":156,\"st\":-7,\"bm\":0},{\"ddd\":0,\"ind\":17,\"ty\":4,\"nm\":\"rec a 3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":4,\"s\":[0]},{\"t\":185,\"s\":[-2160]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":4,\"s\":[468.214,-22.292,0],\"to\":[-167.333,119.667,0],\"ti\":[-130.667,-315.667,0]},{\"t\":185,\"s\":[268.214,839.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":4,\"s\":[100,50,100]},{\"t\":185,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,8],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9921568627450981,0.4980392156862745,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":4,\"op\":186,\"st\":-11,\"bm\":0},{\"ddd\":0,\"ind\":18,\"ty\":4,\"nm\":\"rec b 3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":6,\"s\":[0]},{\"t\":245,\"s\":[-2880]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":6,\"s\":[263.071,-22.292,0],\"to\":[0,143.667,0],\"ti\":[-114.571,-267.708,0]},{\"t\":245,\"s\":[263.071,839.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":6,\"s\":[100,50,100]},{\"t\":245,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,8],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9686274509803922,0.37254901960784315,0.023529411764705882,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":6,\"op\":246,\"st\":-9,\"bm\":0},{\"ddd\":0,\"ind\":19,\"ty\":4,\"nm\":\"square a 3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":2,\"s\":[0]},{\"t\":217,\"s\":[-2520]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":2,\"s\":[160.5,-26.292,0],\"to\":[13,430.305,0],\"ti\":[52.221,-418.892,0]},{\"t\":217,\"s\":[238.5,833.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":2,\"s\":[100,50,100]},{\"t\":217,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":2,\"op\":218,\"st\":-13,\"bm\":0},{\"ddd\":0,\"ind\":20,\"ty\":4,\"nm\":\"square b 3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":4,\"s\":[0]},{\"t\":185,\"s\":[-2160]}],\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"t\":4,\"s\":[314.357,-26.292,0],\"to\":[157.333,415.667,0],\"ti\":[22.667,-253.667,0]},{\"t\":185,\"s\":[154.357,835.708,0]}],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"t\":4,\"s\":[100,50,100]},{\"t\":185,\"s\":[50,100,100]}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"a\":0,\"k\":[16,16],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":4},\"nm\":\"Rectangle Path 1\",\"mn\":\"ADBE Vector Shape - Rect\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9764705882352941,0.6196078431372549,0.027450980392156862,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"bm\":0,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":4,\"op\":186,\"st\":-11,\"bm\":0}]}],\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":0,\"nm\":\"cannon (small - left)\",\"refId\":\"comp_0\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[76,451.99999999999994,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,360,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":480,\"h\":720,\"ip\":0,\"op\":300,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":0,\"nm\":\"cannon (small - right)\",\"refId\":\"comp_2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[533,451.99999999999994,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[479.994,360,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":480,\"h\":720,\"ip\":0,\"op\":300,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":0,\"nm\":\"cannon (small - top)\",\"refId\":\"comp_3\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[304,408,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[400,400,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[102,102,100],\"ix\":6}},\"ao\":0,\"w\":800,\"h\":800,\"ip\":0,\"op\":300,\"st\":0,\"bm\":0}],\"markers\":[]}"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/core.tsx",
    "content": "import { closeCompletion } from \"@codemirror/autocomplete\"\nimport {\n  Compartment,\n  EditorState,\n  Extension,\n  StateEffect,\n} from \"@codemirror/state\"\nimport {\n  EditorView,\n  placeholder as placeholderExtension,\n} from \"@codemirror/view\"\nimport { FC, useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { useBasicSetup } from \"@/components/CodeEditor/CodeMirror/extensions\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { ILLACodeMirrorProps } from \"@/components/CodeEditor/CodeMirror/interface\"\nimport { applyEditorWrapperStyle } from \"@/components/CodeEditor/CodeMirror/style\"\nimport { ILLACodeMirrorTheme } from \"@/components/CodeEditor/CodeMirror/theme\"\nimport { HintToolTip } from \"@/components/CodeEditor/HintToolTip\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\n// thk ReactCodeMirror:https://github.com/uiwjs/react-codemirror\nexport const ILLACodeMirrorCore: FC<ILLACodeMirrorProps> = (props) => {\n  const {\n    className,\n    extensions = [],\n    value,\n    height = \"\",\n    maxHeight = \"\",\n    minHeight = \"\",\n    width = \"\",\n    maxWidth = \"\",\n    minWidth = \"\",\n    editable = true,\n    readOnly = false,\n    placeholder,\n    showLineNumbers = false,\n    lang = CODE_LANG.JAVASCRIPT,\n    codeType = CODE_TYPE.EXPRESSION,\n    expressions = [],\n    result = \"\",\n    hasError = false,\n    resultType = VALIDATION_TYPES.STRING,\n    canShowCompleteInfo = false,\n    sqlScheme = {},\n    singleLine,\n    onChange,\n    onBlur,\n    onFocus,\n    tooltipContainer,\n    scopeOfAutoComplete,\n  } = props\n\n  const [isFocus, setIsFocus] = useState(false)\n\n  const editorViewRef = useRef<EditorView>()\n  const editorWrapperRef = useRef<HTMLDivElement | null>(null)\n  const compartmentsRef = useRef<Compartment[]>([])\n\n  const extensionOptions = useMemo(() => {\n    return {\n      showLineNumbers,\n      lang,\n      codeType,\n      expressions,\n      canShowCompleteInfo,\n      sqlScheme,\n      scopeOfAutoComplete,\n    }\n  }, [\n    canShowCompleteInfo,\n    codeType,\n    expressions,\n    lang,\n    showLineNumbers,\n    sqlScheme,\n    scopeOfAutoComplete,\n  ])\n\n  const basicExtensions = useBasicSetup(extensionOptions)\n\n  const defaultThemeOption = useMemo(\n    () =>\n      EditorView.theme({\n        \"&\": {\n          height,\n          minHeight,\n          maxHeight,\n          width,\n          maxWidth,\n          minWidth,\n        },\n        ...ILLACodeMirrorTheme,\n      }),\n    [height, maxHeight, maxWidth, minHeight, minWidth, width],\n  )\n\n  const focusUpdateListener: Extension = useMemo(() => {\n    return EditorView.updateListener.of((viewUpdate) => {\n      if (viewUpdate.focusChanged) {\n        setIsFocus(viewUpdate.view.hasFocus)\n        const currentString = viewUpdate.state.doc.toString()\n\n        if (viewUpdate.view.hasFocus) {\n          onFocus?.()\n        } else {\n          onBlur?.(currentString)\n        }\n        if (!viewUpdate.view.hasFocus) {\n          setTimeout(() => {\n            closeCompletion(viewUpdate.view)\n          }, 500)\n        }\n      }\n    })\n  }, [onBlur, onFocus])\n\n  const changeUpdateListener: Extension = useMemo(() => {\n    return EditorView.updateListener.of((viewUpdate) => {\n      const currentString = viewUpdate.state.doc.toString()\n      if (viewUpdate.docChanged) {\n        onChange?.(currentString)\n      }\n    })\n  }, [onChange])\n\n  const readOnlyStateChangeEffect: Extension = useMemo(\n    () => EditorState.readOnly.of(readOnly),\n    [readOnly],\n  )\n\n  const editableStateChangeEffect: Extension = useMemo(\n    () => EditorView.editable.of(editable),\n    [editable],\n  )\n\n  const placeholderExt: Extension = useMemo(() => {\n    return typeof placeholder === \"string\"\n      ? placeholderExtension(placeholder)\n      : []\n  }, [placeholder])\n\n  const singleLineExt: Extension = useMemo(() => {\n    return singleLine\n      ? EditorState.transactionFilter.of((tr) => {\n          return tr.newDoc.lines > 1 ? [] : [tr]\n        })\n      : EditorView.lineWrapping\n  }, [singleLine])\n\n  const allExtensions = useMemo(() => {\n    return [\n      basicExtensions,\n      defaultThemeOption,\n      focusUpdateListener,\n      changeUpdateListener,\n      readOnlyStateChangeEffect,\n      editableStateChangeEffect,\n      placeholderExt,\n      singleLineExt,\n      extensions,\n    ]\n  }, [\n    basicExtensions,\n    defaultThemeOption,\n    focusUpdateListener,\n    changeUpdateListener,\n    readOnlyStateChangeEffect,\n    editableStateChangeEffect,\n    placeholderExt,\n    singleLineExt,\n    extensions,\n  ])\n\n  const extensionsWithCompartment = useMemo(() => {\n    for (\n      let i = compartmentsRef.current.length;\n      i < allExtensions.length;\n      i++\n    ) {\n      const compartment = new Compartment()\n      compartmentsRef.current.push(compartment)\n    }\n    return allExtensions.map((ext, index) =>\n      compartmentsRef.current[index].of(ext),\n    )\n  }, [allExtensions])\n\n  useEffect(() => {\n    if (\n      !editorViewRef.current ||\n      (!isFocus && value !== editorViewRef.current.state.doc.toString())\n    ) {\n      const state = EditorState.create({\n        doc: value,\n        extensions: extensionsWithCompartment,\n      })\n      if (editorViewRef.current) {\n        editorViewRef.current.setState(state)\n      } else {\n        if (editorWrapperRef.current) {\n          editorViewRef.current = new EditorView({\n            state,\n            parent: editorWrapperRef.current,\n          })\n        }\n      }\n    }\n  }, [value, extensionsWithCompartment, isFocus])\n\n  const reconfigure = useCallback(\n    (view?: EditorView) => {\n      if (view) {\n        const effects: StateEffect<unknown>[] = []\n        allExtensions.forEach((e, i) => {\n          if (compartmentsRef.current[i].get(view.state) !== e) {\n            effects.push(compartmentsRef.current[i].reconfigure(e))\n          }\n        })\n        if (effects.length > 0) {\n          view.dispatch({ effects })\n        }\n      }\n    },\n    [allExtensions],\n  )\n\n  useEffect(() => {\n    if (editorViewRef.current) {\n      reconfigure(editorViewRef.current)\n    }\n  }, [reconfigure])\n\n  return (\n    <HintToolTip\n      isEditorFocused={isFocus}\n      result={!result ? '\"\"' : result}\n      hasError={hasError}\n      resultType={resultType}\n      toolTipContainer={tooltipContainer}\n    >\n      <div\n        ref={editorWrapperRef}\n        className={className}\n        css={applyEditorWrapperStyle(hasError, isFocus, editable, readOnly)}\n      />\n    </HintToolTip>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/extensions/completionSources/ILLAContextDesc/index.tsx",
    "content": "import { ILLA_UTILS_DESC } from \"./utils\"\n\nexport const ILLAContextDesc: Record<string, any> = {\n  utils: ILLA_UTILS_DESC,\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/extensions/completionSources/ILLAContextDesc/utils.tsx",
    "content": "interface IILLAUtilsDesc {\n  desc?: string\n  usage: string\n}\n\nexport const ILLA_UTILS_DESC: Record<string, IILLAUtilsDesc> = {\n  goToURL: {\n    desc: \"\",\n    usage: \"utils.goToURL({url:string,newTab?:boolean = false})\",\n  },\n  showNotification: {\n    desc: \"\",\n    usage: `utils.showNotification({type:\"info\" | \"error\" | \"success\" | \"warning\" | \"normal\" = \"info\",title?:string,description?:string,duration?:number = 4500})`,\n  },\n  copyToClipboard: {\n    desc: \"\",\n    usage: `utils.copyToClipboard(copiedValue:any)`,\n  },\n  setRouter: {\n    desc: \"\",\n    usage: \"utils.setRouter({pagePath:string;viewPath?:string})\",\n  },\n  downloadFile: {\n    desc: \"\",\n    usage: `utils.downloadFile({fileType?:string = \"auto\";fileName?:string = \"Untitled File\",data:any})`,\n  },\n  downloadFromILLADrive: {\n    desc: \"\",\n    usage: `utils.downloadFromILLADrive({downloadInfo:{tinyURL:string,fileID:string}[],asZip?:boolean})`,\n  },\n  saveToILLADrive: {\n    desc: \"\",\n    usage: `utils.saveToILLADrive({fileName:string,fileData:string,fileType?:string=\"auto\",folder?:string=\"\",allowAnonymous?:boolean = false,replace?:boolean = false})`,\n  },\n  setGlobalDataIn: {\n    desc: \"\",\n    usage: `utils.setGlobalDataIn({key:string,path:string,value:any})`,\n  },\n  setGlobalDataValue: {\n    desc: \"\",\n    usage: `utils.setGlobalDataValue({key:string,value:any})`,\n  },\n  setLocalStorage: {\n    desc: \"\",\n    usage: `utils.setLocalStorage({key:string,value:any})`,\n  },\n  clearLocalStorage: {\n    desc: \"\",\n    usage: `utils.clearLocalStorage()`,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/extensions/completionSources/TernServer/defs/ecmascript.json",
    "content": "{\n  \"!name\": \"ecmascript\",\n  \"!define\": {\n    \"Error.prototype\": \"Error.prototype\",\n    \"propertyDescriptor\": {\n      \"enumerable\": \"bool\",\n      \"configurable\": \"bool\",\n      \"value\": \"?\",\n      \"writable\": \"bool\",\n      \"get\": \"fn() -> ?\",\n      \"set\": \"fn(value: ?)\"\n    },\n    \"Promise.prototype\": {\n      \"catch\": {\n        \"!doc\": \"The catch() method returns a Promise and deals with rejected cases only. It behaves the same as calling Promise.prototype.then(undefined, onRejected).\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch\",\n        \"!type\": \"fn(onRejected: fn(reason: ?)) -> !this\"\n      },\n      \"then\": {\n        \"!doc\": \"The then() method returns a Promise. It takes two arguments, both are callback functions for the success and failure cases of the Promise.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then\",\n        \"!type\": \"fn(onFulfilled: fn(value: ?), onRejected: fn(reason: ?)) -> !custom:Promise_then\",\n        \"!effects\": [\"call !0 !this.:t\"]\n      }\n    },\n    \"Promise_reject\": {\n      \"!type\": \"fn(reason: ?) -> !this\",\n      \"!doc\": \"The Promise.reject(reason) method returns a Promise object that is rejected with the given reason.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject\"\n    },\n    \"iter_prototype\": {\n      \":Symbol.iterator\": \"fn() -> !this\"\n    },\n    \"iter\": {\n      \"!proto\": \"iter_prototype\",\n      \"next\": {\n        \"!type\": \"fn() -> +iter_result[value=!this.:t]\",\n        \"!doc\": \"Return the next item in the sequence.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators\"\n      },\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators\"\n    },\n    \"iter_result\": {\n      \"done\": \"bool\",\n      \"value\": \"?\"\n    },\n    \"generator_prototype\": {\n      \"!proto\": \"iter_prototype\",\n      \"next\": \"fn(value?: ?) -> iter_result\",\n      \"return\": \"fn(value?: ?) -> iter_result\",\n      \"throw\": \"fn(exception: +Error)\"\n    },\n    \"Proxy_handler\": {\n      \"!doc\": \"The proxy's handler object is a placeholder object which contains traps for proxies.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler\",\n      \"getPrototypeOf\": \"fn(target: ?)\",\n      \"setPrototypeOf\": \"fn(target: ?, prototype: ?)\",\n      \"isExtensible\": \"fn(target: ?)\",\n      \"preventExtensions\": \"fn(target: ?)\",\n      \"getOwnPropertyDescriptor\": \"fn(target: ?, property: string) -> propertyDescriptor\",\n      \"defineProperty\": \"fn(target: ?, property: string, descriptor: propertyDescriptor)\",\n      \"has\": \"fn(target: ?, property: string)\",\n      \"get\": \"fn(target: ?, property: string)\",\n      \"set\": \"fn(target: ?, property: string, value: ?)\",\n      \"deleteProperty\": \"fn(target: ?, property: string)\",\n      \"enumerate\": \"fn(target: ?)\",\n      \"ownKeys\": \"fn(target: ?)\",\n      \"apply\": \"fn(target: ?, self: ?, arguments: [?])\",\n      \"construct\": \"fn(target: ?, arguments: [?])\"\n    },\n    \"Proxy_revocable\": {\n      \"proxy\": \"+Proxy\",\n      \"revoke\": \"fn()\"\n    },\n    \"TypedArray\": {\n      \"!type\": \"fn(size: number)\",\n      \"!doc\": \"A TypedArray object describes an array-like view of an underlying binary data buffer. There is no global property named TypedArray, nor is there a directly visible TypedArray constructor.  Instead, there are a number of different global properties, whose values are typed array constructors for specific element types, listed below. On the following pages you will find common properties and methods that can be used with any typed array containing elements of any type.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray\",\n      \"from\": {\n        \"!type\": \"fn(arrayLike: ?, mapFn?: fn(elt: ?, i: number) -> number, thisArg?: ?) -> +TypedArray\",\n        \"!effects\": [\"call !1 this=!2 !0.<i> number\"],\n        \"!doc\": \"Creates a new typed array from an array-like or iterable object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from\"\n      },\n      \"of\": {\n        \"!type\": \"fn(elements: number) -> +TypedArray\",\n        \"!doc\": \"Creates a new typed array from a variable number of arguments.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/of\"\n      },\n      \"BYTES_PER_ELEMENT\": {\n        \"!type\": \"number\",\n        \"!doc\": \"The TypedArray.BYTES_PER_ELEMENT property represents the size in bytes of each element in an typed array.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT\"\n      },\n      \"name\": {\n        \"!type\": \"string\",\n        \"!doc\": \"The TypedArray.name property represents a string value of the typed array constructor name.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/name\"\n      },\n      \"prototype\": {\n        \"<i>\": \"number\",\n        \"buffer\": {\n          \"!type\": \"+ArrayBuffer\",\n          \"!doc\": \"The buffer accessor property represents the ArrayBuffer referenced by a TypedArray at construction time.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/buffer\"\n        },\n        \"byteLength\": {\n          \"!type\": \"number\",\n          \"!doc\": \"The byteLength accessor property represents the length (in bytes) of a typed array from the start of its ArrayBuffer.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/byteLength\"\n        },\n        \"byteOffset\": {\n          \"!type\": \"number\",\n          \"!doc\": \"The byteOffset accessor property represents the offset (in bytes) of a typed array from the start of its ArrayBuffer.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/byteOffset\"\n        },\n        \"copyWithin\": {\n          \"!type\": \"fn(target: number, start: number, end?: number) -> ?\",\n          \"!doc\": \"The copyWithin() method copies the sequence of array elements within the array to the position starting at target. The copy is taken from the index positions of the second and third arguments start and end. The end argument is optional and defaults to the length of the array. This method has the same algorithm as Array.prototype.copyWithin. TypedArray is one of the typed array types here.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/copyWithin\"\n        },\n        \"entries\": {\n          \"!type\": \"fn() -> +iter[:t=number]\",\n          \"!doc\": \"The entries() method returns a new Array Iterator object that contains the key/value pairs for each index in the array.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/entries\"\n        },\n        \"every\": {\n          \"!type\": \"fn(callback: fn(element: number, index: number, array: TypedArray) -> bool, thisArg?: ?) -> bool\",\n          \"!effects\": [\"call !0 this=!1 number number !this\"],\n          \"!doc\": \"The every() method tests whether all elements in the typed array pass the test implemented by the provided function. This method has the same algorithm as Array.prototype.every(). TypedArray is one of the typed array types here.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/every\"\n        },\n        \"fill\": {\n          \"!type\": \"fn(value: number, start?: number, end?: number)\",\n          \"!doc\": \"The fill() method fills all the elements of a typed array from a start index to an end index with a static value. This method has the same algorithm as Array.prototype.fill(). TypedArray is one of the typed array types here.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/fill\"\n        },\n        \"filter\": {\n          \"!type\": \"fn(test: fn(element: number, i: number) -> bool, context?: ?) -> !this\",\n          \"!effects\": [\"call !0 this=!1 number number\"],\n          \"!doc\": \"Creates a new array with all of the elements of this array for which the provided filtering function returns true. See also Array.prototype.filter().\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/filter\"\n        },\n        \"find\": {\n          \"!type\": \"fn(callback: fn(element: number, index: number, array: +TypedArray) -> bool, thisArg?: ?) -> number\",\n          \"!effects\": [\"call !0 this=!1 number number !this\"],\n          \"!doc\": \"The find() method returns a value in the typed array, if an element satisfies the provided testing function. Otherwise undefined is returned. TypedArray is one of the typed array types here.\\nSee also the findIndex() method, which returns the index of a found element in the typed array instead of its value.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/find\"\n        },\n        \"findIndex\": {\n          \"!type\": \"fn(callback: fn(element: number, index: number, array: +TypedArray) -> bool, thisArg?: ?) -> number\",\n          \"!effects\": [\"call !0 this=!1 number number !this\"],\n          \"!doc\": \"The findIndex() method returns an index in the typed array, if an element in the typed array satisfies the provided testing function. Otherwise -1 is returned.\\nSee also the find() method, which returns the value of a found element in the typed array instead of its index.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/findIndex\"\n        },\n        \"forEach\": {\n          \"!type\": \"fn(callback: fn(value: number, key: number, array: +TypedArray), thisArg?: ?)\",\n          \"!effects\": [\"call !0 this=!1 number number !this\"],\n          \"!doc\": \"Executes a provided function once per array element.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/forEach\"\n        },\n        \"indexOf\": {\n          \"!type\": \"fn(searchElement: number, fromIndex?: number) -> number\",\n          \"!doc\": \"The indexOf() method returns the first index at which a given element can be found in the typed array, or -1 if it is not present. This method has the same algorithm as Array.prototype.indexOf(). TypedArray is one of the typed array types here.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/indexOf\"\n        },\n        \"join\": {\n          \"!type\": \"fn(separator?: string) -> string\",\n          \"!doc\": \"The join() method joins all elements of an array into a string. This method has the same algorithm as Array.prototype.join(). TypedArray is one of the typed array types here.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/join\"\n        },\n        \"keys\": {\n          \"!type\": \"fn() -> +iter[:t=number]\",\n          \"!doc\": \"The keys() method returns a new Array Iterator object that contains the keys for each index in the array.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/keys\"\n        },\n        \"lastIndexOf\": {\n          \"!type\": \"fn(searchElement: number, fromIndex?: number) -> number\",\n          \"!doc\": \"The lastIndexOf() method returns the last index at which a given element can be found in the typed array, or -1 if it is not present. The typed array is searched backwards, starting at fromIndex. This method has the same algorithm as Array.prototype.lastIndexOf(). TypedArray is one of the typed array types here.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/lastIndexOf\"\n        },\n        \"length\": {\n          \"!type\": \"number\",\n          \"!doc\": \"Returns the number of elements hold in the typed array. Fixed at construction time and thus read only.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/length\"\n        },\n        \"map\": {\n          \"!type\": \"fn(f: fn(element: number, i: number) -> number, context?: ?) -> +TypedArray\",\n          \"!effects\": [\"call !0 this=!1 number number\"],\n          \"!doc\": \"Creates a new array with the results of calling a provided function on every element in this array. See also Array.prototype.map().\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/map\"\n        },\n        \"reduce\": {\n          \"!type\": \"fn(combine: fn(sum: ?, elt: number, i: number) -> ?, init?: ?) -> !0.!ret\",\n          \"!effects\": [\"call !0 !1 number number\"],\n          \"!doc\": \"Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. See also Array.prototype.reduce().\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reduce\"\n        },\n        \"reduceRight\": {\n          \"!type\": \"fn(combine: fn(sum: ?, elt: number, i: number) -> ?, init?: ?) -> !0.!ret\",\n          \"!effects\": [\"call !0 !1 number number\"],\n          \"!doc\": \"Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value. See also Array.prototype.reduceRight().\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reduceRight\"\n        },\n        \"reverse\": {\n          \"!type\": \"fn()\",\n          \"!doc\": \"The reverse() method reverses a typed array in place. The first typed array element becomes the last and the last becomes the first. This method has the same algorithm as Array.prototype.reverse(). TypedArray is one of the typed array types here.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reverse\"\n        },\n        \"set\": {\n          \"!type\": \"fn(array: [number], offset?: number)\",\n          \"!doc\": \"The set() method stores multiple values in the typed array, reading input values from a specified array.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set\"\n        },\n        \"slice\": {\n          \"!type\": \"fn(from: number, to?: number) -> +TypedArray\",\n          \"!doc\": \"Extracts a section of an array and returns a new array. See also Array.prototype.slice().\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice\"\n        },\n        \"some\": {\n          \"!type\": \"fn(test: fn(elt: number, i: number) -> bool, context?: ?) -> bool\",\n          \"!effects\": [\"call !0 this=!1 number number\"],\n          \"!doc\": \"The some() method tests whether some element in the typed array passes the test implemented by the provided function. This method has the same algorithm as Array.prototype.some(). TypedArray is one of the typed array types here.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/some\"\n        },\n        \"sort\": {\n          \"!type\": \"fn(compare?: fn(a: number, b: number) -> number)\",\n          \"!effects\": [\"call !0 number number\"],\n          \"!doc\": \"Sorts the elements of an array in place and returns the array. See also Array.prototype.sort().\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/sort\"\n        },\n        \"subarray\": {\n          \"!type\": \"fn(begin?: number, end?: number) -> +TypedArray\",\n          \"!doc\": \"The subarray() method returns a new TypedArray on the same ArrayBuffer store and with the same element types as for this TypedArray object. The begin offset is inclusive and the end offset is exclusive. TypedArray is one of the typed array types.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray\"\n        },\n        \"values\": {\n          \"!type\": \"fn() -> +iter[:t=number]\",\n          \"!doc\": \"The values() method returns a new Array Iterator object that contains the values for each index in the array.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/values\"\n        },\n        \":Symbol.iterator\": {\n          \"!type\": \"fn() -> +iter[:t=number]\",\n          \"!doc\": \"Returns a new Array Iterator object that contains the values for each index in the array.\",\n          \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/@@iterator\"\n        }\n      }\n    }\n  },\n  \"Infinity\": {\n    \"!type\": \"number\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Infinity\",\n    \"!doc\": \"A numeric value representing infinity.\"\n  },\n  \"undefined\": {\n    \"!type\": \"?\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/undefined\",\n    \"!doc\": \"The value undefined.\"\n  },\n  \"NaN\": {\n    \"!type\": \"number\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/NaN\",\n    \"!doc\": \"A value representing Not-A-Number.\"\n  },\n  \"Object\": {\n    \"!type\": \"fn()\",\n    \"getPrototypeOf\": {\n      \"!type\": \"fn(obj: ?) -> ?\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getPrototypeOf\",\n      \"!doc\": \"Returns the prototype (i.e. the internal prototype) of the specified object.\"\n    },\n    \"create\": {\n      \"!type\": \"fn(proto: ?) -> !custom:Object_create\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create\",\n      \"!doc\": \"Creates a new object with the specified prototype object and properties.\"\n    },\n    \"defineProperty\": {\n      \"!type\": \"fn(obj: ?, prop: string, desc: propertyDescriptor) -> !custom:Object_defineProperty\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty\",\n      \"!doc\": \"Defines a new property directly on an object, or modifies an existing property on an object, and returns the object. If you want to see how to use the Object.defineProperty method with a binary-flags-like syntax, see this article.\"\n    },\n    \"defineProperties\": {\n      \"!type\": \"fn(obj: ?, props: ?) -> !custom:Object_defineProperties\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty\",\n      \"!doc\": \"Defines a new property directly on an object, or modifies an existing property on an object, and returns the object. If you want to see how to use the Object.defineProperty method with a binary-flags-like syntax, see this article.\"\n    },\n    \"getOwnPropertyDescriptor\": {\n      \"!type\": \"fn(obj: ?, prop: string) -> propertyDescriptor\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor\",\n      \"!doc\": \"Returns a property descriptor for an own property (that is, one directly present on an object, not present by dint of being along an object's prototype chain) of a given object.\"\n    },\n    \"keys\": {\n      \"!type\": \"fn(obj: ?) -> [string]\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys\",\n      \"!doc\": \"Returns an array of a given object's own enumerable properties, in the same order as that provided by a for-in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).\"\n    },\n    \"getOwnPropertyNames\": {\n      \"!type\": \"fn(obj: ?) -> [string]\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames\",\n      \"!doc\": \"Returns an array of all properties (enumerable or not) found directly upon a given object.\"\n    },\n    \"seal\": {\n      \"!type\": \"fn(obj: ?)\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/seal\",\n      \"!doc\": \"Seals an object, preventing new properties from being added to it and marking all existing properties as non-configurable. Values of present properties can still be changed as long as they are writable.\"\n    },\n    \"isSealed\": {\n      \"!type\": \"fn(obj: ?) -> bool\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/isSealed\",\n      \"!doc\": \"Determine if an object is sealed.\"\n    },\n    \"freeze\": {\n      \"!type\": \"fn(obj: ?) -> !0\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/freeze\",\n      \"!doc\": \"Freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed. In essence the object is made effectively immutable. The method returns the object being frozen.\"\n    },\n    \"isFrozen\": {\n      \"!type\": \"fn(obj: ?) -> bool\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/isFrozen\",\n      \"!doc\": \"Determine if an object is frozen.\"\n    },\n    \"preventExtensions\": {\n      \"!type\": \"fn(obj: ?)\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions\",\n      \"!doc\": \"Prevents new properties from ever being added to an object.\"\n    },\n    \"isExtensible\": {\n      \"!type\": \"fn(obj: ?) -> bool\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\",\n      \"!doc\": \"The Object.isExtensible() method determines if an object is extensible (whether it can have new properties added to it).\"\n    },\n    \"assign\": {\n      \"!type\": \"fn(target: ?, source: ?, source?: ?) -> !0\",\n      \"!effects\": [\"copy !1 !0\", \"copy !2 !0\", \"copy !3 !0\"],\n      \"!doc\": \"The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\"\n    },\n    \"getOwnPropertySymbols\": {\n      \"!type\": \"fn(obj: ?) -> !custom:getOwnPropertySymbols\",\n      \"!doc\": \"The Object.getOwnPropertySymbols() method returns an array of all symbol properties found directly upon a given object.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols\"\n    },\n    \"is\": {\n      \"!type\": \"fn(value1: ?, value2: ?) -> bool\",\n      \"!doc\": \"The Object.is() method determines whether two values are the same value.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\"\n    },\n    \"setPrototypeOf\": {\n      \"!type\": \"fn(obj: ?, prototype: ?)\",\n      \"!doc\": \"The Object.setPrototype() method sets the prototype (i.e., the internal [[Prototype]] property) of a specified object to another object or null.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf\"\n    },\n    \"prototype\": {\n      \"!stdProto\": \"Object\",\n      \"toString\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/toString\",\n        \"!doc\": \"Returns a string representing the object.\"\n      },\n      \"toLocaleString\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/toLocaleString\",\n        \"!doc\": \"Returns a string representing the object. This method is meant to be overriden by derived objects for locale-specific purposes.\"\n      },\n      \"valueOf\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/valueOf\",\n        \"!doc\": \"Returns the primitive value of the specified object\"\n      },\n      \"hasOwnProperty\": {\n        \"!type\": \"fn(prop: string) -> bool\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty\",\n        \"!doc\": \"Returns a boolean indicating whether the object has the specified property.\"\n      },\n      \"propertyIsEnumerable\": {\n        \"!type\": \"fn(prop: string) -> bool\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable\",\n        \"!doc\": \"Returns a Boolean indicating whether the specified property is enumerable.\"\n      },\n      \"isPrototypeOf\": {\n        \"!type\": \"fn(obj: ?) -> bool\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf\",\n        \"!doc\": \"Tests for an object in another object's prototype chain.\"\n      }\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object\",\n    \"!doc\": \"Creates an object wrapper.\"\n  },\n  \"Function\": {\n    \"!type\": \"fn(body: string) -> fn()\",\n    \"prototype\": {\n      \"!stdProto\": \"Function\",\n      \"apply\": {\n        \"!type\": \"fn(this: ?, args: [?])\",\n        \"!effects\": [\"call and return !this this=!0 !1.<i> !1.<i> !1.<i>\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply\",\n        \"!doc\": \"Calls a function with a given this value and arguments provided as an array (or an array like object).\"\n      },\n      \"call\": {\n        \"!type\": \"fn(this: ?, args?: ?) -> !this.!ret\",\n        \"!effects\": [\"call and return !this this=!0 !1 !2 !3 !4\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/call\",\n        \"!doc\": \"Calls a function with a given this value and arguments provided individually.\"\n      },\n      \"bind\": {\n        \"!type\": \"fn(this: ?, args?: ?) -> !custom:Function_bind\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind\",\n        \"!doc\": \"Creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function was called.\"\n      },\n      \"prototype\": \"?\"\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function\",\n    \"!doc\": \"Every function in JavaScript is actually a Function object.\"\n  },\n  \"Array\": {\n    \"!type\": \"fn(size: number) -> !custom:Array_ctor\",\n    \"isArray\": {\n      \"!type\": \"fn(value: ?) -> bool\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray\",\n      \"!doc\": \"Returns true if an object is an array, false if it is not.\"\n    },\n    \"from\": {\n      \"!type\": \"fn(arrayLike: ?, mapFn?: fn(elt: ?, i: number) -> ?, thisArg?: ?) -> [!0.<i>]\",\n      \"!effects\": [\"call !1 this=!2 !0.<i> number\"],\n      \"!doc\": \"The Array.from() method creates a new Array instance from an array-like or iterable object.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from\"\n    },\n    \"of\": {\n      \"!type\": \"fn(elementN: ?) -> [!0]\",\n      \"!doc\": \"The Array.of() method creates a new Array instance with a variable number of arguments, regardless of number or type of the arguments.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of\"\n    },\n    \"prototype\": {\n      \"!stdProto\": \"Array\",\n      \"length\": {\n        \"!type\": \"number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/length\",\n        \"!doc\": \"An unsigned, 32-bit integer that specifies the number of elements in an array.\"\n      },\n      \"concat\": {\n        \"!type\": \"fn(other: [?]) -> !this\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/concat\",\n        \"!doc\": \"Returns a new array comprised of this array joined with other array(s) and/or value(s).\"\n      },\n      \"join\": {\n        \"!type\": \"fn(separator?: string) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/join\",\n        \"!doc\": \"Joins all elements of an array into a string.\"\n      },\n      \"splice\": {\n        \"!type\": \"fn(pos: number, amount: number, newelt?: ?) -> [?]\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/splice\",\n        \"!doc\": \"Changes the content of an array, adding new elements while removing old elements.\"\n      },\n      \"pop\": {\n        \"!type\": \"fn() -> !this.<i>\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/pop\",\n        \"!doc\": \"Removes the last element from an array and returns that element.\"\n      },\n      \"push\": {\n        \"!type\": \"fn(newelt: ?) -> number\",\n        \"!effects\": [\"propagate !0 !this.<i>\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/push\",\n        \"!doc\": \"Mutates an array by appending the given elements and returning the new length of the array.\"\n      },\n      \"shift\": {\n        \"!type\": \"fn() -> !this.<i>\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/shift\",\n        \"!doc\": \"Removes the first element from an array and returns that element. This method changes the length of the array.\"\n      },\n      \"unshift\": {\n        \"!type\": \"fn(newelt: ?) -> number\",\n        \"!effects\": [\"propagate !0 !this.<i>\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/unshift\",\n        \"!doc\": \"Adds one or more elements to the beginning of an array and returns the new length of the array.\"\n      },\n      \"slice\": {\n        \"!type\": \"fn(from?: number, to?: number) -> !this\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/slice\",\n        \"!doc\": \"Returns a shallow copy of a portion of an array.\"\n      },\n      \"reverse\": {\n        \"!type\": \"fn()\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/reverse\",\n        \"!doc\": \"Reverses an array in place.  The first array element becomes the last and the last becomes the first.\"\n      },\n      \"sort\": {\n        \"!type\": \"fn(compare?: fn(a: ?, b: ?) -> number)\",\n        \"!effects\": [\"call !0 !this.<i> !this.<i>\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort\",\n        \"!doc\": \"Sorts the elements of an array in place and returns the array.\"\n      },\n      \"indexOf\": {\n        \"!type\": \"fn(elt: ?, from?: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf\",\n        \"!doc\": \"Returns the first index at which a given element can be found in the array, or -1 if it is not present.\"\n      },\n      \"lastIndexOf\": {\n        \"!type\": \"fn(elt: ?, from?: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/lastIndexOf\",\n        \"!doc\": \"Returns the last index at which a given element can be found in the array, or -1 if it is not present. The array is searched backwards, starting at fromIndex.\"\n      },\n      \"every\": {\n        \"!type\": \"fn(test: fn(elt: ?, i: number, array: +Array) -> bool, context?: ?) -> bool\",\n        \"!effects\": [\"call !0 this=!1 !this.<i> number !this\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/every\",\n        \"!doc\": \"Tests whether all elements in the array pass the test implemented by the provided function.\"\n      },\n      \"some\": {\n        \"!type\": \"fn(test: fn(elt: ?, i: number, array: +Array) -> bool, context?: ?) -> bool\",\n        \"!effects\": [\"call !0 this=!1 !this.<i> number !this\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/some\",\n        \"!doc\": \"Tests whether some element in the array passes the test implemented by the provided function.\"\n      },\n      \"filter\": {\n        \"!type\": \"fn(test: fn(elt: ?, i: number, array: +Array) -> bool, context?: ?) -> !this\",\n        \"!effects\": [\"call !0 this=!1 !this.<i> number !this\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter\",\n        \"!doc\": \"Creates a new array with all elements that pass the test implemented by the provided function.\"\n      },\n      \"forEach\": {\n        \"!type\": \"fn(f: fn(elt: ?, i: number, array: +Array), context?: ?)\",\n        \"!effects\": [\"call !0 this=!1 !this.<i> number !this\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach\",\n        \"!doc\": \"Executes a provided function once per array element.\"\n      },\n      \"map\": {\n        \"!type\": \"fn(f: fn(elt: ?, i: number, array: +Array) -> ?, context?: ?) -> [!0.!ret]\",\n        \"!effects\": [\"call !0 this=!1 !this.<i> number !this\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map\",\n        \"!doc\": \"Creates a new array with the results of calling a provided function on every element in this array.\"\n      },\n      \"reduce\": {\n        \"!type\": \"fn(combine: fn(sum: ?, elt: ?, i: number, array: +Array) -> ?, init?: ?) -> !0.!ret\",\n        \"!effects\": [\"call !0 !1 !this.<i> number !this\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/Reduce\",\n        \"!doc\": \"Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value.\"\n      },\n      \"reduceRight\": {\n        \"!type\": \"fn(combine: fn(sum: ?, elt: ?, i: number, array: +Array) -> ?, init?: ?) -> !0.!ret\",\n        \"!effects\": [\"call !0 !1 !this.<i> number !this\"],\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/ReduceRight\",\n        \"!doc\": \"Apply a function simultaneously against two values of the array (from right-to-left) as to reduce it to a single value.\"\n      },\n      \"copyWithin\": {\n        \"!type\": \"fn(target: number, start: number, end?: number) -> !this\",\n        \"!doc\": \"The copyWithin() method copies the sequence of array elements within the array to the position starting at target. The copy is taken from the index positions of the second and third arguments start and end.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\"\n      },\n      \"entries\": {\n        \"!type\": \"fn() -> +iter[:t=[number, !this.<i>]]\",\n        \"!doc\": \"The entries() method returns a new Array Iterator object that contains the key/value pairs for each index in the array.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries\"\n      },\n      \"fill\": {\n        \"!type\": \"fn(value: ?, start?: number, end?: number) -> !this\",\n        \"!doc\": \"The fill() method fills all the elements of an array from a start index to an end index with a static value.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill\"\n      },\n      \"find\": {\n        \"!type\": \"fn(callback: fn(element: ?, index: number, array: [?]) -> bool, thisArg?: ?) -> !this.<i>\",\n        \"!effects\": [\"call !0 this=!2 !this.<i> number\"],\n        \"!doc\": \"The find() method returns a value in the array, if an element in the array satisfies the provided testing function. Otherwise undefined is returned.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find\"\n      },\n      \"findIndex\": {\n        \"!type\": \"fn(callback: fn(element: ?, index: number, array: [?]), thisArg?: ?) -> number\",\n        \"!effects\": [\"call !0 this=!2 !this.<i> number\"],\n        \"!doc\": \"The findIndex() method returns an index in the array, if an element in the array satisfies the provided testing function. Otherwise -1 is returned.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex\"\n      },\n      \"keys\": {\n        \"!type\": \"fn() -> +iter[:t=number]\",\n        \"!doc\": \"The keys() method returns a new Array Iterator that contains the keys for each index in the array.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/keys\"\n      },\n      \"values\": {\n        \"!type\": \"fn() -> +iter[:t=!this.<i>]\",\n        \"!doc\": \"The values() method returns a new Array Iterator object that contains the values for each index in the array.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values\"\n      },\n      \":Symbol.iterator\": {\n        \"!type\": \"fn() -> +iter[:t=!this.<i>]\",\n        \"!doc\": \"Returns a new Array Iterator object that contains the values for each index in the array.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@iterator\"\n      },\n      \"includes\": {\n        \"!type\": \"fn(value: ?) -> bool\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes\",\n        \"!doc\": \"Determines whether an array includes a certain element, returning true or false as appropriate.\"\n      }\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array\",\n    \"!doc\": \"The JavaScript Array global object is a constructor for arrays, which are high-level, list-like objects.\"\n  },\n  \"String\": {\n    \"!type\": \"fn(value: ?) -> string\",\n    \"fromCharCode\": {\n      \"!type\": \"fn(code: number) -> string\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/fromCharCode\",\n      \"!doc\": \"Returns a string created by using the specified sequence of Unicode values.\"\n    },\n    \"fromCodePoint\": {\n      \"!type\": \"fn(point: number, point?: number) -> string\",\n      \"!doc\": \"The static String.fromCodePoint() method returns a string created by using the specified sequence of code points.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint\"\n    },\n    \"raw\": {\n      \"!type\": \"fn(template: [string], substitutions: ?, templateString: ?) -> string\",\n      \"!doc\": \"The static String.raw() method is a tag function of template strings, used to get the raw string form of template strings.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw\"\n    },\n    \"prototype\": {\n      \"!stdProto\": \"String\",\n      \"length\": {\n        \"!type\": \"number\",\n        \"!url\": \"https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/String/length\",\n        \"!doc\": \"Represents the length of a string.\"\n      },\n      \"<i>\": \"string\",\n      \"charAt\": {\n        \"!type\": \"fn(i: number) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/charAt\",\n        \"!doc\": \"Returns the specified character from a string.\"\n      },\n      \"charCodeAt\": {\n        \"!type\": \"fn(i: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/charCodeAt\",\n        \"!doc\": \"Returns the numeric Unicode value of the character at the given index (except for unicode codepoints > 0x10000).\"\n      },\n      \"indexOf\": {\n        \"!type\": \"fn(char: string, from?: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/indexOf\",\n        \"!doc\": \"Returns the index within the calling String object of the first occurrence of the specified value, starting the search at fromIndex,\\nreturns -1 if the value is not found.\"\n      },\n      \"lastIndexOf\": {\n        \"!type\": \"fn(char: string, from?: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/lastIndexOf\",\n        \"!doc\": \"Returns the index within the calling String object of the last occurrence of the specified value, or -1 if not found. The calling string is searched backward, starting at fromIndex.\"\n      },\n      \"substring\": {\n        \"!type\": \"fn(from: number, to?: number) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/substring\",\n        \"!doc\": \"Returns a subset of a string between one index and another, or through the end of the string.\"\n      },\n      \"substr\": {\n        \"!type\": \"fn(from: number, length?: number) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/substr\",\n        \"!doc\": \"Returns the characters in a string beginning at the specified location through the specified number of characters.\"\n      },\n      \"slice\": {\n        \"!type\": \"fn(from: number, to?: number) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/slice\",\n        \"!doc\": \"Extracts a section of a string and returns a new string.\"\n      },\n      \"trim\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/Trim\",\n        \"!doc\": \"Removes whitespace from both ends of the string.\"\n      },\n      \"toUpperCase\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toUpperCase\",\n        \"!doc\": \"Returns the calling string value converted to uppercase.\"\n      },\n      \"toLowerCase\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLowerCase\",\n        \"!doc\": \"Returns the calling string value converted to lowercase.\"\n      },\n      \"toLocaleUpperCase\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase\",\n        \"!doc\": \"Returns the calling string value converted to upper case, according to any locale-specific case mappings.\"\n      },\n      \"toLocaleLowerCase\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase\",\n        \"!doc\": \"Returns the calling string value converted to lower case, according to any locale-specific case mappings.\"\n      },\n      \"split\": {\n        \"!type\": \"fn(pattern?: string|+RegExp, limit?: number) -> [string]\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/split\",\n        \"!doc\": \"Splits a String object into an array of strings by separating the string into substrings.\"\n      },\n      \"concat\": {\n        \"!type\": \"fn(other: string) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/concat\",\n        \"!doc\": \"Combines the text of two or more strings and returns a new string.\"\n      },\n      \"localeCompare\": {\n        \"!type\": \"fn(other: string) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/localeCompare\",\n        \"!doc\": \"Returns a number indicating whether a reference string comes before or after or is the same as the given string in sort order.\"\n      },\n      \"match\": {\n        \"!type\": \"fn(pattern: +RegExp) -> [string]\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/match\",\n        \"!doc\": \"Used to retrieve the matches when matching a string against a regular expression.\"\n      },\n      \"replace\": {\n        \"!type\": \"fn(pattern: string|+RegExp, replacement: string) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace\",\n        \"!doc\": \"Returns a new string with some or all matches of a pattern replaced by a replacement.  The pattern can be a string or a RegExp, and the replacement can be a string or a function to be called for each match.\"\n      },\n      \"search\": {\n        \"!type\": \"fn(pattern: +RegExp) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/search\",\n        \"!doc\": \"Executes the search for a match between a regular expression and this String object.\"\n      },\n      \"codePointAt\": {\n        \"!type\": \"fn(pos: number) -> number\",\n        \"!doc\": \"The codePointAt() method returns a non-negative integer that is the UTF-16 encoded code point value.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt\"\n      },\n      \"endsWith\": {\n        \"!type\": \"fn(searchString: string, position?: number) -> bool\",\n        \"!doc\": \"The endsWith() method determines whether a string ends with the characters of another string, returning true or false as appropriate.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith\"\n      },\n      \"includes\": {\n        \"!type\": \"fn(searchString: string, position?: number) -> bool\",\n        \"!doc\": \"The includes() method determines whether one string may be found within another string, returning true or false as appropriate.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/contains\"\n      },\n      \"normalize\": {\n        \"!type\": \"fn(form: string) -> string\",\n        \"!doc\": \"The normalize() method returns the Unicode Normalization Form of a given string (if the value isn't a string, it will be converted to one first).\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize\"\n      },\n      \"repeat\": {\n        \"!type\": \"fn(count: number) -> string\",\n        \"!doc\": \"The repeat() method constructs and returns a new string which contains the specified number of copies of the string on which it was called, concatenated together.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat\"\n      },\n      \"startsWith\": {\n        \"!type\": \"fn(searchString: string, position?: number) -> bool\",\n        \"!doc\": \"The startsWith() method determines whether a string begins with the characters of another string, returning true or false as appropriate.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith\"\n      },\n      \":Symbol.iterator\": {\n        \"!type\": \"fn() -> +iter[:t=string]\",\n        \"!doc\": \"Returns a new Iterator object that iterates over the code points of a String value, returning each code point as a String value.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@iterator\"\n      }\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String\",\n    \"!doc\": \"The String global object is a constructor for strings, or a sequence of characters.\"\n  },\n  \"Number\": {\n    \"!type\": \"fn(value: ?) -> number\",\n    \"MAX_VALUE\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/MAX_VALUE\",\n      \"!doc\": \"The maximum numeric value representable in JavaScript.\"\n    },\n    \"MIN_VALUE\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/MIN_VALUE\",\n      \"!doc\": \"The smallest positive numeric value representable in JavaScript.\"\n    },\n    \"POSITIVE_INFINITY\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/POSITIVE_INFINITY\",\n      \"!doc\": \"A value representing the positive Infinity value.\"\n    },\n    \"NEGATIVE_INFINITY\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/NEGATIVE_INFINITY\",\n      \"!doc\": \"A value representing the negative Infinity value.\"\n    },\n    \"prototype\": {\n      \"!stdProto\": \"Number\",\n      \"toString\": {\n        \"!type\": \"fn(radix?: number) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toString\",\n        \"!doc\": \"Returns a string representing the specified Number object\"\n      },\n      \"toFixed\": {\n        \"!type\": \"fn(digits: number) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toFixed\",\n        \"!doc\": \"Formats a number using fixed-point notation\"\n      },\n      \"toExponential\": {\n        \"!type\": \"fn(digits: number) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toExponential\",\n        \"!doc\": \"Returns a string representing the Number object in exponential notation\"\n      },\n      \"toPrecision\": {\n        \"!type\": \"fn(digits: number) -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toPrecision\",\n        \"!doc\": \"The toPrecision() method returns a string representing the number to the specified precision.\"\n      }\n    },\n    \"EPSILON\": {\n      \"!type\": \"number\",\n      \"!doc\": \"The Number.EPSILON property represents the difference between one and the smallest value greater than one that can be represented as a Number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON\"\n    },\n    \"MAX_SAFE_INTEGER\": {\n      \"!type\": \"number\",\n      \"!doc\": \"The Number.MAX_SAFE_INTEGER constant represents the maximum safe integer in JavaScript (253 - 1).\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER\"\n    },\n    \"MIN_SAFE_INTEGER\": {\n      \"!type\": \"number\",\n      \"!doc\": \"The Number.MIN_SAFE_INTEGER constant represents the minimum safe integer in JavaScript (-(253 - 1)).\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER\"\n    },\n    \"isFinite\": {\n      \"!type\": \"fn(testValue: ?) -> bool\",\n      \"!doc\": \"The Number.isFinite() method determines whether the passed value is finite.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite\"\n    },\n    \"isInteger\": {\n      \"!type\": \"fn(testValue: ?) -> bool\",\n      \"!doc\": \"The Number.isInteger() method determines whether the passed value is an integer.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger\"\n    },\n    \"isNaN\": {\n      \"!type\": \"fn(testValue: ?) -> bool\",\n      \"!doc\": \"The Number.isNaN() method determines whether the passed value is NaN. More robust version of the original global isNaN().\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN\"\n    },\n    \"isSafeInteger\": {\n      \"!type\": \"fn(testValue: ?) -> bool\",\n      \"!doc\": \"The Number.isSafeInteger() method determines whether the provided value is a number that is a safe integer. A safe integer is an integer that\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger\"\n    },\n    \"parseFloat\": {\n      \"!type\": \"fn(string: string) -> number\",\n      \"!doc\": \"The Number.parseFloat() method parses a string argument and returns a floating point number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseFloat\"\n    },\n    \"parseInt\": {\n      \"!type\": \"fn(string: string, radix?: number) -> number\",\n      \"!doc\": \"The Number.parseInt() method parses a string argument and returns an integer of the specified radix or base.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseInt\"\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number\",\n    \"!doc\": \"The Number JavaScript object is a wrapper object allowing you to work with numerical values. A Number object is created using the Number() constructor.\"\n  },\n  \"Boolean\": {\n    \"!type\": \"fn(value: ?) -> bool\",\n    \"prototype\": {\n      \"!stdProto\": \"Boolean\"\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Boolean\",\n    \"!doc\": \"The Boolean object is an object wrapper for a boolean value.\"\n  },\n  \"RegExp\": {\n    \"!type\": \"fn(source: string, flags?: string)\",\n    \"prototype\": {\n      \"!stdProto\": \"RegExp\",\n      \"exec\": {\n        \"!type\": \"fn(input: string) -> [string]\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec\",\n        \"!doc\": \"Executes a search for a match in a specified string. Returns a result array, or null.\"\n      },\n      \"test\": {\n        \"!type\": \"fn(input: string) -> bool\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/test\",\n        \"!doc\": \"Executes the search for a match between a regular expression and a specified string. Returns true or false.\"\n      },\n      \"global\": {\n        \"!type\": \"bool\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp\",\n        \"!doc\": \"Creates a regular expression object for matching text with a pattern.\"\n      },\n      \"ignoreCase\": {\n        \"!type\": \"bool\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp\",\n        \"!doc\": \"Creates a regular expression object for matching text with a pattern.\"\n      },\n      \"multiline\": {\n        \"!type\": \"bool\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/multiline\",\n        \"!doc\": \"Reflects whether or not to search in strings across multiple lines.\\n\"\n      },\n      \"source\": {\n        \"!type\": \"string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/source\",\n        \"!doc\": \"A read-only property that contains the text of the pattern, excluding the forward slashes.\\n\"\n      },\n      \"lastIndex\": {\n        \"!type\": \"number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/lastIndex\",\n        \"!doc\": \"A read/write integer property that specifies the index at which to start the next match.\"\n      },\n      \"flags\": {\n        \"!type\": \"string\",\n        \"!doc\": \"The flags property returns a string consisting of the flags of the current regular expression object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags\"\n      },\n      \"sticky\": {\n        \"!type\": \"bool\",\n        \"!doc\": \"The sticky property reflects whether or not the search is sticky (searches in strings only from the index indicated by the lastIndex property of this regular expression). sticky is a read-only property of an individual regular expression object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky\"\n      },\n      \"unicode\": {\n        \"!type\": \"bool\",\n        \"!doc\": \"The 'u' flag enables various Unicode-related features.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode\"\n      }\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp\",\n    \"!doc\": \"Creates a regular expression object for matching text with a pattern.\"\n  },\n  \"Date\": {\n    \"!type\": \"fn(ms: number)\",\n    \"parse\": {\n      \"!type\": \"fn(source: string) -> +Date\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/parse\",\n      \"!doc\": \"Parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC.\"\n    },\n    \"UTC\": {\n      \"!type\": \"fn(year: number, month: number, date: number, hour?: number, min?: number, sec?: number, ms?: number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/UTC\",\n      \"!doc\": \"Accepts the same parameters as the longest form of the constructor, and returns the number of milliseconds in a Date object since January 1, 1970, 00:00:00, universal time.\"\n    },\n    \"now\": {\n      \"!type\": \"fn() -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/now\",\n      \"!doc\": \"Returns the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.\"\n    },\n    \"prototype\": {\n      \"toUTCString\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toUTCString\",\n        \"!doc\": \"Converts a date to a string, using the universal time convention.\"\n      },\n      \"toISOString\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toISOString\",\n        \"!doc\": \"JavaScript provides a direct way to convert a date object into a string in ISO format, the ISO 8601 Extended Format.\"\n      },\n      \"toDateString\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toDateString\",\n        \"!doc\": \"Returns the date portion of a Date object in human readable form in American English.\"\n      },\n      \"toTimeString\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toTimeString\",\n        \"!doc\": \"Returns the time portion of a Date object in human readable form in American English.\"\n      },\n      \"toLocaleDateString\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toLocaleDateString\",\n        \"!doc\": \"Converts a date to a string, returning the \\\"date\\\" portion using the operating system's locale's conventions.\\n\"\n      },\n      \"toLocaleTimeString\": {\n        \"!type\": \"fn() -> string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString\",\n        \"!doc\": \"Converts a date to a string, returning the \\\"time\\\" portion using the current locale's conventions.\"\n      },\n      \"getTime\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getTime\",\n        \"!doc\": \"Returns the numeric value corresponding to the time for the specified date according to universal time.\"\n      },\n      \"getFullYear\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getFullYear\",\n        \"!doc\": \"Returns the year of the specified date according to local time.\"\n      },\n      \"getYear\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getYear\",\n        \"!doc\": \"Returns the year in the specified date according to local time.\"\n      },\n      \"getMonth\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getMonth\",\n        \"!doc\": \"Returns the month in the specified date according to local time.\"\n      },\n      \"getUTCMonth\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCMonth\",\n        \"!doc\": \"Returns the month of the specified date according to universal time.\\n\"\n      },\n      \"getDate\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getDate\",\n        \"!doc\": \"Returns the day of the month for the specified date according to local time.\"\n      },\n      \"getUTCDate\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCDate\",\n        \"!doc\": \"Returns the day (date) of the month in the specified date according to universal time.\\n\"\n      },\n      \"getDay\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getDay\",\n        \"!doc\": \"Returns the day of the week for the specified date according to local time.\"\n      },\n      \"getUTCDay\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCDay\",\n        \"!doc\": \"Returns the day of the week in the specified date according to universal time.\\n\"\n      },\n      \"getHours\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getHours\",\n        \"!doc\": \"Returns the hour for the specified date according to local time.\"\n      },\n      \"getUTCHours\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCHours\",\n        \"!doc\": \"Returns the hours in the specified date according to universal time.\\n\"\n      },\n      \"getMinutes\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getMinutes\",\n        \"!doc\": \"Returns the minutes in the specified date according to local time.\"\n      },\n      \"getUTCMinutes\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date\",\n        \"!doc\": \"Creates JavaScript Date instances which let you work with dates and times.\"\n      },\n      \"getSeconds\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getSeconds\",\n        \"!doc\": \"Returns the seconds in the specified date according to local time.\"\n      },\n      \"getUTCSeconds\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCSeconds\",\n        \"!doc\": \"Returns the seconds in the specified date according to universal time.\\n\"\n      },\n      \"getMilliseconds\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getMilliseconds\",\n        \"!doc\": \"Returns the milliseconds in the specified date according to local time.\"\n      },\n      \"getUTCMilliseconds\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds\",\n        \"!doc\": \"Returns the milliseconds in the specified date according to universal time.\\n\"\n      },\n      \"getTimezoneOffset\": {\n        \"!type\": \"fn() -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset\",\n        \"!doc\": \"Returns the time-zone offset from UTC, in minutes, for the current locale.\"\n      },\n      \"setTime\": {\n        \"!type\": \"fn(date: +Date) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setTime\",\n        \"!doc\": \"Sets the Date object to the time represented by a number of milliseconds since January 1, 1970, 00:00:00 UTC.\\n\"\n      },\n      \"setFullYear\": {\n        \"!type\": \"fn(year: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setFullYear\",\n        \"!doc\": \"Sets the full year for a specified date according to local time.\\n\"\n      },\n      \"setUTCFullYear\": {\n        \"!type\": \"fn(year: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCFullYear\",\n        \"!doc\": \"Sets the full year for a specified date according to universal time.\\n\"\n      },\n      \"setMonth\": {\n        \"!type\": \"fn(month: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setMonth\",\n        \"!doc\": \"Set the month for a specified date according to local time.\"\n      },\n      \"setUTCMonth\": {\n        \"!type\": \"fn(month: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCMonth\",\n        \"!doc\": \"Sets the month for a specified date according to universal time.\\n\"\n      },\n      \"setDate\": {\n        \"!type\": \"fn(day: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setDate\",\n        \"!doc\": \"Sets the day of the month for a specified date according to local time.\"\n      },\n      \"setUTCDate\": {\n        \"!type\": \"fn(day: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCDate\",\n        \"!doc\": \"Sets the day of the month for a specified date according to universal time.\\n\"\n      },\n      \"setHours\": {\n        \"!type\": \"fn(hour: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setHours\",\n        \"!doc\": \"Sets the hours for a specified date according to local time, and returns the number of milliseconds since 1 January 1970 00:00:00 UTC until the time represented by the updated Date instance.\"\n      },\n      \"setUTCHours\": {\n        \"!type\": \"fn(hour: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCHours\",\n        \"!doc\": \"Sets the hour for a specified date according to universal time.\\n\"\n      },\n      \"setMinutes\": {\n        \"!type\": \"fn(min: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setMinutes\",\n        \"!doc\": \"Sets the minutes for a specified date according to local time.\"\n      },\n      \"setUTCMinutes\": {\n        \"!type\": \"fn(min: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCMinutes\",\n        \"!doc\": \"Sets the minutes for a specified date according to universal time.\\n\"\n      },\n      \"setSeconds\": {\n        \"!type\": \"fn(sec: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setSeconds\",\n        \"!doc\": \"Sets the seconds for a specified date according to local time.\"\n      },\n      \"setUTCSeconds\": {\n        \"!type\": \"fn(sec: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCSeconds\",\n        \"!doc\": \"Sets the seconds for a specified date according to universal time.\\n\"\n      },\n      \"setMilliseconds\": {\n        \"!type\": \"fn(ms: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setMilliseconds\",\n        \"!doc\": \"Sets the milliseconds for a specified date according to local time.\\n\"\n      },\n      \"setUTCMilliseconds\": {\n        \"!type\": \"fn(ms: number) -> number\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCMilliseconds\",\n        \"!doc\": \"Sets the milliseconds for a specified date according to universal time.\\n\"\n      },\n      \"toJSON\": {\n        \"!type\": \"fn() -> string\",\n        \"!doc\": \"Returns a string (using toISOString()) representing the Date object's value.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON\"\n      }\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date\",\n    \"!doc\": \"Creates JavaScript Date instances which let you work with dates and times.\"\n  },\n  \"Error\": {\n    \"!type\": \"fn(message: string)\",\n    \"prototype\": {\n      \"name\": {\n        \"!type\": \"string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error/name\",\n        \"!doc\": \"A name for the type of error.\"\n      },\n      \"message\": {\n        \"!type\": \"string\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error/message\",\n        \"!doc\": \"A human-readable description of the error.\"\n      }\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error\",\n    \"!doc\": \"Creates an error object.\"\n  },\n  \"SyntaxError\": {\n    \"!type\": \"fn(message: string)\",\n    \"prototype\": \"Error.prototype\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/SyntaxError\",\n    \"!doc\": \"Represents an error when trying to interpret syntactically invalid code.\"\n  },\n  \"ReferenceError\": {\n    \"!type\": \"fn(message: string)\",\n    \"prototype\": \"Error.prototype\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/ReferenceError\",\n    \"!doc\": \"Represents an error when a non-existent variable is referenced.\"\n  },\n  \"URIError\": {\n    \"!type\": \"fn(message: string)\",\n    \"prototype\": \"Error.prototype\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/URIError\",\n    \"!doc\": \"Represents an error when a malformed URI is encountered.\"\n  },\n  \"EvalError\": {\n    \"!type\": \"fn(message: string)\",\n    \"prototype\": \"Error.prototype\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/EvalError\",\n    \"!doc\": \"Represents an error regarding the eval function.\"\n  },\n  \"RangeError\": {\n    \"!type\": \"fn(message: string)\",\n    \"prototype\": \"Error.prototype\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RangeError\",\n    \"!doc\": \"Represents an error when a number is not within the correct range allowed.\"\n  },\n  \"TypeError\": {\n    \"!type\": \"fn(message: string)\",\n    \"prototype\": \"Error.prototype\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/TypeError\",\n    \"!doc\": \"Represents an error an error when a value is not of the expected type.\"\n  },\n  \"parseInt\": {\n    \"!type\": \"fn(string: string, radix?: number) -> number\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt\",\n    \"!doc\": \"Parses a string argument and returns an integer of the specified radix or base.\"\n  },\n  \"parseFloat\": {\n    \"!type\": \"fn(string: string) -> number\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseFloat\",\n    \"!doc\": \"Parses a string argument and returns a floating point number.\"\n  },\n  \"isNaN\": {\n    \"!type\": \"fn(value: number) -> bool\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/isNaN\",\n    \"!doc\": \"Determines whether a value is NaN or not. Be careful, this function is broken. You may be interested in ECMAScript 6 Number.isNaN.\"\n  },\n  \"isFinite\": {\n    \"!type\": \"fn(value: number) -> bool\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/isFinite\",\n    \"!doc\": \"Determines whether the passed value is a finite number.\"\n  },\n  \"eval\": {\n    \"!type\": \"fn(code: string) -> ?\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/eval\",\n    \"!doc\": \"Evaluates JavaScript code represented as a string.\"\n  },\n  \"encodeURI\": {\n    \"!type\": \"fn(uri: string) -> string\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURI\",\n    \"!doc\": \"Encodes a Uniform Resource Identifier (URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two \\\"surrogate\\\" characters).\"\n  },\n  \"encodeURIComponent\": {\n    \"!type\": \"fn(uri: string) -> string\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent\",\n    \"!doc\": \"Encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two \\\"surrogate\\\" characters).\"\n  },\n  \"decodeURI\": {\n    \"!type\": \"fn(uri: string) -> string\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/decodeURI\",\n    \"!doc\": \"Decodes a Uniform Resource Identifier (URI) previously created by encodeURI or by a similar routine.\"\n  },\n  \"decodeURIComponent\": {\n    \"!type\": \"fn(uri: string) -> string\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/decodeURIComponent\",\n    \"!doc\": \"Decodes a Uniform Resource Identifier (URI) component previously created by encodeURIComponent or by a similar routine.\"\n  },\n  \"Math\": {\n    \"E\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/E\",\n      \"!doc\": \"The base of natural logarithms, e, approximately 2.718.\"\n    },\n    \"LN2\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LN2\",\n      \"!doc\": \"The natural logarithm of 2, approximately 0.693.\"\n    },\n    \"LN10\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LN10\",\n      \"!doc\": \"The natural logarithm of 10, approximately 2.302.\"\n    },\n    \"LOG2E\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LOG2E\",\n      \"!doc\": \"The base 2 logarithm of E (approximately 1.442).\"\n    },\n    \"LOG10E\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LOG10E\",\n      \"!doc\": \"The base 10 logarithm of E (approximately 0.434).\"\n    },\n    \"SQRT1_2\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/SQRT1_2\",\n      \"!doc\": \"The square root of 1/2; equivalently, 1 over the square root of 2, approximately 0.707.\"\n    },\n    \"SQRT2\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/SQRT2\",\n      \"!doc\": \"The square root of 2, approximately 1.414.\"\n    },\n    \"PI\": {\n      \"!type\": \"number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/PI\",\n      \"!doc\": \"The ratio of the circumference of a circle to its diameter, approximately 3.14159.\"\n    },\n    \"abs\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/abs\",\n      \"!doc\": \"Returns the absolute value of a number.\"\n    },\n    \"cos\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/cos\",\n      \"!doc\": \"Returns the cosine of a number.\"\n    },\n    \"sin\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/sin\",\n      \"!doc\": \"Returns the sine of a number.\"\n    },\n    \"tan\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/tan\",\n      \"!doc\": \"Returns the tangent of a number.\"\n    },\n    \"acos\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/acos\",\n      \"!doc\": \"Returns the arccosine (in radians) of a number.\"\n    },\n    \"asin\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/asin\",\n      \"!doc\": \"Returns the arcsine (in radians) of a number.\"\n    },\n    \"atan\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/atan\",\n      \"!doc\": \"Returns the arctangent (in radians) of a number.\"\n    },\n    \"atan2\": {\n      \"!type\": \"fn(y: number, x: number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/atan2\",\n      \"!doc\": \"Returns the arctangent of the quotient of its arguments.\"\n    },\n    \"ceil\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/ceil\",\n      \"!doc\": \"Returns the smallest integer greater than or equal to a number.\"\n    },\n    \"floor\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/floor\",\n      \"!doc\": \"Returns the largest integer less than or equal to a number.\"\n    },\n    \"round\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/round\",\n      \"!doc\": \"Returns the value of a number rounded to the nearest integer.\"\n    },\n    \"exp\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/exp\",\n      \"!doc\": \"Returns Ex, where x is the argument, and E is Euler's constant, the base of the natural logarithms.\"\n    },\n    \"log\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/log\",\n      \"!doc\": \"Returns the natural logarithm (base E) of a number.\"\n    },\n    \"sqrt\": {\n      \"!type\": \"fn(number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/sqrt\",\n      \"!doc\": \"Returns the square root of a number.\"\n    },\n    \"pow\": {\n      \"!type\": \"fn(number, number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/pow\",\n      \"!doc\": \"Returns base to the exponent power, that is, baseexponent.\"\n    },\n    \"max\": {\n      \"!type\": \"fn(number, number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/max\",\n      \"!doc\": \"Returns the largest of zero or more numbers.\"\n    },\n    \"min\": {\n      \"!type\": \"fn(number, number) -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/min\",\n      \"!doc\": \"Returns the smallest of zero or more numbers.\"\n    },\n    \"random\": {\n      \"!type\": \"fn() -> number\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/random\",\n      \"!doc\": \"Returns a floating-point, pseudo-random number in the range [0, 1) that is, from 0 (inclusive) up to but not including 1 (exclusive), which you can then scale to your desired range.\"\n    },\n    \"acosh\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.acosh() function returns the hyperbolic arc-cosine of a number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh\"\n    },\n    \"asinh\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.asinh() function returns the hyperbolic arcsine of a number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh\"\n    },\n    \"atanh\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.atanh() function returns the hyperbolic arctangent of a number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh\"\n    },\n    \"cbrt\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.cbrt() function returns the cube root of a number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt\"\n    },\n    \"clz32\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.clz32() function returns the number of leading zero bits in the 32-bit binary representation of a number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32\"\n    },\n    \"cosh\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.cosh() function returns the hyperbolic cosine of a number, that can be expressed using the constant e:\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh\"\n    },\n    \"expm1\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.expm1() function returns ex - 1, where x is the argument, and e the base of the natural logarithms.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1\"\n    },\n    \"fround\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.fround() function returns the nearest single precision float representation of a number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround\"\n    },\n    \"hypot\": {\n      \"!type\": \"fn(value: number) -> number\",\n      \"!doc\": \"The Math.hypot() function returns the square root of the sum of squares of its arguments.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot\"\n    },\n    \"imul\": {\n      \"!type\": \"fn(a: number, b: number) -> number\",\n      \"!doc\": \"The Math.imul() function returns the result of the C-like 32-bit multiplication of the two parameters.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul\"\n    },\n    \"log10\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.log10() function returns the base 10 logarithm of a number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10\"\n    },\n    \"log1p\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.log1p() function returns the natural logarithm (base e) of 1 + a number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p\"\n    },\n    \"log2\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.log2() function returns the base 2 logarithm of a number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2\"\n    },\n    \"sign\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.sign() function returns the sign of a number, indicating whether the number is positive, negative or zero.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\"\n    },\n    \"sinh\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.sinh() function returns the hyperbolic sine of a number, that can be expressed using the constant e:\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sinh\"\n    },\n    \"tanh\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.tanh() function returns the hyperbolic tangent of a number.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tanh\"\n    },\n    \"trunc\": {\n      \"!type\": \"fn(x: number) -> number\",\n      \"!doc\": \"The Math.trunc() function returns the integral part of a number by removing any fractional digits. It does not round any numbers. The function can be expressed with the floor() and ceil() function:\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc\"\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math\",\n    \"!doc\": \"A built-in object that has properties and methods for mathematical constants and functions.\"\n  },\n  \"JSON\": {\n    \"parse\": {\n      \"!type\": \"fn(json: string, reviver?: fn(key: string, value: ?) -> ?) -> ?\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/parse\",\n      \"!doc\": \"Parse a string as JSON, optionally transforming the value produced by parsing.\"\n    },\n    \"stringify\": {\n      \"!type\": \"fn(value: ?, replacer?: fn(key: string, value: ?) -> ?, space?: string|number) -> string\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify\",\n      \"!doc\": \"Convert a value to JSON, optionally replacing values if a replacer function is specified, or optionally including only the specified properties if a replacer array is specified.\"\n    },\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/JSON\",\n    \"!doc\": \"JSON (JavaScript Object Notation) is a data-interchange format.  It closely resembles a subset of JavaScript syntax, although it is not a strict subset. (See JSON in the JavaScript Reference for full details.)  It is useful when writing any kind of JavaScript-based application, including websites and browser extensions.  For example, you might store user information in JSON format in a cookie, or you might store extension preferences in JSON in a string-valued browser preference.\"\n  },\n  \"ArrayBuffer\": {\n    \"!type\": \"fn(length: number)\",\n    \"!doc\": \"The ArrayBuffer object is used to represent a generic, fixed-length raw binary data buffer.\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer\",\n    \"isView\": {\n      \"!type\": \"fn(arg: +ArrayBuffer) -> bool\",\n      \"!doc\": \"The ArrayBuffer.isView() method returns true if arg is one of the ArrayBuffer views, such as typed array objects or a DataView; false otherwise.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView\"\n    },\n    \"prototype\": {\n      \"byteLength\": {\n        \"!type\": \"number\",\n        \"!doc\": \"The byteLength accessor property represents the length of an ArrayBuffer in bytes.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength\"\n      },\n      \"slice\": {\n        \"!type\": \"fn(begin: number, end?: number) -> +ArrayBuffer\",\n        \"!doc\": \"The slice() method returns a new ArrayBuffer whose contents are a copy of this ArrayBuffer's bytes from begin, inclusive, up to end, exclusive.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/slice\"\n      }\n    }\n  },\n  \"DataView\": {\n    \"!type\": \"fn(buffer: +ArrayBuffer, byteOffset?: number, byteLength?: number)\",\n    \"!doc\": \"The DataView view provides a low-level interface for reading data from and writing it to an ArrayBuffer.\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView\",\n    \"prototype\": {\n      \"buffer\": {\n        \"!type\": \"+ArrayBuffer\",\n        \"!doc\": \"The buffer accessor property represents the ArrayBuffer referenced by the DataView at construction time.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/buffer\"\n      },\n      \"byteLength\": {\n        \"!type\": \"number\",\n        \"!doc\": \"The byteLength accessor property represents the length (in bytes) of this view from the start of its ArrayBuffer.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/byteLength\"\n      },\n      \"byteOffset\": {\n        \"!type\": \"number\",\n        \"!doc\": \"The byteOffset accessor property represents the offset (in bytes) of this view from the start of its ArrayBuffer.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/byteOffset\"\n      },\n      \"getFloat32\": {\n        \"!type\": \"fn(byteOffset: number, littleEndian?: bool) -> number\",\n        \"!doc\": \"The getFloat32() method gets a signed 32-bit integer (float) at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getFloat32\"\n      },\n      \"getFloat64\": {\n        \"!type\": \"fn(byteOffset: number, littleEndian?: bool) -> number\",\n        \"!doc\": \"The getFloat64() method gets a signed 64-bit float (double) at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getFloat64\"\n      },\n      \"getInt16\": {\n        \"!type\": \"fn(byteOffset: number, littleEndian?: bool) -> number\",\n        \"!doc\": \"The getInt16() method gets a signed 16-bit integer (short) at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt16\"\n      },\n      \"getInt32\": {\n        \"!type\": \"fn(byteOffset: number, littleEndian?: bool) -> number\",\n        \"!doc\": \"The getInt32() method gets a signed 32-bit integer (long) at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt32\"\n      },\n      \"getInt8\": {\n        \"!type\": \"fn(byteOffset: number, littleEndian?: bool) -> number\",\n        \"!doc\": \"The getInt8() method gets a signed 8-bit integer (byte) at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt8\"\n      },\n      \"getUint16\": {\n        \"!type\": \"fn(byteOffset: number, littleEndian?: bool) -> number\",\n        \"!doc\": \"The getUint16() method gets an unsigned 16-bit integer (unsigned short) at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint16\"\n      },\n      \"getUint32\": {\n        \"!type\": \"fn(byteOffset: number, littleEndian?: bool) -> number\",\n        \"!doc\": \"The getUint32() method gets an unsigned 32-bit integer (unsigned long) at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint32\"\n      },\n      \"getUint8\": {\n        \"!type\": \"fn(byteOffset: number) -> number\",\n        \"!doc\": \"The getUint8() method gets an unsigned 8-bit integer (unsigned byte) at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint8\"\n      },\n      \"setFloat32\": {\n        \"!type\": \"fn(byteOffset: number, value: number, littleEndian?: bool)\",\n        \"!doc\": \"The setFloat32() method stores a signed 32-bit integer (float) value at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat32\"\n      },\n      \"setFloat64\": {\n        \"!type\": \"fn(byteOffset: number, value: number, littleEndian?: bool)\",\n        \"!doc\": \"The setFloat64() method stores a signed 64-bit integer (double) value at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat64\"\n      },\n      \"setInt16\": {\n        \"!type\": \"fn(byteOffset: number, value: number, littleEndian?: bool)\",\n        \"!doc\": \"The setInt16() method stores a signed 16-bit integer (short) value at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt16\"\n      },\n      \"setInt32\": {\n        \"!type\": \"fn(byteOffset: number, value: number, littleEndian?: bool)\",\n        \"!doc\": \"The setInt32() method stores a signed 32-bit integer (long) value at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt32\"\n      },\n      \"setInt8\": {\n        \"!type\": \"fn(byteOffset: number, value: number)\",\n        \"!doc\": \"The setInt8() method stores a signed 8-bit integer (byte) value at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt8\"\n      },\n      \"setUint16\": {\n        \"!type\": \"fn(byteOffset: number, value: number, littleEndian?: bool)\",\n        \"!doc\": \"The setUint16() method stores an unsigned 16-bit integer (unsigned short) value at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint16\"\n      },\n      \"setUint32\": {\n        \"!type\": \"fn(byteOffset: number, value: number, littleEndian?: bool)\",\n        \"!doc\": \"The setUint32() method stores an unsigned 32-bit integer (unsigned long) value at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint32\"\n      },\n      \"setUint8\": {\n        \"!type\": \"fn(byteOffset: number, value: number)\",\n        \"!doc\": \"The setUint8() method stores an unsigned 8-bit integer (byte) value at the specified byte offset from the start of the DataView.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint8\"\n      }\n    }\n  },\n  \"Float32Array\": \"TypedArray\",\n  \"Float64Array\": \"TypedArray\",\n  \"Int16Array\": \"TypedArray\",\n  \"Int32Array\": \"TypedArray\",\n  \"Int8Array\": \"TypedArray\",\n  \"Map\": {\n    \"!type\": \"fn(iterable?: [?])\",\n    \"!doc\": \"The Map object is a simple key/value map. Any value (both objects and primitive values) may be used as either a key or a value.\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map\",\n    \"prototype\": {\n      \"clear\": {\n        \"!type\": \"fn()\",\n        \"!doc\": \"The clear() method removes all elements from a Map object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear\"\n      },\n      \"delete\": {\n        \"!type\": \"fn(key: ?)\",\n        \"!doc\": \"The delete() method removes the specified element from a Map object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete\"\n      },\n      \"entries\": {\n        \"!type\": \"fn() -> +iter[:t=[!this.:key, !this.:value]]\",\n        \"!doc\": \"The entries() method returns a new Iterator object that contains the [key, value] pairs for each element in the Map object in insertion order.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries\"\n      },\n      \"forEach\": {\n        \"!type\": \"fn(callback: fn(value: ?, key: ?, map: +Map), thisArg?: ?)\",\n        \"!effects\": [\"call !0 this=!1 !this.:value !this.:key !this\"],\n        \"!doc\": \"The forEach() method executes a provided function once per each key/value pair in the Map object, in insertion order.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach\"\n      },\n      \"get\": {\n        \"!type\": \"fn(key: ?) -> !this.:value\",\n        \"!doc\": \"The get() method returns a specified element from a Map object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get\"\n      },\n      \"has\": {\n        \"!type\": \"fn(key: ?) -> bool\",\n        \"!doc\": \"The has() method returns a boolean indicating whether an element with the specified key exists or not.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has\"\n      },\n      \"keys\": {\n        \"!type\": \"fn() -> +iter[:t=!this.:key]\",\n        \"!doc\": \"The keys() method returns a new Iterator object that contains the keys for each element in the Map object in insertion order.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys\"\n      },\n      \"set\": {\n        \"!type\": \"fn(key: ?, value: ?) -> !this\",\n        \"!effects\": [\"propagate !0 !this.:key\", \"propagate !1 !this.:value\"],\n        \"!doc\": \"The set() method adds a new element with a specified key and value to a Map object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set\"\n      },\n      \"size\": {\n        \"!type\": \"number\",\n        \"!doc\": \"The size accessor property returns the number of elements in a Map object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size\"\n      },\n      \"values\": {\n        \"!type\": \"fn() -> +iter[:t=!this.:value]\",\n        \"!doc\": \"The values() method returns a new Iterator object that contains the values for each element in the Map object in insertion order.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values\"\n      },\n      \":Symbol.iterator\": {\n        \"!type\": \"fn() -> +iter[:t=[!this.:key, !this.:value]]\",\n        \"!doc\": \"Returns a new Iterator object that contains the [key, value] pairs for each element in the Map object in insertion order.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@iterator\"\n      }\n    }\n  },\n  \"Promise\": {\n    \"!type\": \"fn(executor: fn(resolve: fn(value: ?), reject: fn(reason: ?))) -> !custom:Promise_ctor\",\n    \"!doc\": \"The Promise object is used for deferred and asynchronous computations. A Promise is in one of the three states:\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise\",\n    \"all\": {\n      \"!type\": \"fn(iterable: [+Promise]) -> +Promise[:t=[!0.<i>.:t]]\",\n      \"!doc\": \"The Promise.all(iterable) method returns a promise that resolves when all of the promises in the iterable argument have resolved.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all\"\n    },\n    \"race\": {\n      \"!type\": \"fn(iterable: [+Promise]) -> !0.<i>\",\n      \"!doc\": \"The Promise.race(iterable) method returns a promise that resolves or rejects as soon as one of the promises in the iterable resolves or rejects, with the value or reason from that promise.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race\"\n    },\n    \"reject\": \"Promise_reject\",\n    \"resolve\": {\n      \"!type\": \"fn(value: ?) -> !custom:Promise_resolve\",\n      \"!doc\": \"The Promise.resolve(value) method returns a Promise object that is resolved with the given value. If the value is a thenable (i.e. has a then method), the returned promise will 'follow' that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve\"\n    },\n    \"prototype\": \"Promise.prototype\"\n  },\n  \"Proxy\": {\n    \"!type\": \"fn(target: ?, handler: Proxy_handler)\",\n    \"!doc\": \"The Proxy object is used to define the custom behavior in JavaScript fundamental operation (e.g. property lookup, assignment, enumeration, function invocation, etc).\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy\",\n    \"revocable\": {\n      \"!type\": \"fn(target: ?, handler: Proxy_handler) -> Proxy_revocable\",\n      \"!doc\": \"The Proxy.revocable() method is used to create a revocable Proxy object.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/revocable\"\n    }\n  },\n  \"Reflect\": {\n    \"!doc\": \"Reflect is a built-in object that provides methods for interceptable JavaScript operations.\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect\",\n    \"apply\": {\n      \"!type\": \"fn(target: fn(), thisArg?: ?, argumentList?: [?]) -> !0.!ret\",\n      \"!doc\": \"Calls a target function with arguments as specified.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/apply\"\n    },\n    \"construct\": {\n      \"!type\": \"fn(target: fn(), argumentList?: [?]) -> ?\",\n      \"!doc\": \"Acts like the new operator as a function. It is equivalent to calling new target(...args).\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct\"\n    },\n    \"defineProperty\": {\n      \"!type\": \"fn(target: ?, property: string, descriptor: propertyDescriptor) -> bool\",\n      \"!doc\": \"The static Reflect.defineProperty() method is like Object.defineProperty() but returns a Boolean.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty\"\n    },\n    \"deleteProperty\": {\n      \"!type\": \"fn(target: ?, property: string) -> bool\",\n      \"!doc\": \"Works like the delete operator as a function.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty\"\n    },\n    \"enumerate\": {\n      \"!type\": \"fn(target: ?) -> +iter[:t=string]\",\n      \"!doc\": \"Returns an iterator with the enumerable own and inherited properties of the target object.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/enumerate\"\n    },\n    \"get\": {\n      \"!type\": \"fn(target: ?, property: string) -> ?\",\n      \"!doc\": \"Gets a property from an object.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/get\"\n    },\n    \"getOwnPropertyDescriptor\": {\n      \"!type\": \"fn(target: ?, property: string) -> ?\",\n      \"!doc\": \"Returns a property descriptor of the given property if it exists on the object, undefined otherwise.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor\"\n    },\n    \"getPrototypeOf\": {\n      \"!type\": \"fn(target: ?) -> ?\",\n      \"!doc\": \"Returns the prototype of the specified object.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf\"\n    },\n    \"has\": {\n      \"!type\": \"fn(target: ?, property: string) -> bool\",\n      \"!doc\": \"The static Reflect.has() method works like the in operator as a function.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/has\"\n    },\n    \"isExtensible\": {\n      \"!type\": \"fn(target: ?) -> bool\",\n      \"!doc\": \"Determines if an object is extensible (whether it can have new properties added to it).\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible\"\n    },\n    \"ownKeys\": {\n      \"!type\": \"fn(target: ?) -> [string]\",\n      \"!doc\": \"Returns an array of the target object's own property keys.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys\"\n    },\n    \"preventExtensions\": {\n      \"!type\": \"fn(target: ?) -> bool\",\n      \"!doc\": \"Prevents new properties from ever being added to an object.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions\"\n    },\n    \"set\": {\n      \"!type\": \"fn(target: ?, property: string, value: ?) -> bool\",\n      \"!doc\": \"Set a property on an object.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/set\"\n    },\n    \"setPrototypeOf\": {\n      \"!type\": \"fn(target: ?, prototype: ?) -> bool\",\n      \"!doc\": \"Sets the prototype of a specified object to another object or to null.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf\"\n    }\n  },\n  \"Set\": {\n    \"!type\": \"fn(iterable?: [?])\",\n    \"!doc\": \"The Set object lets you store unique values of any type, whether primitive values or object references.\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set\",\n    \"prototype\": {\n      \"add\": {\n        \"!type\": \"fn(value: ?) -> !this\",\n        \"!effects\": [\"propagate !0 !this.:t\"],\n        \"!doc\": \"The add() method appends a new element with a specified value to the end of a Set object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add\"\n      },\n      \"clear\": {\n        \"!type\": \"fn()\",\n        \"!doc\": \"The clear() method removes all elements from a Set object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear\"\n      },\n      \"delete\": {\n        \"!type\": \"fn(value: ?) -> bool\",\n        \"!doc\": \"The delete() method removes the specified element from a Set object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete\"\n      },\n      \"entries\": {\n        \"!type\": \"fn() -> +iter[:t=[!this.:t]]\",\n        \"!doc\": \"The entries() method returns a new Iterator object that contains an array of [value, value] for each element in the Set object, in insertion order. For Set objects there is no key like in Map objects. However, to keep the API similar to the Map object, each entry has the same value for its key and value here, so that an array [value, value] is returned.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries\"\n      },\n      \"forEach\": {\n        \"!type\": \"fn(callback: fn(value: ?, value2: ?, set: +Set), thisArg?: ?)\",\n        \"!effects\": [\"call !0 this=!1 !this.:t number !this\"],\n        \"!doc\": \"The forEach() method executes a provided function once per each value in the Set object, in insertion order.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/forEach\"\n      },\n      \"has\": {\n        \"!type\": \"fn(value: ?) -> bool\",\n        \"!doc\": \"The has() method returns a boolean indicating whether an element with the specified value exists in a Set object or not.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has\"\n      },\n      \"keys\": {\n        \"!type\": \"fn() -> +iter[:t=!this.:t]\",\n        \"!doc\": \"The values() method returns a new Iterator object that contains the values for each element in the Set object in insertion order.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys\"\n      },\n      \"size\": {\n        \"!type\": \"number\",\n        \"!doc\": \"The size accessor property returns the number of elements in a Set object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size\"\n      },\n      \"values\": {\n        \"!type\": \"fn() -> +iter[:t=!this.:t]\",\n        \"!doc\": \"The values() method returns a new Iterator object that contains the values for each element in the Set object in insertion order.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values\"\n      },\n      \":Symbol.iterator\": {\n        \"!type\": \"fn() -> +iter[:t=!this.:t]\",\n        \"!doc\": \"Returns a new Iterator object that contains the values for each element in the Set object in insertion order.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/@@iterator\"\n      }\n    }\n  },\n  \"Symbol\": {\n    \"!type\": \"fn(description?: string) -> !custom:getSymbol\",\n    \"!doc\": \"A symbol is a unique and immutable data type and may be used as an identifier for object properties. The symbol object is an implicit object wrapper for the symbol primitive data type.\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol\",\n    \"for\": {\n      \"!type\": \"fn(key: string) -> !custom:getSymbol\",\n      \"!doc\": \"The Symbol.for(key) method searches for existing symbols in a runtime-wide symbol registry with the given key and returns it if found. Otherwise a new symbol gets created in the global symbol registry with this key.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for\"\n    },\n    \"keyFor\": {\n      \"!type\": \"fn(sym: +Symbol) -> string\",\n      \"!doc\": \"The Symbol.keyFor(sym) method retrieves a shared symbol key from the global symbol registry for the given symbol.\",\n      \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/keyFor\"\n    },\n    \"hasInstance\": \":Symbol.hasInstance\",\n    \"isConcatSpreadable\": \":Symbol.isConcatSpreadable\",\n    \"iterator\": \":Symbol.iterator\",\n    \"keyFor\": \":Symbol.keyFor\",\n    \"match\": \":Symbol.match\",\n    \"replace\": \":Symbol.replace\",\n    \"search\": \":Symbol.search\",\n    \"species\": \":Symbol.species\",\n    \"split\": \":Symbol.split\",\n    \"toStringTag\": \":Symbol.toStringTag\",\n    \"unscopables\": \":Symbol.unscopables\",\n    \"prototype\": {\n      \"!stdProto\": \"Symbol\"\n    }\n  },\n  \"Uint16Array\": \"TypedArray\",\n  \"Uint32Array\": \"TypedArray\",\n  \"Uint8Array\": \"TypedArray\",\n  \"Uint8ClampedArray\": \"TypedArray\",\n  \"WeakMap\": {\n    \"!type\": \"fn(iterable?: [?])\",\n    \"!doc\": \"The WeakMap object is a collection of key/value pairs in which the keys are objects and the values can be arbitrary values.\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap\",\n    \"prototype\": {\n      \"delete\": {\n        \"!type\": \"fn(key: ?) -> bool\",\n        \"!doc\": \"The delete() method removes the specified element from a WeakMap object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/delete\"\n      },\n      \"get\": {\n        \"!type\": \"fn(key: ?) -> !this.:value\",\n        \"!doc\": \"The get() method returns a specified element from a WeakMap object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/get\"\n      },\n      \"has\": {\n        \"!type\": \"fn(key: ?) -> bool\",\n        \"!doc\": \"The has() method returns a boolean indicating whether an element with the specified key exists in the WeakMap object or not.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/has\"\n      },\n      \"set\": {\n        \"!type\": \"fn(key: ?, value: ?)\",\n        \"!effects\": [\"propagate !0 !this.:key\", \"propagate !1 !this.:value\"],\n        \"!doc\": \"The set() method adds a new element with a specified key and value to a WeakMap object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/set\"\n      }\n    }\n  },\n  \"WeakSet\": {\n    \"!type\": \"fn(iterable?: [?])\",\n    \"!doc\": \"The WeakSet object lets you store weakly held objects in a collection.\",\n    \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet\",\n    \"prototype\": {\n      \"add\": {\n        \"!type\": \"fn(value: ?)\",\n        \"!doc\": \"The add() method appends a new object to the end of a WeakSet object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/add\"\n      },\n      \"delete\": {\n        \"!type\": \"fn(value: ?) -> bool\",\n        \"!doc\": \"The delete() method removes the specified element from a WeakSet object.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/delete\"\n      },\n      \"has\": {\n        \"!type\": \"fn(value: ?) -> bool\",\n        \"!doc\": \"The has() method returns a boolean indicating whether an object exists in a WeakSet or not.\",\n        \"!url\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/has\"\n      }\n    }\n  },\n  \"uuid\": {},\n  \"numbro\": {\n    \"!type\": \"fn(number)\",\n    \"!doc\": \"Numbers can be formatted to look like currency, percentages, times, or even plain old numbers with decimal places, thousands, and abbreviations.\",\n    \"!url\": \"https://numbrojs.com/format.html\"\n  },\n  \"Papa\": {}\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/extensions/completionSources/TernServer/index.tsx",
    "content": "import {\n  Completion,\n  CompletionContext,\n  CompletionResult,\n} from \"@codemirror/autocomplete\"\nimport { getStringSnippets } from \"@illa-public/dynamic-string\"\nimport { CompletionsQuery, Server } from \"tern\"\nimport { CompletionsQueryResult } from \"tern/lib/tern\"\nimport { CODE_TYPE } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport ecmaScript from \"./defs/ecmascript.json\"\n\n// @ts-ignore\nconst server = new Server({ defs: [ecmaScript] })\n\nexport enum AutocompleteDataType {\n  OBJECT = \"Object\",\n  NUMBER = \"Number\",\n  ARRAY = \"Array\",\n  FUNCTION = \"Function\",\n  BOOLEAN = \"Boolean\",\n  STRING = \"String\",\n  UNKNOWN = \"Unknown\",\n}\n\nexport function getDataType(type: string): AutocompleteDataType {\n  if (type === \"?\") return AutocompleteDataType.UNKNOWN\n  else if (type === \"number\") return AutocompleteDataType.NUMBER\n  else if (type === \"string\") return AutocompleteDataType.STRING\n  else if (type === \"bool\") return AutocompleteDataType.BOOLEAN\n  else if (type === \"array\") return AutocompleteDataType.ARRAY\n  else if (/^\\[/.test(type)) return AutocompleteDataType.ARRAY\n  else if (/^fn\\(/.test(type)) return AutocompleteDataType.FUNCTION\n  else return AutocompleteDataType.UNKNOWN\n}\n\nexport function checkCursorInDynamicFlag(\n  context: CompletionContext,\n  isFunction?: boolean,\n): boolean {\n  if (isFunction) {\n    return true\n  }\n  const { state, pos } = context\n  const doc = state.sliceDoc(0, pos)\n  const stringSnippets = getStringSnippets(doc)\n  let nextDynamicStringStartIndex = 0\n  for (let i = 0; i < stringSnippets.length; i++) {\n    const snippet = stringSnippets[i]\n    const start = nextDynamicStringStartIndex\n    const dynamicStringStartIndex = snippet.indexOf(\"{{\")\n    const stringStartIndex = dynamicStringStartIndex + start + 2\n    const dynamicStringEndIndex = snippet.indexOf(\"}}\")\n    const stringEndIndex = dynamicStringEndIndex + start\n    if (\n      dynamicStringStartIndex > -1 &&\n      stringStartIndex <= pos &&\n      (dynamicStringEndIndex <= -1 || pos <= stringEndIndex)\n    ) {\n      return true\n    }\n    nextDynamicStringStartIndex += snippet.length\n  }\n  return false\n}\n\nexport const ternSeverCompletionSource = (\n  canShowCompleteInfo: boolean,\n  codeType: CODE_TYPE,\n): ((\n  context: CompletionContext,\n) => CompletionResult | Promise<CompletionResult | null> | null) => {\n  const isFunction =\n    codeType === CODE_TYPE.FUNCTION || codeType === CODE_TYPE.NO_METHOD_FUNCTION\n  return (context: CompletionContext) => {\n    const isCursorInDynamicFlag = checkCursorInDynamicFlag(context, isFunction)\n    if (!isCursorInDynamicFlag) {\n      return null\n    }\n    if (\n      context.matchBefore(/\\w[\\w\\.]*/) === null &&\n      (isFunction || context.matchBefore(/\\{\\{\\s*/) === null)\n    ) {\n      return null\n    }\n    const pos = context.pos\n    const query: CompletionsQuery = {\n      type: \"completions\",\n      types: true,\n      docs: true,\n      urls: true,\n      origins: true,\n      caseInsensitive: true,\n      guess: false,\n      inLiteral: false,\n      includeKeywords: true,\n      end: pos,\n      file: \"#0\",\n    }\n    const files = [\n      // @ts-ignore maybe this is a ternjs type error\n      {\n        type: \"full\",\n        name: \"_temp\",\n        text: context.state.sliceDoc(),\n      },\n    ]\n\n    const request = { query, files }\n    let error: string | null = null\n\n    // @ts-ignore maybe this is a ternjs type error\n    let result: any\n\n    server.request(\n      // @ts-ignore maybe this is a ternjs type error\n      request,\n      (ternError, response) => {\n        error = ternError\n        if (response) {\n          result = response as CompletionsQueryResult\n        }\n      },\n    )\n\n    if (error || !result || result.completions.length === 0) {\n      return null\n    }\n    const options: Completion[] = []\n    const completions = result.completions as Array<{\n      name: string\n      type?: string | undefined\n      depth?: number | undefined\n      doc?: string | undefined\n      url?: string | undefined\n      origin?: string | undefined\n    }>\n    completions.forEach((completion) => {\n      const dataType = getDataType(completion?.type || \"?\")\n      const completionOption: Completion = {\n        type: dataType,\n        label: completion.name,\n        detail: dataType,\n        boost: -1,\n      }\n      if (completion.doc && canShowCompleteInfo) {\n        completionOption.info = () => {\n          let dom = document.createElement(\"span\")\n          dom.innerHTML = `<div class=\"completionInfoCardTitle\">\n        <span class=\"cardTitle\">${completion.name}</span>\n        <a\n          class=\"openInfo\"\n          href=${completion.url}\n          target=\"_blank\"\n        >\n          <svg\n            width=\"12\"\n            height=\"12\"\n            viewBox=\"0 0 12 12\"\n            fill=\"none\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n          >\n            <path\n              fill-rule=\"evenodd\"\n              clip-rule=\"evenodd\"\n              d=\"M6.5 5C6.22386 5 6 4.77614 6 4.5L6 2L3 2L3 10L9 10L9 5L6.5 5ZM10 4.5V5L10 10.5C10 10.7761 9.77614 11 9.5 11L2.5 11C2.22386 11 2 10.7761 2 10.5L2 1.5C2 1.22386 2.22386 1 2.5 1L6 1L6.5 1L7 1.5L9.5 4L10 4.5ZM8.08579 4L7 2.91421L7 4H8.08579ZM4 7V6L8 6V7L4 7ZM4 9H7V8L4 8V9Z\"\n              fill=\"#654AEC\"\n            />\n          </svg>\n        </a>\n      </div>\n      <p class=\"completionInfoType\">${completion.type}</p>\n      <p class=\"completionInfoDoc\">${completion.doc}</p>`\n          return dom\n        }\n      }\n      options.push(completionOption)\n    })\n\n    return {\n      from: result.start,\n      validFor: /^\\w*$/,\n      options,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/extensions/completionSources/illaContext.ts",
    "content": "import {\n  Completion,\n  CompletionContext,\n  CompletionResult,\n} from \"@codemirror/autocomplete\"\nimport { capitalize } from \"lodash-es\"\nimport {\n  AutocompleteDataType,\n  checkCursorInDynamicFlag,\n} from \"@/components/CodeEditor/CodeMirror/extensions/completionSources/TernServer\"\nimport { CODE_TYPE } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport {\n  removeIgnoredKeys,\n  removeWidgetOrActionMethods,\n} from \"@/utils/executionTreeHelper/utils\"\nimport { isFunction, isObject } from \"@/utils/typeHelper\"\nimport { ILLAContextDesc } from \"./ILLAContextDesc\"\n\nconst formatUtils = (data: unknown) => {\n  if (isObject(data)) {\n    return \"#Object#\"\n  } else if (Array.isArray(data)) {\n    return \"#Array#\"\n  } else if (typeof data === \"string\") {\n    return `\"${data.length > 50 ? data.slice(0, 50) + \"...\" : data}\"`\n  } else if (typeof data === \"number\" || typeof data === \"boolean\") {\n    return data\n  } else if (typeof data === \"function\") {\n    return \"#Function#\"\n  } else if (data === null) {\n    return \"null\"\n  } else if (data === undefined) {\n    return \"undefined\"\n  } else {\n    return \"#Unknown#\"\n  }\n}\n\nconst formatEvaluate = (data: any) => {\n  let format = \"\"\n  if (Array.isArray(data)) {\n    if (data.length > 0) {\n      format = \"[<br/>\"\n      data.forEach((item) => {\n        const showStr = formatUtils(item)\n        format += `  ${showStr},<br/>`\n      })\n    } else {\n      format = \"[\"\n    }\n    format += \"]\"\n  }\n  if (isObject(data)) {\n    format = \"Object {<br/>\"\n    Object.keys(data).forEach((key) => {\n      const showStr = formatUtils(data[key])\n      format += `  ${key}: ${showStr},<br/>`\n    })\n    format += \"}\"\n  }\n  return format\n}\n\nexport function getDataInfo(data: Record<string, unknown>, path: string) {\n  let currentData: Record<string, unknown> = data\n  let offset: number = 0\n  let descInfos: Record<string, any> = {}\n  for (let i = 0; i < path.length; i++) {\n    switch (path[i]) {\n      case \".\":\n      case \"[\":\n      case \"]\":\n        if (offset < i) {\n          const currentPath = path.slice(offset, i).trim()\n          currentData = currentData[currentPath] as Record<string, unknown>\n          if (!currentData || !isObject(currentData)) {\n            return null\n          }\n          descInfos = ILLAContextDesc[currentPath] as Record<string, unknown>\n        }\n        offset = i + 1\n        if (path[i] === \".\" && Array.isArray(currentData)) {\n          return null\n        }\n        if (path[i] === \"[\" && !Array.isArray(currentData)) {\n          return null\n        }\n        break\n    }\n  }\n  return {\n    currentData,\n    descInfos,\n    offset,\n    prefix: path.slice(offset),\n  }\n}\n\nexport const buildIllaContextCompletionSource = (\n  canShowCompleteInfo: boolean,\n  codeType: CODE_TYPE,\n  executionResult: Record<string, unknown>,\n): ((\n  context: CompletionContext,\n) => CompletionResult | Promise<CompletionResult | null> | null) => {\n  const isFunction =\n    codeType === CODE_TYPE.FUNCTION || codeType === CODE_TYPE.NO_METHOD_FUNCTION\n\n  if (codeType === CODE_TYPE.FUNCTION) {\n    executionResult = removeIgnoredKeys(executionResult)\n  } else {\n    executionResult = removeIgnoredKeys(\n      removeWidgetOrActionMethods(executionResult),\n    )\n  }\n\n  return (context: CompletionContext) => {\n    const isCursorInDynamicFlag = checkCursorInDynamicFlag(context, isFunction)\n    if (!isCursorInDynamicFlag) {\n      return null\n    }\n    const validString = context.matchBefore(/(\\w+(\\[\\s*\\d+\\s*\\])*\\.)*\\w*/)\n    if (!validString) {\n      return null\n    }\n    if (\n      validString.text.length === 0 &&\n      (isFunction || context.matchBefore(/\\{\\{\\s*/) === null)\n    ) {\n      return null\n    }\n\n    const dataInfo = getDataInfo(executionResult, validString.text)\n    if (!dataInfo) {\n      return null\n    }\n\n    const { currentData, offset, prefix, descInfos } = dataInfo\n    const keys = Object.keys(currentData).filter((key) =>\n      key.startsWith(prefix),\n    )\n\n    const options = keys.map((key) => {\n      const dataType = getDataType(currentData[key])\n      const currentKeyDesc = descInfos?.[key]\n      const result: Completion = {\n        type: dataType,\n        label: key,\n        detail: capitalize(dataType),\n        boost: 1,\n      }\n      if (canShowCompleteInfo) {\n        result.info = () => {\n          let dom = document.createElement(\"span\")\n          dom.innerHTML = `<div class=\"completionInfoCardTitle\">\n        <span class=\"cardTitle\">${key}</span>\n      </div>\n      <p class=\"completionInfoType\">${\n        currentKeyDesc ? currentKeyDesc.usage : dataType\n      }</p>\n      <p class=\"completionInfoEvaluatesTitle\">Evaluates to</p>\n${getDataEvaluatesToDom(currentData[key], dataType)}`\n          return dom\n        }\n      }\n      return result\n    })\n\n    return {\n      from: validString.from + offset,\n      validFor: /^\\w*$/,\n      options: options,\n    }\n  }\n}\n\nfunction getDataType(data: unknown): AutocompleteDataType {\n  const type = typeof data\n  if (type === \"number\") return AutocompleteDataType.NUMBER\n  else if (type === \"string\") return AutocompleteDataType.STRING\n  else if (type === \"boolean\") return AutocompleteDataType.BOOLEAN\n  else if (Array.isArray(data)) return AutocompleteDataType.ARRAY\n  else if (isFunction(data)) return AutocompleteDataType.FUNCTION\n  else if (type === \"undefined\") return AutocompleteDataType.UNKNOWN\n  return AutocompleteDataType.OBJECT\n}\n\nfunction getDataEvaluatesToDom(data: unknown, dataType: AutocompleteDataType) {\n  switch (dataType) {\n    case AutocompleteDataType.STRING:\n      return `<span class=\"evaluatesResult\">\"${data}\"</span>`\n    case AutocompleteDataType.NUMBER:\n    case AutocompleteDataType.BOOLEAN:\n      return `<span class=\"evaluatesResult\">${data}</span>`\n    case AutocompleteDataType.ARRAY:\n      return `<span class=\"evaluatesResult\">[ ... ]${getEvaluatesTooltipDOM(\n        data as unknown[],\n      )}</span>`\n    case AutocompleteDataType.OBJECT:\n      return `<span class=\"evaluatesResult\">{ ... } ${getEvaluatesTooltipDOM(\n        data as Object,\n      )}</span>`\n    default:\n      return `<span class=\"evaluatesResult\">null</span>`\n  }\n}\n\nconst getEvaluatesTooltipDOM = (data: Object | unknown[]) => {\n  return `<div class=\"evaluatesTooltips\">${formatEvaluate(data)}</div>`\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/extensions/heighLightJSExpression.ts",
    "content": "import { Range } from \"@codemirror/state\"\nimport {\n  Decoration,\n  DecorationSet,\n  EditorView,\n  ViewPlugin,\n  ViewUpdate,\n} from \"@codemirror/view\"\nimport { IExpressionShape } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\n\nexport const defaultHighlightClassName = \"cm-default-highlight\"\nexport const errorHighlightClassName = \"cm-error-highlight\"\n\nconst defaultHighlightMark = Decoration.mark({\n  class: defaultHighlightClassName,\n})\nconst errorHighlightMark = Decoration.mark({ class: errorHighlightClassName })\n\nexport function getDecoration(\n  view: EditorView,\n  expressions?: IExpressionShape[],\n) {\n  if (!Array.isArray(expressions) || expressions.length === 0) {\n    return Decoration.none\n  }\n  const value = view.state.doc.toString()\n  if (!value) {\n    return Decoration.none\n  }\n  const ranges: Range<Decoration>[] = []\n  let i = 0\n  expressions.forEach((expression) => {\n    const start = value.indexOf(expression.value, i)\n    if (start >= 0) {\n      i = start + expression.value.length\n      const rang = (\n        expression.hasError ? errorHighlightMark : defaultHighlightMark\n      ).range(start, i)\n      ranges.push(rang)\n    }\n  })\n  return Decoration.set(ranges)\n}\n\nconst getHighlightExtDecorations = (value: {\n  decoration: DecorationSet\n  update: (update: ViewUpdate) => void\n}) => value.decoration\n\nconst getCls = (expressions?: IExpressionShape[]) => {\n  return class {\n    decoration: DecorationSet\n    constructor(view: EditorView) {\n      this.decoration = getDecoration(view, expressions)\n    }\n    update(update: ViewUpdate) {\n      this.decoration = getDecoration(update.view, expressions)\n    }\n  }\n}\nexport const getHighlightExpressionExtension = (\n  expressions?: IExpressionShape[],\n) => {\n  return ViewPlugin.fromClass(getCls(expressions), {\n    decorations: getHighlightExtDecorations,\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/extensions/index.ts",
    "content": "import {\n  CompletionContext,\n  CompletionResult,\n  acceptCompletion,\n  autocompletion,\n  closeBrackets,\n  closeBracketsKeymap,\n  closeCompletion,\n  moveCompletionSelection,\n} from \"@codemirror/autocomplete\"\nimport { defaultKeymap, history, historyKeymap } from \"@codemirror/commands\"\nimport { html, htmlCompletionSource } from \"@codemirror/lang-html\"\nimport { javascript } from \"@codemirror/lang-javascript\"\nimport { json } from \"@codemirror/lang-json\"\nimport {\n  Cassandra,\n  MSSQL,\n  MariaSQL,\n  MySQL,\n  PLSQL,\n  SQLite,\n  StandardSQL,\n  keywordCompletionSource,\n  schemaCompletionSource,\n  sql,\n} from \"@codemirror/lang-sql\"\nimport { xml } from \"@codemirror/lang-xml\"\nimport {\n  bracketMatching,\n  defaultHighlightStyle,\n  indentOnInput,\n  syntaxHighlighting,\n} from \"@codemirror/language\"\nimport { Extension, Prec } from \"@codemirror/state\"\nimport { dropCursor, keymap, lineNumbers, tooltips } from \"@codemirror/view\"\nimport { useMemo } from \"react\"\nimport { ternSeverCompletionSource } from \"@/components/CodeEditor/CodeMirror/extensions/completionSources/TernServer\"\nimport { buildIllaContextCompletionSource } from \"@/components/CodeEditor/CodeMirror/extensions/completionSources/illaContext\"\nimport { getHighlightExpressionExtension } from \"@/components/CodeEditor/CodeMirror/extensions/heighLightJSExpression\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n  ICodeMirrorOptions,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { ILLAEditorRuntimePropsCollectorInstance } from \"@/utils/executionTreeHelper/runtimePropsCollector\"\nimport { isObject } from \"@/utils/typeHelper\"\n\nexport const basicExtension: Extension = [\n  history(),\n  dropCursor(),\n  indentOnInput(),\n  bracketMatching(),\n  closeBrackets(),\n  keymap.of([...closeBracketsKeymap, ...defaultKeymap, ...historyKeymap]),\n]\n\nconst buildSqlSchemeSources = (sqlScheme: Record<string, unknown>) => {\n  const requiredScheme: { [table: string]: string[] } = {}\n  Object.keys(sqlScheme).forEach((tableName) => {\n    if (sqlScheme[tableName] && isObject(sqlScheme[tableName])) {\n      requiredScheme[tableName] = Object.keys(\n        sqlScheme[tableName] as Record<string, unknown>,\n      )\n    }\n  })\n  const completionSourceFunc = schemaCompletionSource({\n    schema: requiredScheme,\n  })\n  return (context: CompletionContext) => {\n    const completionSource = completionSourceFunc(context) as CompletionResult\n    if (Array.isArray(completionSource?.options)) {\n      completionSource.options = completionSource.options.map((option) => {\n        return {\n          ...option,\n          type: \"table\",\n        }\n      })\n    }\n\n    return completionSource\n  }\n}\n\nconst buildSqlKeywordSources = (lang: CODE_LANG) => {\n  switch (lang) {\n    case CODE_LANG.PLSQL: {\n      return keywordCompletionSource(PLSQL)\n    }\n    case CODE_LANG.CASSANDRA: {\n      return keywordCompletionSource(Cassandra)\n    }\n    case CODE_LANG.SQLite: {\n      return keywordCompletionSource(SQLite)\n    }\n    case CODE_LANG.MSSQL: {\n      return keywordCompletionSource(MSSQL)\n    }\n    case CODE_LANG.MARIASQL: {\n      return keywordCompletionSource(MariaSQL)\n    }\n    case CODE_LANG.MYSQL: {\n      return keywordCompletionSource(MySQL)\n    }\n    case CODE_LANG.PGSQL: {\n      return keywordCompletionSource(StandardSQL)\n    }\n    default:\n    case CODE_LANG.SQL: {\n      return keywordCompletionSource(StandardSQL)\n    }\n  }\n}\n\nconst buildCompletionSources = (\n  codeType: CODE_TYPE,\n  lang: CODE_LANG,\n  canShowCompleteInfo: boolean,\n  sqlScheme: Record<string, unknown>,\n  executedResult: Record<string, unknown>,\n) => {\n  const ternSource = ternSeverCompletionSource(canShowCompleteInfo, codeType)\n  const illaSources = buildIllaContextCompletionSource(\n    canShowCompleteInfo,\n    codeType,\n    executedResult,\n  )\n  const completionSources = [ternSource, illaSources]\n\n  switch (lang) {\n    case CODE_LANG.HTML: {\n      completionSources.push(htmlCompletionSource)\n      break\n    }\n    case CODE_LANG.PGSQL:\n    case CODE_LANG.MARIASQL:\n    case CODE_LANG.MSSQL:\n    case CODE_LANG.SQLite:\n    case CODE_LANG.CASSANDRA:\n    case CODE_LANG.PLSQL:\n    case CODE_LANG.MYSQL:\n    case CODE_LANG.SQL: {\n      const sqlKeywordsSources = buildSqlKeywordSources(lang)\n      const sqlSchemeSources = buildSqlSchemeSources(sqlScheme)\n      completionSources.push(sqlKeywordsSources, sqlSchemeSources)\n      break\n    }\n    default: {\n      break\n    }\n  }\n  return completionSources\n}\nconst keyMapExtensions = Prec.highest(\n  keymap.of([\n    { key: \"Escape\", run: closeCompletion },\n    { key: \"ArrowDown\", run: moveCompletionSelection(true) },\n    { key: \"ArrowUp\", run: moveCompletionSelection(false) },\n    { key: \"PageDown\", run: moveCompletionSelection(true, \"page\") },\n    { key: \"PageUp\", run: moveCompletionSelection(false, \"page\") },\n    { key: \"Tab\", run: acceptCompletion },\n    { key: \"Enter\", run: acceptCompletion },\n  ]),\n)\n\nconst getAutoCompletionExtension = (\n  codeType: CODE_TYPE,\n  lang: CODE_LANG,\n  canShowCompleteInfo: boolean,\n  sqlScheme: Record<string, unknown>,\n  executedResult: Record<string, unknown>,\n) => {\n  const completionSources = buildCompletionSources(\n    codeType,\n    lang,\n    canShowCompleteInfo,\n    sqlScheme,\n    executedResult,\n  )\n  return [\n    autocompletion({\n      override: completionSources,\n      defaultKeymap: false,\n      closeOnBlur: false,\n    }),\n    keyMapExtensions,\n  ]\n}\n\nexport const useBasicSetup = (options: ICodeMirrorOptions) => {\n  const {\n    showLineNumbers,\n    lang = CODE_LANG.JAVASCRIPT,\n    codeType = CODE_TYPE.EXPRESSION,\n    canShowCompleteInfo = false,\n    sqlScheme = {},\n    expressions = [],\n    scopeOfAutoComplete = \"global\",\n  } = options\n\n  const executedResult =\n    scopeOfAutoComplete === \"global\"\n      ? ILLAEditorRuntimePropsCollectorInstance.getGlobalCalcContextWithLimit()\n      : ILLAEditorRuntimePropsCollectorInstance.getCurrentPageCalcContext()\n\n  const autocompletionExtension = useMemo(\n    () =>\n      getAutoCompletionExtension(\n        codeType,\n        lang,\n        canShowCompleteInfo,\n        sqlScheme,\n        executedResult,\n      ),\n    [canShowCompleteInfo, codeType, executedResult, lang, sqlScheme],\n  )\n\n  const showLinNUmberExtension = useMemo(\n    () => (showLineNumbers ? [lineNumbers()] : []),\n    [showLineNumbers],\n  )\n\n  const langExtension = useMemo(() => {\n    const plugins: Extension[] = [\n      syntaxHighlighting(defaultHighlightStyle, { fallback: true }),\n    ]\n    switch (lang) {\n      case CODE_LANG.PGSQL:\n      case CODE_LANG.MARIASQL:\n      case CODE_LANG.MSSQL:\n      case CODE_LANG.SQLite:\n      case CODE_LANG.CASSANDRA:\n      case CODE_LANG.PLSQL:\n      case CODE_LANG.MYSQL:\n      case CODE_LANG.SQL: {\n        plugins.push(sql())\n        break\n      }\n      case CODE_LANG.HTML: {\n        plugins.push(html())\n        break\n      }\n      case CODE_LANG.JSON: {\n        plugins.push(json())\n        break\n      }\n      case CODE_LANG.XML: {\n        plugins.push(xml())\n        break\n      }\n      case CODE_LANG.JAVASCRIPT:\n      default: {\n        plugins.push(javascript())\n        break\n      }\n    }\n    return plugins\n  }, [lang])\n\n  const highlightJSExpressionExtension = useMemo(() => {\n    const isFunction = codeType === CODE_TYPE.FUNCTION\n    return isFunction ? [] : getHighlightExpressionExtension(expressions)\n  }, [codeType, expressions])\n\n  const tooltipExtension = useMemo(() => {\n    return tooltips({\n      position: \"absolute\",\n      parent:\n        document.querySelector<HTMLElement>(\".illaCodeMirrorWrapper\") ||\n        document.body,\n    })\n  }, [])\n\n  const extensions = useMemo(\n    () => [\n      basicExtension,\n      showLinNUmberExtension,\n      langExtension,\n      autocompletionExtension,\n      highlightJSExpressionExtension,\n      tooltipExtension,\n    ],\n    [\n      showLinNUmberExtension,\n      langExtension,\n      autocompletionExtension,\n      highlightJSExpressionExtension,\n      tooltipExtension,\n    ],\n  )\n\n  return extensions\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/extensions/interface.ts",
    "content": "export enum CODE_TYPE {\n  \"EXPRESSION\" = \"EXPRESSION\",\n  \"FUNCTION\" = \"FUNCTION\",\n  \"NO_METHOD_FUNCTION\" = \"NO_METHOD_FUNCTION\",\n}\n\nexport enum CODE_LANG {\n  \"JAVASCRIPT\" = \"javascript\",\n  \"SQL\" = \"sql\",\n  \"HTML\" = \"html\",\n  \"JSON\" = \"json\",\n  \"XML\" = \"xml\",\n  \"PGSQL\" = \"pgsql\",\n  \"MYSQL\" = \"mysql\",\n  \"MARIASQL\" = \"mariasql\",\n  \"MSSQL\" = \"mssql\",\n  \"SQLite\" = \"sqlite\",\n  \"CASSANDRA\" = \"cassandra\",\n  \"PLSQL\" = \"plsql\",\n}\n\nexport interface IExpressionShape {\n  value: string\n  hasError: boolean\n}\n\nexport interface ICodeMirrorOptions {\n  showLineNumbers?: boolean\n  lang?: CODE_LANG\n  codeType?: CODE_TYPE\n  expressions?: IExpressionShape[]\n  canShowCompleteInfo?: boolean\n  sqlScheme?: Record<string, unknown>\n  singleLine?: boolean\n  scopeOfAutoComplete?: \"global\" | \"page\"\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/extensions/utils.ts",
    "content": "import { Text } from \"@codemirror/state\"\n\nexport function posToOffset(doc: Text, pos: IPosition) {\n  return doc.line(pos.line + 1).from + pos.character\n}\nexport function offsetToPos(doc: Text, offset: number): Position {\n  const line = doc.lineAt(offset)\n  return new Position(line.number - 1, offset - line.from)\n}\n\nexport interface IPosition {\n  line: number\n  character: number\n  setLine(line: number): void\n  setCharacter(character: number): void\n  lessThanOrEqualTo(position: IPosition): boolean\n}\n\nexport class Position implements IPosition {\n  constructor(public line: number, public character: number) {}\n\n  setLine(line: number) {\n    this.line = line\n  }\n\n  setCharacter(character: number) {\n    this.character = character\n  }\n\n  lessThanOrEqualTo(position: IPosition) {\n    return (\n      this.line < position.line ||\n      (this.line === position.line && this.character <= position.character)\n    )\n  }\n}\n\nconst isMac = () => /mac/i.test(navigator.platform)\nexport const isMetaKeyPressed = (e: MouseEvent) =>\n  isMac() ? e.metaKey : e.ctrlKey\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/interface.ts",
    "content": "import { Extension } from \"@codemirror/state\"\nimport { RefObject } from \"react\"\nimport { ICodeMirrorOptions } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { HintTooltipProps } from \"@/components/CodeEditor/HintToolTip/interface\"\n\nexport interface ILLACodeMirrorProps\n  extends ICodeMirrorOptions,\n    Omit<HintTooltipProps, \"isEditorFocused\" | \"children\"> {\n  extensions?: Extension[]\n  value?: string\n  onChange?: (value: string) => void\n  onFocus?: () => void\n  onBlur?: (value: string) => void\n  height?: string\n  minHeight?: string\n  maxHeight?: string\n  width?: string\n  minWidth?: string\n  maxWidth?: string\n  editable?: boolean\n  readOnly?: boolean\n  placeholder?: string\n  className?: string\n  tooltipContainer?: RefObject<HTMLElement>\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nconst getEditorWrapperBorderColor = (\n  hasError: boolean,\n  isFocused: boolean,\n  isHovered: boolean,\n) => {\n  if (hasError) {\n    return getColor(\"red\", \"03\")\n  }\n  if (isFocused) {\n    return getColor(\"green\", \"03\")\n  }\n  return isHovered ? getColor(\"techPurple\", \"07\") : getColor(\"grayBlue\", \"08\")\n}\nexport const applyEditorWrapperStyle = (\n  hasError: boolean,\n  isFocused: boolean,\n  editable: boolean,\n  readOnly: boolean,\n) => {\n  const hoverStyle =\n    !editable || readOnly\n      ? null\n      : css`\n          :hover {\n            border: 1px solid\n              ${getEditorWrapperBorderColor(hasError, isFocused, true)};\n            z-index: 1;\n          }\n        `\n  return css`\n    width: 100%;\n    height: 100%;\n    .cm-editor {\n      border: 1px solid\n        ${getEditorWrapperBorderColor(hasError, isFocused, false)};\n      border-radius: ${isFocused ? \"8px 8px 0px 0px;\" : \"8px\"};\n      &.cm-focused {\n        z-index: 1;\n      }\n      ${hoverStyle}\n    }\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/CodeMirror/theme.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { githubLightInit } from \"@uiw/codemirror-theme-github/src\"\nimport { getColor } from \"@illa-design/react\"\nimport ArrayIcon from \"@/components/CodeEditor/CodeMirror/assets/array.svg\"\nimport BooleanIcon from \"@/components/CodeEditor/CodeMirror/assets/boolean.svg\"\nimport FunctionIcon from \"@/components/CodeEditor/CodeMirror/assets/function.svg\"\nimport KeywordIcon from \"@/components/CodeEditor/CodeMirror/assets/keyword.svg\"\nimport NullIcon from \"@/components/CodeEditor/CodeMirror/assets/null.svg\"\nimport NumberIcon from \"@/components/CodeEditor/CodeMirror/assets/number.svg\"\nimport ObjectIcon from \"@/components/CodeEditor/CodeMirror/assets/object.svg\"\nimport StringIcon from \"@/components/CodeEditor/CodeMirror/assets/string.svg\"\nimport TableIcon from \"@/components/CodeEditor/CodeMirror/assets/table.svg\"\nimport TypeIcon from \"@/components/CodeEditor/CodeMirror/assets/type.svg\"\nimport UnknownIcon from \"@/components/CodeEditor/CodeMirror/assets/undefine.svg\"\nimport {\n  defaultHighlightClassName,\n  errorHighlightClassName,\n} from \"@/components/CodeEditor/CodeMirror/extensions/heighLightJSExpression\"\n\nexport const ILLACodeMirrorTheme = {\n  \"&.cm-editor\": {\n    borderRadius: \"8px\",\n    border: `1px solid ${getColor(\"grayBlue\", \"03\")}`,\n    overflow: \"hidden\",\n    fontFamily: \"Fira Code\",\n  },\n  \"&.cm-editor .cm-scroller\": {\n    lineHeight: \"22px\",\n    fontSize: \"12px\",\n  },\n  \"&.cm-editor .cm-content\": {\n    padding: \"4px 0\",\n  },\n  \"&.cm-editor .cm-line\": {\n    padding: \"0 16px\",\n  },\n  \"&.cm-editor.cm-focused .cm-matchingBracket\": {\n    color: getColor(\"green\", \"03\"),\n  },\n  \"&.cm-editor .cm-placeholder\": {\n    color: getColor(\"grayBlue\", \"04\"),\n    height: 0,\n  },\n  \"&.cm-editor .cm-gutters .cm-gutter .cm-gutterElement\": {\n    padding: \"0 8px 0 23px\",\n  },\n  \"&.cm-editor .cm-gutters\": {\n    borderRadius: \"8px 0 0 8px\",\n    borderRight: \"none\",\n  },\n  [`.${defaultHighlightClassName}`]: {\n    color: getColor(\"green\", \"03\"),\n    backgroundColor: \"rgba(0, 170, 91, 0.08);\",\n  },\n  [`.${errorHighlightClassName}`]: {\n    color: getColor(\"red\", \"03\"),\n    backgroundColor: \"rgba(255, 71, 71, 0.08);\",\n  },\n}\n\nexport const illaCodeMirrorTooltipStyle = css`\n  > div {\n    height: unset;\n    min-height: unset;\n  }\n  .cm-tooltip {\n    &.cm-tooltip-autocomplete {\n      border: none;\n      > ul {\n        background-color: ${getColor(\"white\", \"01\")};\n        border: 1px solid ${getColor(\"greyBlue\", \"08\")};\n        box-shadow: 0 2px 16px rgba(0, 0, 0, 0.16);\n        border-radius: 8px;\n        font-family: \"Fira Code\", monospace;\n        li {\n          height: 24px;\n          line-height: 24px;\n          position: relative;\n          overflow: hidden;\n          &[aria-selected] {\n            background-color: ${getColor(\"techPurple\", \"08\")};\n            color: ${getColor(\"techPurple\", \"03\")};\n          }\n          .cm-completionIcon {\n            width: 14px;\n            height: 14px;\n            font-size: 14px;\n            opacity: 1;\n            padding-right: 8px;\n            position: absolute;\n            top: 2.5px;\n          }\n          .cm-completionIcon-Function::after {\n            content: url(${FunctionIcon});\n          }\n          .cm-completionIcon-Number::after {\n            content: url(${NumberIcon});\n          }\n          .cm-completionIcon-String::after {\n            content: url(${StringIcon});\n          }\n          .cm-completionIcon-Boolean::after {\n            content: url(${BooleanIcon});\n          }\n          .cm-completionIcon-Null::after {\n            content: url(${NullIcon});\n          }\n          .cm-completionIcon-Object::after {\n            content: url(${ObjectIcon});\n          }\n          .cm-completionIcon-Array::after {\n            content: url(${ArrayIcon});\n          }\n          .cm-completionIcon-Unknown::after {\n            content: url(${UnknownIcon});\n          }\n          .cm-completionIcon-keyword::after {\n            content: url(${KeywordIcon});\n          }\n          .cm-completionIcon-type::after {\n            content: url(${TypeIcon});\n          }\n          .cm-completionIcon-table::after {\n            content: url(${TableIcon});\n          }\n          .cm-completionLabel {\n            font-size: 12px;\n            line-height: 22px;\n            position: absolute;\n            left: 25px;\n            top: 2px;\n            .cm-completionMatchedText {\n              font-weight: 600;\n              text-decoration: none;\n            }\n          }\n          .cm-completionDetail {\n            position: absolute;\n            right: 8px;\n            top: 2px;\n            margin: 0;\n            color: ${getColor(\"grayBlue\", \"04\")};\n            font-size: 12px;\n            line-height: 22px;\n            font-style: normal;\n          }\n        }\n      }\n      .cm-completionInfo {\n        padding: 4px 8px;\n        background-color: ${getColor(\"white\", \"01\")};\n        border: 1px solid ${getColor(\"greyBlue\", \"08\")};\n        box-shadow: 0 2px 16px rgba(0, 0, 0, 0.16);\n        border-radius: 8px;\n        width: 287px;\n        &.cm-completionInfo-right {\n          left: calc(100% + 8px);\n        }\n        .completionInfoCardTitle {\n          display: flex;\n          justify-content: space-between;\n          align-items: center;\n          .cardTitle {\n            width: 100%;\n            font-weight: 500;\n            font-size: 12px;\n            line-height: 20px;\n            color: ${getColor(\"techPurple\", \"03\")};\n          }\n          .openInfo {\n            width: 12px;\n            height: 12px;\n            display: flex;\n            align-items: center;\n          }\n        }\n        .completionInfoType {\n          font-size: 12px;\n          color: ${getColor(\"grayBlue\", \"02\")};\n          margin: 0;\n          line-height: 20px;\n          word-break: break-all;\n        }\n        .completionInfoEvaluatesTitle {\n          font-size: 12px;\n          color: ${getColor(\"grayBlue\", \"02\")};\n          margin: 0;\n          font-weight: 500;\n          line-height: 20px;\n        }\n        .completionInfoDoc {\n          font-size: 12px;\n          color: ${getColor(\"grayBlue\", \"04\")};\n          margin: 0;\n          line-height: 20px;\n        }\n        .evaluatesResult {\n          display: inline-block;\n          margin: 0;\n          padding: 0 8px;\n          font-size: 12px;\n          line-height: 18px;\n          color: ${getColor(\"grayBlue\", \"02\")};\n          background-color: ${getColor(\"grayBlue\", \"09\")};\n          position: relative;\n          cursor: pointer;\n          :hover {\n            .evaluatesTooltips {\n              visibility: visible;\n            }\n          }\n          .evaluatesTooltips {\n            visibility: hidden;\n            font-family: \"Fira Code\", monospace;\n            position: absolute;\n            left: calc(100% + 4px);\n            top: -50%;\n            max-height: 162px;\n            border-radius: 4px;\n            box-shadow: 0 2px 16px rgba(0, 0, 0, 0.16);\n            background-color: ${getColor(\"grayBlue\", \"01\")};\n            padding: 12px 16px;\n            font-size: 14px;\n            line-height: 18px;\n            color: ${getColor(\"white\", \"01\")};\n            white-space: pre;\n            overflow-y: auto;\n            cursor: auto;\n          }\n        }\n      }\n    }\n  }\n`\n\nexport const githubLightScheme = githubLightInit({\n  settings: {\n    background: \"#fff\",\n    foreground: \"#24292e\",\n    gutterBackground: getColor(\"grayBlue\", \"09\"),\n  },\n})\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/HintToolTip/index.tsx",
    "content": "import copy from \"copy-to-clipboard\"\nimport { FC, useCallback, useState } from \"react\"\nimport { CopyIcon, ErrorIcon, Trigger } from \"@illa-design/react\"\nimport {\n  HintTooltipContentProps,\n  HintTooltipProps,\n} from \"@/components/CodeEditor/HintToolTip/interface\"\nimport {\n  applyHintTooltipContentMainWrapperStyle,\n  applyHintTooltipContentWrapperStyle,\n  copyIconStyle,\n  hintTooltipContentTitleStyle,\n  hintTooltipContentTitleWrapperStyle,\n  hintTooltipResultStyle,\n} from \"@/components/CodeEditor/HintToolTip/style\"\n\nexport const HintTooltipContent: FC<HintTooltipContentProps> = (props) => {\n  const { hasError = false, resultType, result, setIsHovered } = props\n\n  const handleClickCopy = useCallback(() => {\n    if (result) {\n      copy(result)\n    }\n  }, [result])\n\n  return (\n    <div\n      css={applyHintTooltipContentWrapperStyle(hasError)}\n      onMouseEnter={() => {\n        setIsHovered(true)\n      }}\n      onMouseLeave={() => {\n        setIsHovered(false)\n      }}\n    >\n      <div css={applyHintTooltipContentMainWrapperStyle(hasError)}>\n        <div css={hintTooltipContentTitleWrapperStyle}>\n          {hasError && <ErrorIcon size=\"12px\" />}\n          <span css={hintTooltipContentTitleStyle}>\n            {hasError ? \"Error\" : resultType}\n          </span>\n        </div>\n        <span css={hintTooltipResultStyle}>{result}</span>\n      </div>\n      <CopyIcon css={copyIconStyle} onClick={handleClickCopy} />\n    </div>\n  )\n}\n\nexport const HintToolTip: FC<HintTooltipProps> = (props) => {\n  const {\n    isEditorFocused,\n    result,\n    hasError,\n    resultType,\n    children,\n    toolTipContainer,\n  } = props\n  const [isHovered, setIsHovered] = useState(false)\n\n  return (\n    <Trigger\n      withoutPadding\n      withoutOffset\n      withoutShadow\n      autoAlignPopupWidth\n      showArrow={false}\n      popupVisible={isEditorFocused || isHovered}\n      position=\"bottom-start\"\n      colorScheme=\"white\"\n      popupContainer={toolTipContainer}\n      content={\n        <HintTooltipContent\n          hasError={hasError}\n          resultType={resultType}\n          result={result}\n          setIsHovered={setIsHovered}\n        />\n      }\n    >\n      {children}\n    </Trigger>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/HintToolTip/interface.ts",
    "content": "import { Dispatch, ReactNode, RefObject, SetStateAction } from \"react\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface HintTooltipProps {\n  isEditorFocused: boolean\n  hasError?: boolean\n  resultType?: VALIDATION_TYPES\n  result?: string\n  children: ReactNode\n  toolTipContainer?: RefObject<HTMLElement>\n}\n\nexport interface HintTooltipContentProps\n  extends Pick<HintTooltipProps, \"hasError\" | \"resultType\" | \"result\"> {\n  setIsHovered: Dispatch<SetStateAction<boolean>>\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/HintToolTip/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const applyHintTooltipContentWrapperStyle = (hasError: boolean) => css`\n  display: flex;\n  width: 100%;\n  padding: 4px 0;\n  border-radius: 0 0 8px 8px;\n  font-family: \"fira code\", monospace;\n  background-color: ${hasError\n    ? getColor(\"red\", \"08\")\n    : getColor(\"green\", \"08\")};\n`\n\nexport const applyHintTooltipContentMainWrapperStyle = (\n  hasError: boolean,\n) => css`\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  color: ${hasError ? getColor(\"red\", \"03\") : getColor(\"green\", \"03\")};\n  flex: 9;\n`\n\nexport const hintTooltipContentTitleWrapperStyle = css`\n  gap: 4px;\n  align-items: center;\n  padding: 0 8px;\n  position: relative;\n`\nexport const hintTooltipContentTitleStyle = css`\n  font-size: 14px;\n  font-weight: 600;\n  line-height: 22px;\n`\n\nexport const hintTooltipResultStyle = css`\n  word-break: break-all;\n  max-height: 150px;\n  overflow: auto;\n  padding: 0 8px;\n`\n\nexport const copyIconStyle = css`\n  cursor: pointer;\n  position: absolute;\n  top: 4px;\n  right: 4px;\n`\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/ModalCodeMirror/content.tsx",
    "content": "import { FC } from \"react\"\nimport useMeasure from \"react-use-measure\"\nimport { getColor } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { ModalBodyContent } from \"@/components/CodeEditor/ModalCodeMirror/interface\"\nimport {\n  applyCodeMirrorWrapperStyle,\n  codeMirrorContainerStyle,\n  contentWrapperStyle,\n  descriptionStyle,\n} from \"@/components/CodeEditor/ModalCodeMirror/style\"\nimport { ILLAMarkdown } from \"@/components/ILLAMarkdown\"\n\nexport const ModalContent: FC<ModalBodyContent> = (props) => {\n  const {\n    description,\n    lang,\n    expectValueType,\n    onChange,\n    value,\n    placeholder,\n    wrappedCodeFunc,\n    scopeOfAutoComplete,\n    codeType,\n  } = props\n\n  const [ref, rect] = useMeasure()\n\n  return (\n    <div css={contentWrapperStyle}>\n      {description && (\n        <div css={descriptionStyle} ref={ref}>\n          <ILLAMarkdown\n            textString={description}\n            textColor={getColor(\"grayBlue\", \"04\")}\n            urlColor=\"grayBlue\"\n          />\n        </div>\n      )}\n      <div css={applyCodeMirrorWrapperStyle(rect.height)}>\n        <CodeEditor\n          placeholder={placeholder}\n          showLineNumbers\n          height=\"100%\"\n          minHeight=\"88px\"\n          maxHeight=\"100%\"\n          value={value}\n          lang={lang}\n          canShowCompleteInfo\n          expectValueType={expectValueType}\n          wrapperCss={codeMirrorContainerStyle}\n          onChange={onChange}\n          canExpand={false}\n          wrappedCodeFunc={wrappedCodeFunc}\n          scopeOfAutoComplete={scopeOfAutoComplete}\n          codeType={codeType}\n        />\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/ModalCodeMirror/footer.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button } from \"@illa-design/react\"\nimport { FooterContentProps } from \"@/components/CodeEditor/ModalCodeMirror/interface\"\nimport { saveButtonStyle } from \"@/components/CodeEditor/ModalCodeMirror/style\"\n\nexport const FooterContent: FC<FooterContentProps> = (props) => {\n  const { t } = useTranslation()\n  const { onClickSaveButton } = props\n  return (\n    <Button\n      colorScheme=\"techPurple\"\n      onClick={onClickSaveButton}\n      _css={saveButtonStyle}\n    >\n      {t(\"save\")}\n    </Button>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/ModalCodeMirror/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { ModalContent } from \"@/components/CodeEditor/ModalCodeMirror/content\"\nimport { FooterContent } from \"@/components/CodeEditor/ModalCodeMirror/footer\"\nimport { ModalCodeMirrorProps } from \"@/components/CodeEditor/ModalCodeMirror/interface\"\nimport { MovableModal } from \"@/components/Modal/movableModal\"\n\nexport const ModalCodeMirror: FC<ModalCodeMirrorProps> = (props) => {\n  const {\n    title,\n    value,\n    description,\n    lang,\n    expectValueType,\n    codeType,\n    onChange,\n    onClickSaveButton,\n    onClose,\n    placeholder,\n    scopeOfAutoComplete,\n    wrappedCodeFunc,\n    onBlur,\n    onFocus,\n  } = props\n  const { t } = useTranslation()\n\n  return (\n    <MovableModal\n      title={title || t(\"editor.inspect.setter_label.code.write_code\")}\n      bodyContent={\n        <ModalContent\n          description={\n            description ||\n            t(\"editor.inspect.setter_description.code.write_code\")\n          }\n          lang={lang}\n          expectValueType={expectValueType}\n          value={value}\n          onChange={onChange}\n          placeholder={placeholder}\n          wrappedCodeFunc={wrappedCodeFunc}\n          onBlur={onBlur}\n          onFocus={onFocus}\n          scopeOfAutoComplete={scopeOfAutoComplete}\n          codeType={codeType}\n        />\n      }\n      footerContent={\n        onClickSaveButton ? (\n          <FooterContent onClickSaveButton={onClickSaveButton} />\n        ) : null\n      }\n      onClose={onClose}\n    />\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/ModalCodeMirror/interface.ts",
    "content": "import { CodeEditorProps } from \"@/components/CodeEditor/interface\"\nimport { MovableModalProps } from \"@/components/Modal/interface\"\n\nexport interface ModalBodyContent {\n  description?: string\n  placeholder?: string\n  lang?: CodeEditorProps[\"lang\"]\n  expectValueType?: CodeEditorProps[\"expectValueType\"]\n  scopeOfAutoComplete?: CodeEditorProps[\"scopeOfAutoComplete\"]\n  onChange?: CodeEditorProps[\"onChange\"]\n  wrappedCodeFunc?: CodeEditorProps[\"wrappedCodeFunc\"]\n  onFocus?: CodeEditorProps[\"onFocus\"]\n  onBlur?: CodeEditorProps[\"onBlur\"]\n  value: string\n  codeType?: CodeEditorProps[\"codeType\"]\n}\n\nexport interface FooterContentProps {\n  onClickSaveButton: () => void\n}\n\nexport interface ModalCodeMirrorProps\n  extends Omit<MovableModalProps, \"bodyContent\" | \"footerContent\">,\n    ModalBodyContent {\n  onClickSaveButton?: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/ModalCodeMirror/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const descriptionStyle = css`\n  font-size: 14px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-weight: 400;\n  line-height: 22px;\n  margin: 0;\n`\n\nexport const applyCodeMirrorWrapperStyle = (desHeight: number) => css`\n  width: 100%;\n  height: max(88px, calc(100% - ${desHeight}px - 16px));\n`\n\nexport const codeMirrorContainerStyle = css`\n  height: 100%;\n`\n\nexport const saveButtonStyle = css`\n  position: absolute;\n  right: 16px;\n`\n\nexport const contentWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/index.tsx",
    "content": "import {\n  getStringSnippets,\n  isDynamicStringSnippet,\n} from \"@illa-public/dynamic-string\"\nimport { debounce } from \"lodash-es\"\nimport { FC, useCallback, useMemo, useRef, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport OpenWindowIcon from \"@/assets/public/openWindow.svg?react\"\nimport { ILLACodeMirrorCore } from \"@/components/CodeEditor/CodeMirror/core\"\nimport {\n  CODE_TYPE,\n  IExpressionShape,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { githubLightScheme } from \"@/components/CodeEditor/CodeMirror/theme\"\nimport { ModalCodeMirror } from \"@/components/CodeEditor/ModalCodeMirror\"\nimport { CodeEditorProps } from \"@/components/CodeEditor/interface\"\nimport {\n  ILLACodeMirrorWrapperStyle,\n  openWindowIconHotspotStyle,\n} from \"@/components/CodeEditor/style\"\nimport i18n from \"@/i18n/config\"\nimport {\n  getExecutionResultToCurrentPageCodeMirror,\n  getExecutionResultToGlobalCodeMirror,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { LIMIT_MEMORY, estimateMemoryUsage } from \"@/utils/calculateMemoryUsage\"\nimport { evaluateDynamicString } from \"@/utils/evaluateDynamicString\"\nimport {\n  removeIgnoredKeys,\n  removeWidgetOrActionMethods,\n} from \"@/utils/executionTreeHelper/utils\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { fixedValue } from \"./utils\"\n\nconst getResultType = (result: unknown) => {\n  if (Array.isArray(result)) {\n    return VALIDATION_TYPES.ARRAY\n  } else if (typeof result === \"string\") {\n    return VALIDATION_TYPES.STRING\n  } else if (typeof result === \"number\") {\n    return VALIDATION_TYPES.NUMBER\n  } else if (typeof result === \"boolean\") {\n    return VALIDATION_TYPES.BOOLEAN\n  } else if (typeof result === \"undefined\") {\n    return VALIDATION_TYPES.UNDEFINED\n  } else {\n    return VALIDATION_TYPES.OBJECT\n  }\n}\n\nconst getShowResultType = (results: unknown[]) => {\n  if (results.length === 0) {\n    return VALIDATION_TYPES.STRING\n  }\n  if (results.length === 1) {\n    return getResultType(results[0])\n  } else {\n    return VALIDATION_TYPES.STRING\n  }\n}\n\nconst getShowResult = (results: unknown[]) => {\n  let calcResult: string = \"\"\n  if (results.length === 0) {\n    return \"\"\n  } else {\n    const memorySize = estimateMemoryUsage(results)\n    if (LIMIT_MEMORY < memorySize) {\n      return i18n.t(\"editor.global.size_exceed\", {\n        current_size: memorySize,\n        limit_size: LIMIT_MEMORY,\n      })\n    }\n    results.forEach((result) => {\n      if (\n        typeof result === \"string\" ||\n        typeof result === \"number\" ||\n        typeof result === \"boolean\"\n      ) {\n        calcResult += result\n      } else if (result == undefined) {\n        calcResult += result\n      } else {\n        calcResult += JSON.stringify(result)\n      }\n    })\n  }\n  return calcResult\n}\n\nexport const MAX_LEN_WITH_SNIPPETS = 1024\n\nexport const CodeEditor: FC<CodeEditorProps> = (props) => {\n  const {\n    value = \"\",\n    modalTitle = \"\",\n    modalDescription,\n    onChange = () => {},\n    showLineNumbers,\n    placeholder,\n    lang,\n    sqlScheme,\n    width,\n    maxWidth,\n    height,\n    maxHeight,\n    editable = true,\n    readOnly,\n    extensions,\n    expectValueType,\n    codeType = CODE_TYPE.EXPRESSION,\n    minWidth,\n    minHeight,\n    canShowCompleteInfo,\n    wrapperCss,\n    singleLine,\n    canExpand = true,\n    scopeOfAutoComplete = \"global\",\n    wrappedCodeFunc,\n    onBlur = () => {},\n    onFocus = () => {},\n    className,\n  } = props\n  const [result, setResult] = useState<string>(\"\")\n  const [error, setError] = useState<boolean>(false)\n  const [resultType, setResultType] = useState(VALIDATION_TYPES.STRING)\n  const [isExpanded, setIsExpanded] = useState(false)\n  const popupContainerRef = useRef<HTMLDivElement>(null)\n  const innerCanExpand = canExpand && !readOnly && editable\n\n  const tmpCalcContext = useSelector<RootState, Record<string, unknown>>(\n    (rootState) => {\n      return scopeOfAutoComplete === \"global\"\n        ? getExecutionResultToGlobalCodeMirror(rootState)\n        : getExecutionResultToCurrentPageCodeMirror(rootState)\n    },\n  )\n  const calcContext = useMemo(() => {\n    if (codeType === CODE_TYPE.FUNCTION) {\n      return removeIgnoredKeys(tmpCalcContext)\n    } else {\n      return removeIgnoredKeys(removeWidgetOrActionMethods(tmpCalcContext))\n    }\n  }, [codeType, tmpCalcContext])\n\n  const stringSnippets = useMemo(() => {\n    const result: IExpressionShape[] = []\n    const realInput = wrappedCodeFunc ? wrappedCodeFunc(value) : value\n    const dynamicStrings = getStringSnippets(realInput)\n    const errors: string[] = []\n    const calcResultArray: unknown[] = []\n    const calcResultMap: Map<string, number[]> = new Map()\n    dynamicStrings.forEach((dynamicString, index) => {\n      if (isDynamicStringSnippet(dynamicString)) {\n        try {\n          const calcRes = evaluateDynamicString(\"\", dynamicString, calcContext)\n          calcResultArray.push(calcRes)\n          const res = { value: dynamicString, hasError: false }\n          result.push(res)\n          if (calcResultMap.has(dynamicString)) {\n            calcResultMap.get(dynamicString)?.push(index)\n          } else {\n            calcResultMap.set(dynamicString, [index])\n          }\n        } catch (e) {\n          errors.push((e as Error).message)\n          const res = { value: dynamicString, hasError: true }\n          result.push(res)\n          if (calcResultMap.has(dynamicString)) {\n            calcResultMap.get(dynamicString)?.push(index)\n          } else {\n            calcResultMap.set(dynamicString, [index])\n          }\n        }\n      } else {\n        calcResultArray.push(dynamicString)\n      }\n    })\n    if (errors.length > 0) {\n      setError(true)\n      setResult(errors[0])\n      return result\n    }\n    const showResult = getShowResult(calcResultArray)\n    const showResultType = getShowResultType(calcResultArray)\n    setError(false)\n    if (expectValueType) {\n      setResultType(expectValueType)\n      if (showResultType !== expectValueType && value) {\n        dynamicStrings.forEach((dynamicString) => {\n          if (\n            dynamicString.length <= MAX_LEN_WITH_SNIPPETS &&\n            isDynamicStringSnippet(dynamicString) &&\n            calcResultMap.has(dynamicString)\n          ) {\n            const indexs = calcResultMap.get(dynamicString)\n            indexs?.forEach((index) => {\n              if (result[index]) {\n                result[index].hasError = true\n              }\n            })\n          }\n        })\n\n        setResult(`Expect ${expectValueType}, but got ${showResultType}`)\n        setError(true)\n      } else {\n        setResult(\n          showResult.length > MAX_LEN_WITH_SNIPPETS\n            ? showResult.slice(0, MAX_LEN_WITH_SNIPPETS) + \"...\"\n            : showResult,\n        )\n      }\n    } else {\n      setResultType(showResultType)\n      setResult(\n        showResult.length > MAX_LEN_WITH_SNIPPETS\n          ? showResult.slice(0, MAX_LEN_WITH_SNIPPETS) + \"...\"\n          : showResult,\n      )\n    }\n    return result\n  }, [wrappedCodeFunc, value, expectValueType, calcContext])\n\n  const debounceHandleChange = useMemo(() => {\n    return debounce(onChange, 160)\n  }, [onChange])\n\n  const customExtensions = useMemo(\n    () => (extensions ? [extensions, githubLightScheme] : [githubLightScheme]),\n    [extensions],\n  )\n\n  const handleOpenExpandModal = useCallback(() => {\n    setIsExpanded(true)\n  }, [])\n\n  const handleCloseExpandModal = useCallback(() => {\n    setIsExpanded(false)\n  }, [])\n\n  return (\n    <div css={[ILLACodeMirrorWrapperStyle, wrapperCss]} ref={popupContainerRef}>\n      <ILLACodeMirrorCore\n        className={className}\n        showLineNumbers={showLineNumbers}\n        placeholder={placeholder}\n        value={fixedValue(value)}\n        onChange={debounceHandleChange}\n        lang={lang}\n        expressions={stringSnippets}\n        result={result}\n        hasError={error}\n        resultType={resultType}\n        width={width}\n        maxWidth={maxWidth}\n        height={height}\n        maxHeight={maxHeight}\n        editable={editable}\n        readOnly={readOnly}\n        codeType={codeType}\n        extensions={customExtensions}\n        minWidth={minWidth}\n        minHeight={minHeight}\n        canShowCompleteInfo={canShowCompleteInfo}\n        sqlScheme={sqlScheme}\n        singleLine={singleLine}\n        tooltipContainer={popupContainerRef ?? undefined}\n        scopeOfAutoComplete={scopeOfAutoComplete}\n        onBlur={onBlur}\n        onFocus={onFocus}\n      />\n      {innerCanExpand && (\n        <div\n          css={openWindowIconHotspotStyle}\n          className=\"open-window-icon-hotspot\"\n          onClick={handleOpenExpandModal}\n        >\n          <OpenWindowIcon />\n        </div>\n      )}\n      {isExpanded && (\n        <ModalCodeMirror\n          title={modalTitle}\n          onClose={handleCloseExpandModal}\n          value={fixedValue(value)}\n          onChange={onChange}\n          expectValueType={expectValueType}\n          lang={lang}\n          description={modalDescription}\n          placeholder={placeholder}\n          wrappedCodeFunc={wrappedCodeFunc}\n          onBlur={onBlur}\n          onFocus={onFocus}\n          scopeOfAutoComplete={scopeOfAutoComplete}\n          codeType={codeType}\n        />\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/interface.ts",
    "content": "import { SerializedStyles } from \"@emotion/react\"\nimport { ILLACodeMirrorProps } from \"@/components/CodeEditor/CodeMirror/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface CodeEditorProps\n  extends Omit<\n    ILLACodeMirrorProps,\n    | \"hasError\"\n    | \"resultType\"\n    | \"result\"\n    | \"executionResult\"\n    | \"expressions\"\n    | \"canShowResultRealtime\"\n  > {\n  expectValueType?: VALIDATION_TYPES\n  wrappedCodeFunc?: (value: string) => string\n  canExpand?: boolean\n  modalTitle?: string\n  modalDescription?: string\n  wrapperCss?: SerializedStyles\n}\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const ILLACodeMirrorWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  position: relative;\n  :hover {\n    .open-window-icon-hotspot {\n      visibility: visible;\n    }\n  }\n`\n\nexport const openWindowIconHotspotStyle = css`\n  position: absolute;\n  z-index: 10;\n  right: 2px;\n  bottom: 2px;\n  width: 16px;\n  height: 16px;\n  cursor: pointer;\n  font-size: 12px;\n  background-color: ${getColor(\"grayBlue\", \"09\")};\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  border-radius: 2px 2px 6px 2px;\n  visibility: hidden;\n`\n"
  },
  {
    "path": "apps/builder/src/components/CodeEditor/utils.ts",
    "content": "export const fixedValue = (value: unknown) => {\n  if (value == undefined) return \"\"\n  if (typeof value === \"string\") return value\n  return `{{${JSON.stringify(value)}}}`\n}\n"
  },
  {
    "path": "apps/builder/src/components/ColorPicker/constants.ts",
    "content": "import { getSpecialThemeColor } from \"@illa-design/react\"\n\nexport const colorSchemes = [\n  \"white\",\n  \"grayBlue\",\n  \"red\",\n  \"orange\",\n  \"yellow\",\n  \"green\",\n  \"blue\",\n  \"cyan\",\n  \"purple\",\n]\n\n// for old app\nexport const deletedColorSchemes = [\"transparent\", \"blackAlpha\"]\n\nexport const COLOR_MAP = (() => {\n  const m = new Map<string, string>()\n  colorSchemes.forEach((color) => {\n    m.set(getSpecialThemeColor(color), color)\n  })\n  return m\n})()\n\nexport const PRE_COLOR = colorSchemes.map((color) => {\n  return {\n    title: color,\n    color: getSpecialThemeColor(color),\n  }\n})\n"
  },
  {
    "path": "apps/builder/src/components/ColorPicker/index.tsx",
    "content": "import Sketch from \"@uiw/react-color-sketch\"\nimport { FC } from \"react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\nimport { COLOR_MAP, PRE_COLOR, colorSchemes } from \"./constants\"\nimport { ColorPickerProps } from \"./interface\"\n\nexport const ColorPicker: FC<ColorPickerProps> = (props) => {\n  const { onChange, selectedColor, disableAlpha } = props\n\n  let c = selectedColor\n  if (colorSchemes.includes(selectedColor)) {\n    c = getSpecialThemeColor(selectedColor)\n  }\n\n  return (\n    <Sketch\n      color={c}\n      presetColors={PRE_COLOR}\n      disableAlpha={disableAlpha}\n      onChange={(color) => {\n        if (COLOR_MAP.has(color.hexa) || COLOR_MAP.has(color.hex)) {\n          onChange(COLOR_MAP.get(color.hex) || COLOR_MAP.get(color.hexa)!!)\n        } else {\n          onChange(color.hexa)\n        }\n      }}\n    />\n  )\n}\nColorPicker.displayName = \"ColorPicker\"\n"
  },
  {
    "path": "apps/builder/src/components/ColorPicker/interface.ts",
    "content": "export interface ColorPickerProps {\n  selectedColor: string\n  onChange: (color: string) => void\n  disableAlpha?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/components/ColorSetter/index.tsx",
    "content": "import { hexToHsva } from \"@uiw/color-convert\"\nimport { debounce } from \"lodash-es\"\nimport { FC, useRef } from \"react\"\nimport { BindIcon, Trigger, getSpecialThemeColor } from \"@illa-design/react\"\nimport { ColorPicker } from \"@/components/ColorPicker\"\nimport {\n  colorSchemes,\n  deletedColorSchemes,\n} from \"@/components/ColorPicker/constants\"\nimport { ColorPickerSetterProps } from \"./interface\"\nimport {\n  alphaContentStyle,\n  applyCircleStyle,\n  buttonContentWrapperStyle,\n  circleHotSpotStyle,\n  colorContentStyle,\n  colorTipAndValueContainerStyle,\n} from \"./style\"\n\nconst ColorPickerSetter: FC<ColorPickerSetterProps> = (props) => {\n  const { handleUpdateColor, value, setterSize = \"small\" } = props\n  const currentColor = useRef<string>(value)\n  const debounceOnChange = debounce(handleUpdateColor, 300)\n\n  let c = value\n  let isInnerColorScheme = false\n  if (colorSchemes.includes(value)) {\n    isInnerColorScheme = true\n    c = getSpecialThemeColor(value)\n  }\n\n  const showBindIcon = isInnerColorScheme || deletedColorSchemes.includes(value)\n  return (\n    <Trigger\n      trigger=\"click\"\n      withoutPadding\n      clickOutsideToClose\n      position=\"bottom-end\"\n      colorScheme=\"white\"\n      content={\n        <ColorPicker\n          selectedColor={value}\n          onChange={(color) => {\n            currentColor.current = color\n            debounceOnChange(color)\n          }}\n        />\n      }\n    >\n      <div css={buttonContentWrapperStyle(setterSize)}>\n        <div css={colorTipAndValueContainerStyle}>\n          <div css={circleHotSpotStyle}>\n            <div css={applyCircleStyle(c)} />\n          </div>\n          <span css={colorContentStyle}>\n            {value?.includes(\"#\")\n              ? value?.toLocaleUpperCase().slice(0, -2)\n              : value}\n          </span>\n        </div>\n        {showBindIcon ? (\n          <BindIcon />\n        ) : (\n          <span css={alphaContentStyle}>\n            {parseInt(`${hexToHsva(c || \"#fff\").a * 100}`)}%\n          </span>\n        )}\n      </div>\n    </Trigger>\n  )\n}\n\nColorPickerSetter.displayName = \"ColorPickerSetter\"\n\nexport default ColorPickerSetter\n"
  },
  {
    "path": "apps/builder/src/components/ColorSetter/interface.tsx",
    "content": "export interface ColorPickerSetterProps {\n  value: string\n  handleUpdateColor: (color: string) => void\n  setterSize?: \"small\" | \"medium\"\n}\n"
  },
  {
    "path": "apps/builder/src/components/ColorSetter/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\nimport alpha from \"@/assets/alpha.svg\"\n\nexport const circleHotSpotStyle = css`\n  width: 24px;\n  height: 24px;\n  padding: 4px;\n  display: flex;\n  align-items: center;\n`\n\nexport function applyCircleStyle(color: string): SerializedStyles {\n  return css`\n    &::after {\n      content: \"\";\n      display: inline-block;\n      background-color: ${color};\n      width: 16px;\n      height: 16px;\n    }\n\n    background-image: url(${alpha});\n    width: 16px;\n    height: 16px;\n    border-radius: 50%;\n    border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n    overflow: hidden;\n    flex: none;\n  `\n}\n\nexport const colorTipAndValueContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const buttonContentWrapperStyle = (\n  setterSize: \"small\" | \"medium\",\n) => css`\n  display: flex;\n  width: ${setterSize === \"medium\" ? \"182px\" : \"170px\"};\n  cursor: pointer;\n  align-items: center;\n  border-radius: 8px;\n  padding: 3px 12px 3px 12px;\n  justify-content: space-between;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n\n  :hover {\n    background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  }\n\n  :active {\n    background-color: ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  }\n`\n\nexport const colorContentStyle = css`\n  text-align: left;\n  font-size: 12px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  align-self: center;\n  line-height: 24px;\n  flex: none;\n`\n\nexport const alphaContentStyle = css`\n  font-size: 12px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  align-self: center;\n  line-height: 24px;\n  flex: none;\n`\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/components/Breadcrumb/index.tsx",
    "content": "import { FC, useCallback, useContext, useMemo } from \"react\"\nimport { Breadcrumb, BreadcrumbItem } from \"@illa-design/react\"\nimport { DriveFileSelectContext, ROOT_PATH } from \"@/components/DriveFileSelect\"\n\nconst FileBreadCrumb: FC = () => {\n  const { currentPath, totalPath, updatePath } = useContext(\n    DriveFileSelectContext,\n  )\n\n  const handleClickBreadcrumb = useCallback(\n    (path: string, last: boolean) => {\n      if (last) {\n        return\n      }\n      updatePath(path)\n    },\n    [updatePath],\n  )\n\n  const breadList = useMemo(() => {\n    if (!currentPath) {\n      return [\n        {\n          path: ROOT_PATH,\n          title: ROOT_PATH,\n          last: true,\n        },\n      ]\n    }\n\n    return currentPath?.split(\"/\").map((item, index, array) => {\n      const breadcrumbPath = array.slice(0, index + 1).join(\"/\")\n      const limitPath = totalPath.split(breadcrumbPath)[0]\n      const path = `${limitPath}${breadcrumbPath}`\n      const isLast = index === array.length - 1\n      return {\n        path,\n        title: item,\n        last: isLast,\n      }\n    })\n  }, [currentPath, totalPath])\n\n  return (\n    <Breadcrumb\n      flexWrap=\"wrap\"\n      onClickPath={handleClickBreadcrumb}\n      blockRouterChange\n    >\n      {breadList.map((item, index) => (\n        <BreadcrumbItem last={item.last ?? false} key={index} href={item.path}>\n          {item.title}\n        </BreadcrumbItem>\n      ))}\n    </Breadcrumb>\n  )\n}\n\nexport default FileBreadCrumb\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/components/EmptyState/index.tsx",
    "content": "import { FolderIcon } from \"@illa-public/icon\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { emptyContainerStyle } from \"./style\"\n\nconst EmptyState: FC = () => {\n  const { t } = useTranslation()\n  return (\n    <div css={emptyContainerStyle}>\n      <FolderIcon />\n      <span>{t(\"widget.drive_picker.modal.no_file\")}</span>\n    </div>\n  )\n}\n\nexport default EmptyState\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/components/EmptyState/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const emptyContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/components/FileList/index.tsx",
    "content": "import { getFileIconByContentType } from \"@illa-public/icon\"\nimport { GCS_OBJECT_TYPE, IILLAFileInfo } from \"@illa-public/public-types\"\nimport VirtualList from \"rc-virtual-list\"\nimport { FC, MouseEvent, useCallback, useRef } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Checkbox, DoubtIcon, Trigger } from \"@illa-design/react\"\nimport {\n  FOLDER_LIST_CONTAINER_HEIGHT,\n  FOLDER_LIST_ITEM_HEIGHT,\n} from \"@/components/DriveFileSelect/constants\"\nimport { FileListProps } from \"./interface\"\nimport {\n  doubtStyle,\n  fileNameStyle,\n  iconPublicStyle,\n  listItemContainerStyle,\n  singleListItemContainerStyle,\n} from \"./style\"\n\nconst FileList: FC<FileListProps> = (props) => {\n  const {\n    listData,\n    totalPath,\n    search,\n    selectItems,\n    colorScheme,\n    singleSelect,\n    onChange,\n    getFileList,\n    updatePath,\n    handleSingleChange,\n  } = props\n\n  const { t } = useTranslation()\n\n  const handleClickItem = useCallback(\n    (e: MouseEvent<HTMLLabelElement>, item: IILLAFileInfo) => {\n      e.stopPropagation()\n      if (\n        item.type === GCS_OBJECT_TYPE.FOLDER ||\n        item.type === GCS_OBJECT_TYPE.ANONYMOUS_FOLDER\n      ) {\n        updatePath(`${totalPath}/${item.name}`)\n        return\n      } else if (singleSelect) {\n        handleSingleChange(item)\n      }\n    },\n    [singleSelect, totalPath, updatePath, handleSingleChange],\n  )\n\n  const currentPageIndexRef = useRef(1)\n\n  const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => {\n    if (\n      e.currentTarget.scrollHeight - e.currentTarget.scrollTop ===\n      FOLDER_LIST_CONTAINER_HEIGHT\n    ) {\n      getFileList(++currentPageIndexRef.current, totalPath, search?.current)\n    }\n  }\n\n  return (\n    <VirtualList\n      height={FOLDER_LIST_CONTAINER_HEIGHT}\n      itemHeight={FOLDER_LIST_ITEM_HEIGHT}\n      itemKey=\"id\"\n      data={listData}\n      onScroll={onScroll}\n    >\n      {(item: IILLAFileInfo) => {\n        return (\n          <label\n            css={\n              singleSelect\n                ? singleListItemContainerStyle(selectItems[0]?.id === item.id)\n                : listItemContainerStyle\n            }\n            onClick={(e) => handleClickItem(e, item)}\n          >\n            {!singleSelect && (\n              <Checkbox\n                colorScheme={colorScheme}\n                disabled={\n                  item.type === GCS_OBJECT_TYPE.FOLDER ||\n                  item.type === GCS_OBJECT_TYPE.ANONYMOUS_FOLDER\n                }\n                key={item.id}\n                onChange={(v) => onChange(v, item)}\n                defaultChecked={\n                  selectItems.findIndex((file) => file.id === item.id) !== -1\n                }\n              />\n            )}\n            {getFileIconByContentType(\n              item.type,\n              item.contentType,\n              iconPublicStyle,\n            )}\n            <span css={fileNameStyle}>{item.name}</span>\n            {item.type === GCS_OBJECT_TYPE.ANONYMOUS_FOLDER && (\n              <Trigger\n                position=\"top\"\n                content={t(\"drive.drive_builder.public_folder.tips\")}\n              >\n                <span css={doubtStyle}>\n                  <DoubtIcon size=\"16px\" />\n                </span>\n              </Trigger>\n            )}\n          </label>\n        )\n      }}\n    </VirtualList>\n  )\n}\n\nexport default FileList\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/components/FileList/interface.ts",
    "content": "import { MutableRefObject } from \"react\"\nimport { FileToPanel } from \"@/components/DriveFileSelect/interface\"\nimport { IILLAFileInfo } from \"@/services/drive\"\n\nexport interface FileListProps {\n  listData: IILLAFileInfo[]\n  totalPath: string\n  search?: MutableRefObject<string>\n  selectItems: FileToPanel[]\n  colorScheme: string\n  singleSelect?: boolean\n  getFileList: (currentPage: number, totalPath: string, search?: string) => void\n  updatePath: (changedPath: string) => void\n  onChange: (flag: boolean, item: FileToPanel) => void\n  handleSingleChange: (item: FileToPanel) => void\n}\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/components/FileList/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { FOLDER_LIST_ITEM_HEIGHT } from \"../../constants\"\n\nexport const fileNameStyle = css`\n  font-size: 14px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-weight: 500;\n`\nexport const iconPublicStyle = css`\n  display: inline-block;\n  width: 24px;\n  height: 30px;\n  flex: none;\n`\n\nexport const listItemContainerStyle = css`\n  display: flex;\n  align-items: center;\n  padding: 0 24px;\n  height: ${FOLDER_LIST_ITEM_HEIGHT}px;\n  gap: 8px;\n  cursor: pointer;\n  & > input {\n    margin: 3px 4px;\n  }\n`\n\nexport const singleListItemContainerStyle = (isSelected: boolean) => css`\n  ${listItemContainerStyle};\n  background-color: ${isSelected\n    ? getColor(\"techPurple\", \"08\")\n    : \"transparent\"};\n`\n\nexport const doubtStyle = css`\n  display: flex;\n  width: 16px;\n  height: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/components/FileListContent/index.tsx",
    "content": "import { debounce } from \"lodash-es\"\nimport {\n  FC,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button, CloseIcon, Search, useMessage } from \"@illa-design/react\"\nimport { DriveFileSelectContext } from \"@/components/DriveFileSelect\"\nimport FileBreadCrumb from \"@/components/DriveFileSelect/components/Breadcrumb\"\nimport EmptyState from \"@/components/DriveFileSelect/components/EmptyState\"\nimport FileList from \"@/components/DriveFileSelect/components/FileList\"\nimport { LoadingState } from \"@/components/DriveFileSelect/components/LoadingState\"\nimport {\n  MAX_FILE_NUM,\n  MAX_SIZE_MESSAGE,\n  MIN_FILE_NUM,\n  MIN_SIZE_MESSAGE,\n} from \"@/components/DriveFileSelect/constants\"\nimport { FileToPanel } from \"@/components/DriveFileSelect/interface\"\nimport i18n from \"@/i18n/config\"\nimport {\n  ModalTitleStyle,\n  applyInnerFileListContainerStyle,\n  fileListContainerStyle,\n  footerContainerStyle,\n  headerContainerStyle,\n} from \"./style\"\n\nconst FilesModalContent: FC = () => {\n  const {\n    modalVisible,\n    fileList,\n    totalPath,\n    minSize,\n    maxSize,\n    minFileNum,\n    maxFileNum,\n    sizeType = \"mb\",\n    colorScheme,\n    singleSelect = false,\n    getFileList,\n    updatePath,\n    submitSelect,\n    handleCloseModal,\n  } = useContext(DriveFileSelectContext)\n  const { t } = useTranslation()\n\n  const [isConfirmLoading, setConfirmLoading] = useState(false)\n  const searchRef = useRef(\"\")\n  const [selectItems, setSelectItems] = useState<FileToPanel[]>([])\n  const [disabled, setDisabled] = useState(true)\n  const [loading, setLoading] = useState(true)\n  const message = useMessage()\n\n  const handleBtnDisabled = useCallback(\n    (list: FileToPanel[]) => {\n      if (disabled && list.length > 0) {\n        setDisabled(false)\n      } else if (!disabled && list.length === 0) {\n        setDisabled(true)\n      }\n    },\n    [disabled],\n  )\n\n  const validateFileNum = useCallback(() => {\n    if (maxFileNum && selectItems.length > maxFileNum) {\n      message.info({\n        content: i18n.t(MAX_FILE_NUM, {\n          max: maxFileNum,\n        }),\n      })\n      return false\n    }\n    if (minFileNum && selectItems.length < minFileNum) {\n      message.info({\n        content: i18n.t(MIN_FILE_NUM, {\n          min: minFileNum,\n        }),\n      })\n      return false\n    }\n    if (maxSize) {\n      const equalMaxSize =\n        sizeType === \"mb\" ? maxSize * 1024 * 1024 : maxSize * 1024\n      if (selectItems.some((item) => item.size > equalMaxSize)) {\n        message.info({\n          content: i18n.t(MAX_SIZE_MESSAGE, {\n            max: maxSize + sizeType,\n          }),\n        })\n        return false\n      }\n    }\n    if (minSize) {\n      const equalMinSize =\n        sizeType === \"mb\" ? minSize * 1024 * 1024 : minSize * 1024\n      if (selectItems.some((item) => item.size < equalMinSize)) {\n        message.info({\n          content: i18n.t(MIN_SIZE_MESSAGE, {\n            min: minSize + sizeType,\n          }),\n        })\n        return false\n      }\n    }\n    return true\n  }, [maxFileNum, maxSize, message, minFileNum, minSize, selectItems, sizeType])\n\n  const handleChange = useCallback(\n    (flag: boolean, item: FileToPanel) => {\n      const index = selectItems.findIndex((file) => file.id === item.id)\n      if (!flag && index !== -1) {\n        const newSelectItems = selectItems.concat()\n        newSelectItems.splice(index, 1)\n        setSelectItems(newSelectItems)\n        handleBtnDisabled(newSelectItems)\n      } else if (flag && index === -1) {\n        const newSelectItems = selectItems.concat(item)\n        setSelectItems(newSelectItems)\n        handleBtnDisabled(newSelectItems)\n      }\n    },\n    [handleBtnDisabled, selectItems],\n  )\n\n  const handleSingleChange = useCallback(\n    (item: FileToPanel) => {\n      if (selectItems[0]?.id !== item.id) {\n        setSelectItems([item])\n        setDisabled(false)\n      }\n    },\n    [selectItems],\n  )\n\n  const handleClickClose = useCallback(() => {\n    handleCloseModal()\n    setSelectItems([])\n  }, [handleCloseModal])\n\n  const handleClickOk = useCallback(async () => {\n    if (!validateFileNum()) {\n      return\n    }\n    setConfirmLoading(true)\n    submitSelect(selectItems)\n      .then(() => {\n        setSelectItems([])\n      })\n      .finally(() => {\n        setConfirmLoading(false)\n      })\n  }, [selectItems, submitSelect, validateFileNum])\n\n  const getListDate = useCallback(\n    async (currentPage: number, totalPath: string, search?: string) => {\n      setLoading(true)\n      try {\n        await getFileList(currentPage, totalPath, search)\n      } catch (e) {\n      } finally {\n        setLoading(false)\n      }\n    },\n    [getFileList],\n  )\n\n  const debounceHandleOnSearch = useMemo(() => {\n    return debounce((value: string) => {\n      getListDate(1, totalPath, value)\n    }, 500)\n  }, [getListDate, totalPath])\n\n  useEffect(() => {\n    modalVisible && getListDate(1, totalPath)\n  }, [getListDate, modalVisible, totalPath])\n\n  return (\n    <>\n      <div css={ModalTitleStyle}>\n        <span>{t(\"widget.drive_picker.modal.files\")}</span>\n        <span onClick={handleClickClose} style={{ cursor: \"pointer\" }}>\n          <CloseIcon />\n        </span>\n      </div>\n      <div css={headerContainerStyle}>\n        <FileBreadCrumb />\n        <Search\n          colorScheme={colorScheme}\n          placeholder=\"search\"\n          onChange={debounceHandleOnSearch}\n        />\n      </div>\n      <div css={fileListContainerStyle}>\n        <div css={applyInnerFileListContainerStyle(loading)}>\n          {fileList.length > 0 ? (\n            <FileList\n              onChange={handleChange}\n              listData={fileList}\n              key={totalPath}\n              totalPath={totalPath}\n              getFileList={getListDate}\n              search={searchRef}\n              updatePath={updatePath}\n              selectItems={selectItems}\n              colorScheme={colorScheme}\n              singleSelect={singleSelect}\n              handleSingleChange={handleSingleChange}\n            />\n          ) : (\n            !loading && <EmptyState />\n          )}\n        </div>\n        {loading && <LoadingState colorScheme={colorScheme} />}\n      </div>\n      <div css={footerContainerStyle}>\n        <Button minW=\"78px\" onClick={handleClickClose} colorScheme=\"grayBlue\">\n          {t(\"widget.drive_picker.modal.cancel\")}\n        </Button>\n        <Button\n          minW=\"200px\"\n          disabled={disabled}\n          colorScheme={colorScheme}\n          onClick={handleClickOk}\n          loading={isConfirmLoading}\n        >\n          {singleSelect\n            ? t(\"drive.upload.select.confirm_button\")\n            : t(\"widget.drive_picker.modal.confirm\", {\n                fileNum: selectItems.length,\n              })}\n        </Button>\n      </div>\n    </>\n  )\n}\n\nexport default FilesModalContent\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/components/FileListContent/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { FOLDER_LIST_CONTAINER_HEIGHT } from \"../../constants\"\n\nexport const ModalTitleStyle = css`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 32px 32px 8px;\n  & > span:first-of-type {\n    font-weight: 600;\n    font-size: 24px;\n  }\n`\n\nexport const applyInnerFileListContainerStyle = (isLoading: boolean) => {\n  const loadingStyle = css`\n    opacity: 0.5;\n    transition: opacity 0.3s;\n    user-select: none;\n    pointer-events: none;\n  `\n  return css`\n    height: 100%;\n    width: 100%;\n    ${isLoading && loadingStyle};\n  `\n}\n\nexport const fileListContainerStyle = css`\n  height: ${FOLDER_LIST_CONTAINER_HEIGHT}px;\n  width: 100%;\n  position: relative;\n`\n\nexport const footerContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n  padding: 24px 24px 16px 24px;\n  gap: 8px;\n`\n\nexport const headerContainerStyle = css`\n  display: flex;\n  gap: 16px;\n  padding: 8px 24px;\n  display: flex;\n  flex-direction: column;\n  align-items: flex-start;\n`\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/components/LoadingState/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Spin } from \"@illa-design/react\"\nimport { loadingContainerStyle } from \"./style\"\n\nexport const LoadingState: FC<{ colorScheme: string }> = ({ colorScheme }) => {\n  return (\n    <div css={loadingContainerStyle}>\n      <Spin colorScheme={colorScheme} />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/components/LoadingState/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { FOLDER_LIST_CONTAINER_HEIGHT } from \"../../constants\"\n\nexport const loadingContainerStyle = css`\n  height: ${FOLDER_LIST_CONTAINER_HEIGHT}px;\n  width: 100%;\n  position: relative;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  position: absolute;\n  top: 0;\n  z-index: 4;\n`\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/constants.ts",
    "content": "export const FOLDER_LIST_CONTAINER_HEIGHT = 276\nexport const FOLDER_LIST_ITEM_HEIGHT = 46\nexport const MAX_SIZE_MESSAGE =\n  \"editor.inspect.setter_message.drive_builder.max_size\"\nexport const MIN_SIZE_MESSAGE =\n  \"editor.inspect.setter_message.drive_builder.min_size\"\nexport const MAX_FILE_NUM =\n  \"editor.inspect.setter_message.drive_builder.max_files\"\nexport const MIN_FILE_NUM =\n  \"editor.inspect.setter_message.drive_builder.min_files\"\n\nexport const ROOT_PATH = \"root\"\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/context/index.tsx",
    "content": "import { createContext } from \"react\"\nimport { IILLAFileInfo } from \"@/services/drive\"\nimport { FileToPanel } from \"../interface\"\n\ninterface Injected {\n  modalVisible: boolean\n  fileList: IILLAFileInfo[]\n  currentPath: string\n  totalPath: string\n  sizeType?: \"kb\" | \"mb\"\n  minSize?: number\n  maxSize?: number\n  minFileNum?: number\n  maxFileNum?: number\n  colorScheme: string\n  singleSelect?: boolean\n  updatePath: (changedPath: string) => void\n  submitSelect: (selectIds: FileToPanel[]) => Promise<unknown>\n  setModalVisible: (visible: boolean) => void\n  getFileList: (\n    currentPage: number,\n    totalPath: string,\n    search?: string,\n  ) => Promise<unknown>\n  handleCloseModal: () => void\n}\n\nexport const DriveFileSelectContext = createContext<Injected>({} as Injected)\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/hooks/usePath.tsx",
    "content": "import { useCallback, useEffect, useState } from \"react\"\nimport {\n  getCurrentPath,\n  removeSuffixPath,\n} from \"@/components/DriveFileSelect/utils\"\nimport { ROOT_PATH } from \"../constants\"\n\nexport const usePath = (\n  path: string,\n  allowAnonymousUse?: boolean | undefined,\n) => {\n  const [totalPath, setTotalPath] = useState<string>(path || ROOT_PATH)\n  const [currentPath, setCurrentPath] = useState<string>(\n    getCurrentPath(totalPath ?? \"root\"),\n  )\n\n  const updatePath = useCallback(\n    (changedPath: string) => {\n      const curChangePath = removeSuffixPath(changedPath)\n      setTotalPath(curChangePath)\n      setCurrentPath(getCurrentPath(path, curChangePath))\n    },\n    [path],\n  )\n\n  useEffect(() => {\n    if (allowAnonymousUse) {\n      setTotalPath(ROOT_PATH)\n      setCurrentPath(ROOT_PATH)\n    } else {\n      setTotalPath(path || ROOT_PATH)\n      setCurrentPath(getCurrentPath(path || ROOT_PATH))\n    }\n  }, [allowAnonymousUse, path])\n\n  return {\n    currentPath,\n    updatePath,\n    totalPath,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/index.tsx",
    "content": "import { FC, useContext } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { Modal } from \"@illa-design/react\"\nimport FilesModalContent from \"./components/FileListContent\"\nimport { DriveFileSelectContext } from \"./context\"\n\nconst FilesModal: FC = () => {\n  const { modalVisible, handleCloseModal } = useContext(DriveFileSelectContext)\n\n  return createPortal(\n    <>\n      {modalVisible && (\n        <Modal\n          closable\n          maskClosable\n          withoutPadding\n          visible\n          onCancel={handleCloseModal}\n          footer={false}\n        >\n          <FilesModalContent />\n        </Modal>\n      )}\n    </>,\n    document.body,\n  )\n}\n\nexport default FilesModal\nexport { usePath } from \"./hooks/usePath\"\nexport * from \"./utils\"\nexport * from \"./interface\"\nexport * from \"./context\"\nexport * from \"./constants\"\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/interface.ts",
    "content": "import { IILLAFileInfo } from \"@/services/drive\"\n\nexport type FileToPanel = Pick<\n  IILLAFileInfo,\n  \"id\" | \"lastModifiedAt\" | \"name\" | \"size\" | \"type\"\n>\n"
  },
  {
    "path": "apps/builder/src/components/DriveFileSelect/utils.tsx",
    "content": "export const getCurrentPath = (limitPath: string, totalPath?: string) => {\n  const curTotalPath = totalPath ?? limitPath\n  const limitPathArr = limitPath.split(\"/\")\n  const limitRoot = limitPathArr[limitPathArr.length - 1]\n  return removeSuffixPath(`${limitRoot}${curTotalPath.replace(limitPath, \"\")}`)\n}\n\nexport const removeSuffixPath = (path: string): string => {\n  const regex = /^\\/?(.*?)\\/?$/\n  return path?.match(regex)?.[1] || path\n}\n"
  },
  {
    "path": "apps/builder/src/components/EditableText/index.tsx",
    "content": "import { FC, useCallback, useRef, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Input, PenIcon, useMessage } from \"@illa-design/react\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { isValidDisplayName } from \"@/utils/typeHelper\"\nimport { EditableTextProps } from \"./interface\"\nimport { editableTextWrapperStyle, innerTextStyle, textStyle } from \"./style\"\n\nexport const EditableText: FC<EditableTextProps> = (props) => {\n  const {\n    displayName,\n    updateDisplayNameByBlur,\n    onMouseEnter,\n    onClick,\n    onBlur,\n    onValidate,\n  } = props\n  const [inputValue, setInputValue] = useState(displayName)\n  const [isFocusInput, setIsFocusInput] = useState(false)\n  const { t } = useTranslation()\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const handleChangeInputValue = (value: string) => {\n    setInputValue(value)\n  }\n\n  const handleClickOnSpan = () => {\n    if (isFocusInput) return\n    setIsFocusInput(true)\n    onClick?.()\n    setTimeout(() => {\n      inputRef.current?.focus()\n    }, 100)\n  }\n\n  const message = useMessage()\n\n  const handleBlurInput = useCallback(() => {\n    setIsFocusInput(false)\n    if (displayName === inputValue) {\n      return\n    }\n    onBlur?.(inputValue)\n    if (!isValidDisplayName(inputValue)) {\n      message.error({\n        content: t(\"editor.display_name.validate_error\", {\n          displayName: inputValue,\n        }),\n      })\n      onValidate?.(\"failed\")\n      setInputValue(displayName)\n      return\n    }\n    if (DisplayNameGenerator.isAlreadyGenerate(inputValue)) {\n      message.error({\n        content: t(\"editor.display_name.duplicate_error\", {\n          displayName: inputValue,\n        }),\n      })\n      onValidate?.(\"failed\")\n      setInputValue(displayName)\n      return\n    }\n    onValidate?.(\"suc\")\n    updateDisplayNameByBlur(inputValue)\n  }, [\n    displayName,\n    inputValue,\n    message,\n    onBlur,\n    onValidate,\n    t,\n    updateDisplayNameByBlur,\n  ])\n  return (\n    <div\n      css={editableTextWrapperStyle}\n      onMouseEnter={onMouseEnter}\n      className=\"editable-text-container\"\n      onClick={handleClickOnSpan}\n    >\n      {isFocusInput ? (\n        <Input\n          colorScheme=\"techPurple\"\n          value={inputValue}\n          onChange={handleChangeInputValue}\n          onBlur={handleBlurInput}\n          onPressEnter={handleBlurInput}\n          inputRef={inputRef}\n          className=\"input-container\"\n        />\n      ) : (\n        <span css={textStyle} className=\"text-container\">\n          <span css={innerTextStyle}>\n            {inputValue}\n            <PenIcon />\n          </span>\n        </span>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/EditableText/interface.ts",
    "content": "export interface EditableTextProps {\n  displayName: string\n  updateDisplayNameByBlur: (value: string) => void\n  onMouseEnter?: () => void\n  onClick?: () => void\n  onBlur?: (value: string) => void\n  onValidate?: (result: \"suc\" | \"failed\") => void\n}\n"
  },
  {
    "path": "apps/builder/src/components/EditableText/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const editableTextWrapperStyle = css`\n  width: 100%;\n  border-radius: 8px;\n  display: flex;\n  align-items: center;\n  &:hover {\n    background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n    cursor: pointer;\n\n    svg {\n      opacity: 1;\n    }\n    .text-container {\n      padding-left: 16px;\n    }\n  }\n  transition: all 200ms;\n`\n\nexport const textStyle = css`\n  height: 100%;\n  display: inline-flex;\n  min-height: 32px;\n  font-size: 14px;\n  align-items: center;\n  box-sizing: border-box;\n  max-lines: 1;\n  white-space: nowrap;\n  border-radius: 8px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  font-weight: 500;\n  position: relative;\n  svg {\n    width: 14px;\n    height: 14px;\n    margin-left: 8px;\n    opacity: 0;\n    color: ${globalColor(`--${illaPrefix}-grayBlue-05`)};\n    transition: all 200ms;\n  }\n  transition: all 200ms;\n`\n\nexport const innerTextStyle = css`\n  position: relative;\n  display: flex;\n  align-items: center;\n  svg {\n    position: absolute;\n    right: -22px;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/components/ErrorBoundary/fallback/widget/index.tsx",
    "content": "import { FC } from \"react\"\nimport { ErrorIcon } from \"@illa-design/react\"\nimport {\n  contentWrapperStyle,\n  titleWrapperStyle,\n  widgetBoundaryWrapperStyle,\n} from \"./style\"\n\nexport const WidgetErrorBoundary: FC = () => {\n  return (\n    <div css={widgetBoundaryWrapperStyle}>\n      <div css={titleWrapperStyle}>\n        <ErrorIcon size=\"12px\" />\n        <span>Error</span>\n      </div>\n      <div css={contentWrapperStyle}>Configuration error, please modify</div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/ErrorBoundary/fallback/widget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const widgetBoundaryWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  background-color: ${getColor(\"red\", \"08\")};\n  overflow: auto;\n`\n\nexport const titleWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  color: ${getColor(\"red\", \"03\")};\n  font-size: 14px;\n  font-weight: 600;\n`\n\nexport const contentWrapperStyle = css`\n  color: ${getColor(\"red\", \"03\")};\n  font-size: 12px;\n  line-height: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/components/ErrorBoundary/index.tsx",
    "content": "import { Component } from \"react\"\nimport { WidgetErrorBoundary } from \"./fallback/widget\"\nimport { ErrorBoundaryProps, ErrorBoundaryState } from \"./interface\"\n\nclass ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n  constructor(props: ErrorBoundaryProps) {\n    super(props)\n    this.state = { hasError: false }\n  }\n\n  static defaultProps = {\n    fallback: <WidgetErrorBoundary />,\n  }\n\n  static getDerivedStateFromError() {\n    return { hasError: true }\n  }\n\n  componentDidCatch(): void {\n    this.setState({ hasError: true })\n  }\n\n  render() {\n    if (this.state.hasError) {\n      return this.props.fallback\n    }\n    return this.props.children\n  }\n}\n\nexport default ErrorBoundary\n"
  },
  {
    "path": "apps/builder/src/components/ErrorBoundary/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface ErrorBoundaryProps {\n  children: ReactNode\n  fallback?: ReactNode\n}\n\nexport interface ErrorBoundaryState {\n  hasError: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/CreateFolderModal/index.tsx",
    "content": "import { DUPLICATION_HANDLER, GCS_OBJECT_TYPE } from \"@illa-public/public-types\"\nimport { FC, useCallback, useContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Modal, useMessage } from \"@illa-design/react\"\nimport { Input } from \"@illa-design/react\"\nimport {\n  fetchCheckFileExist,\n  fetchGCSUploadPresignedURL,\n} from \"@/services/drive\"\nimport { FolderOperateModalContext } from \"../../context\"\nimport { SameNameModal } from \"../SameNameModal\"\nimport { CreateFolderModalProps } from \"./interface\"\nimport { invalidTipsStyle, messageStyle } from \"./style\"\n\nconst availableFilenameRule = /^[\\u4e00-\\u9fa5a-zA-Z0-9=_~\\-]+$/u\n\nconst isInvalidFolderName = (folderName: string) => {\n  return !availableFilenameRule.test(folderName)\n}\n\nconst CreateFolderModal: FC<CreateFolderModalProps> = ({ currentFolderID }) => {\n  const {\n    currentFolderPath,\n    createFolderVisible,\n    setCreateFolderVisible,\n    setCurrentFolderPath,\n  } = useContext(FolderOperateModalContext)\n  const { t } = useTranslation()\n  const message = useMessage()\n  const [folderName, setFolderName] = useState(\"\")\n  const [newFolderName, setNewFolderName] = useState(\"\")\n  const [isLoading, setIsLoading] = useState(false)\n  const [sameModalVisible, setSameModalVisible] = useState(false)\n\n  const isDisabled =\n    !!folderName && isInvalidFolderName((folderName ?? \"\").trim())\n\n  const createFolder = useCallback(\n    async (name: string, duplicationHandler = DUPLICATION_HANDLER.RENAME) => {\n      try {\n        const response = await fetchGCSUploadPresignedURL({\n          name: name,\n          folderID: currentFolderID,\n          type: GCS_OBJECT_TYPE.FOLDER,\n          size: 0,\n          resumable: false,\n          duplicationHandler,\n          contentType: \"\",\n        })\n        setCreateFolderVisible(false)\n        message.success({\n          content: t(\"drive.message.create_suc\"),\n        })\n        setCurrentFolderPath(`${currentFolderPath}/${response.data.name}`)\n      } catch (e) {\n        message.error({\n          content: t(\"drive.message.create_failed\"),\n        })\n      }\n    },\n    [\n      currentFolderID,\n      currentFolderPath,\n      message,\n      setCreateFolderVisible,\n      setCurrentFolderPath,\n      t,\n    ],\n  )\n\n  const handleClickCreate = useCallback(async () => {\n    setIsLoading(true)\n    try {\n      const duplicateResponse = await fetchCheckFileExist([\n        {\n          folderID: currentFolderID,\n          name: folderName,\n          type: GCS_OBJECT_TYPE.FOLDER,\n        },\n      ])\n      const duplicateInfo = duplicateResponse.data[0]\n      if (duplicateInfo.isDuplicated) {\n        setNewFolderName(duplicateInfo.name)\n        setSameModalVisible(true)\n        return\n      }\n      await createFolder(folderName.trim())\n    } catch (e) {\n    } finally {\n      setIsLoading(false)\n    }\n  }, [createFolder, currentFolderID, folderName, setSameModalVisible])\n\n  return (\n    <>\n      <Modal\n        closable\n        visible={createFolderVisible}\n        okButtonProps={{\n          disabled: (folderName ?? \"\").trim().length <= 0 || isDisabled,\n          loading: isLoading,\n          colorScheme: \"techPurple\",\n        }}\n        enableOnFormTags={[]}\n        title={t(\"drive.create_modal.title.create_a_folder\")}\n        okText={t(\"drive.create_modal.title.create\")}\n        cancelText={t(\"drive.create_modal.title.cancel\")}\n        onOk={handleClickCreate}\n        onCancel={() => {\n          setCreateFolderVisible(false)\n        }}\n        afterClose={() => {\n          setFolderName(\"\")\n          setIsLoading(false)\n        }}\n      >\n        <Input\n          colorScheme=\"techPurple\"\n          onChange={setFolderName}\n          value={folderName}\n          maxLength={255}\n        />\n        {isDisabled ? (\n          <span css={invalidTipsStyle}>\n            {t(\"drive.create_modal.validate_failed\")}\n          </span>\n        ) : (\n          <span css={messageStyle}>{t(\"drive.create_modal.validate\")}</span>\n        )}\n      </Modal>\n      <SameNameModal\n        objectName={newFolderName}\n        createFolder={createFolder}\n        sameModalVisible={sameModalVisible}\n        setSameModalVisible={setSameModalVisible}\n      />\n    </>\n  )\n}\n\nexport default CreateFolderModal\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/CreateFolderModal/interface.ts",
    "content": "export interface CreateFolderModalProps {\n  currentFolderID: string\n}\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/CreateFolderModal/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const createFolderModalMaskStyle = css`\n  background-color: ${getColor(\"white\", \"05\")};\n  backdrop-filter: blur(5px);\n`\n\nexport const invalidTipsStyle = css`\n  display: inline-flex;\n  color: ${getColor(\"orange\", \"03\")};\n  font-size: 14px;\n  margin-top: 4px;\n`\n\nexport const messageStyle = css`\n  display: inline-flex;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 14px;\n  margin-top: 4px;\n`\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/Empty/index.tsx",
    "content": "import { FolderIcon } from \"@illa-public/icon\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { emptyContainerStyle } from \"./style\"\n\nconst EmptyState: FC = () => {\n  const { t } = useTranslation()\n  return (\n    <div css={emptyContainerStyle}>\n      <FolderIcon />\n      <span>{t(\"drive.move_modal.no_folders\")}</span>\n    </div>\n  )\n}\n\nexport default EmptyState\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/Empty/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const emptyContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/FolderList/index.tsx",
    "content": "import { AnonymousIcon, FolderIcon } from \"@illa-public/icon\"\nimport { GCS_OBJECT_TYPE, IILLAFileInfo } from \"@illa-public/public-types\"\nimport VirtualList from \"rc-virtual-list\"\nimport { FC, useCallback, useContext, useRef } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { DoubtIcon, Trigger } from \"@illa-design/react\"\nimport {\n  FOLDER_LIST_CONTAINER_HEIGHT,\n  FOLDER_LIST_ITEM_HEIGHT,\n} from \"../../constants\"\nimport { FolderOperateModalContext } from \"../../context\"\nimport { FolderListProps } from \"./interface\"\nimport {\n  doubtStyle,\n  folderIconStyle,\n  folderNameStyle,\n  listItemContainerStyle,\n} from \"./style\"\n\nconst FolderList: FC<FolderListProps> = (props) => {\n  const { listData, updateListData } = props\n  const { t } = useTranslation()\n  const { currentFolderPath, setCurrentFolderPath } = useContext(\n    FolderOperateModalContext,\n  )\n\n  const handleClickItem = useCallback(\n    (name: string) => {\n      return () => {\n        const path = `${currentFolderPath}/${name}`\n        setCurrentFolderPath(path)\n      }\n    },\n    [currentFolderPath, setCurrentFolderPath],\n  )\n  const currentPageIndexRef = useRef(1)\n\n  const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => {\n    if (\n      e.currentTarget.scrollHeight - e.currentTarget.scrollTop ===\n      FOLDER_LIST_CONTAINER_HEIGHT\n    ) {\n      updateListData(++currentPageIndexRef.current, currentFolderPath)\n    }\n  }\n\n  return (\n    <VirtualList\n      height={FOLDER_LIST_CONTAINER_HEIGHT}\n      itemHeight={FOLDER_LIST_ITEM_HEIGHT}\n      itemKey=\"id\"\n      data={listData}\n      onScroll={onScroll}\n    >\n      {(item: IILLAFileInfo) => {\n        return (\n          <div\n            css={listItemContainerStyle}\n            onClick={handleClickItem(item.name)}\n          >\n            {item.type === GCS_OBJECT_TYPE.ANONYMOUS_FOLDER ? (\n              <AnonymousIcon css={folderIconStyle} />\n            ) : (\n              <FolderIcon css={folderIconStyle} />\n            )}\n            <span css={folderNameStyle}>{item.name}</span>\n            {item.type === GCS_OBJECT_TYPE.ANONYMOUS_FOLDER && (\n              <Trigger\n                position=\"top\"\n                content={t(\"drive.drive_builder.public_folder.tips\")}\n              >\n                <span css={doubtStyle}>\n                  <DoubtIcon size=\"16px\" />\n                </span>\n              </Trigger>\n            )}\n          </div>\n        )\n      }}\n    </VirtualList>\n  )\n}\n\nexport default FolderList\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/FolderList/interface.ts",
    "content": "import { IILLAFileInfo } from \"@/services/drive\"\n\nexport interface FolderListProps {\n  listData: IILLAFileInfo[]\n  updateListData: (page: number, path: string) => void\n}\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/FolderList/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { FOLDER_LIST_ITEM_HEIGHT } from \"../../constants\"\n\nexport const listItemContainerStyle = css`\n  display: flex;\n  align-items: center;\n  height: ${FOLDER_LIST_ITEM_HEIGHT}px;\n  gap: 4px;\n  cursor: pointer;\n`\n\nexport const folderIconStyle = css`\n  width: 24px;\n  height: 24px;\n`\n\nexport const folderNameStyle = css`\n  font-size: 14px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-weight: 500;\n`\n\nexport const doubtStyle = css`\n  display: flex;\n  width: 16px;\n  height: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/FolderModalContent/index.tsx",
    "content": "import {\n  DRIVE_FILE_TYPE,\n  IILLAFileInfo,\n  SORTED_TYPE,\n} from \"@illa-public/public-types\"\nimport {\n  FC,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  Breadcrumb,\n  BreadcrumbItem,\n  Button,\n  CloseIcon,\n} from \"@illa-design/react\"\nimport { PlusIcon } from \"@illa-design/react\"\nimport { fetchFileList } from \"@/services/drive\"\nimport { FOLDER_LIST_LIMIT_IN_MODAL, ROOT_PATH } from \"../../constants\"\nimport { FolderOperateModalContext } from \"../../context\"\nimport CreateFolderModal from \"../CreateFolderModal\"\nimport EmptyState from \"../Empty\"\nimport FolderList from \"../FolderList\"\nimport LoadingState from \"../LoadingState\"\nimport {\n  applyInnerFolderListContainerStyle,\n  breadItemStyle,\n  breadcrumbContainerStyle,\n  closeStyle,\n  containerStyle,\n  contentHeaderStyle,\n  folderListContainerStyle,\n  footerContainerStyle,\n  footerOperationsContainerStyle,\n  newFolderButtonStyle,\n  spanBreadcrumbStyle,\n} from \"./style\"\n\nconst FolderModalContent: FC = () => {\n  const {\n    title,\n    subTitle,\n    currentFolderPath,\n    setCurrentFolderPath,\n    setFolderOperateVisible,\n    setCreateFolderVisible,\n    operateChildren,\n  } = useContext(FolderOperateModalContext)\n  const { t } = useTranslation()\n  const [folderList, setFolderList] = useState<IILLAFileInfo[]>([])\n  const [isLoading, setIsLoading] = useState<boolean>(false)\n\n  const totalRef = useRef<number>(0)\n  const currentFolderID = useRef(\"\")\n\n  const breadList = useMemo(() => {\n    return currentFolderPath.split(\"/\").map((item, index, array) => {\n      const path = array.slice(0, index + 1).join(\"/\")\n      const isLast = index === array.length - 1\n      const isFirst = index === 0\n      if (isFirst) {\n        return {\n          title: t(\"drive.upload.modal.all\"),\n          path: ROOT_PATH,\n          last: isLast,\n        }\n      }\n      return {\n        path,\n        title: item,\n        last: isLast,\n      }\n    })\n  }, [currentFolderPath, t])\n\n  const handleFetchFileList = useCallback(\n    (pageIndex: number = 1, path: string) => {\n      if (folderList.length >= totalRef.current) {\n        return\n      }\n      setIsLoading(true)\n      fetchFileList({\n        path: `/${path}`,\n        page: pageIndex,\n        limit: FOLDER_LIST_LIMIT_IN_MODAL,\n        type: DRIVE_FILE_TYPE.FOLDER,\n        sortedBy: \"name\",\n        sortedType: SORTED_TYPE.ascend,\n      })\n        .then((res) => {\n          const folders = res.data.files ?? []\n          currentFolderID.current = res.data.currentFolderID\n          totalRef.current = res.data.total\n          setFolderList(folderList.concat(folders))\n        })\n        .finally(() => {\n          setIsLoading(false)\n        })\n    },\n    [folderList],\n  )\n\n  const handleInitFIleList = useCallback(\n    async (abortSignal: AbortSignal) => {\n      setIsLoading(true)\n      try {\n        const res = await fetchFileList(\n          {\n            path: `/${currentFolderPath}`,\n            page: 1,\n            limit: FOLDER_LIST_LIMIT_IN_MODAL,\n            type: DRIVE_FILE_TYPE.FOLDER,\n            sortedBy: \"name\",\n            sortedType: SORTED_TYPE.ascend,\n          },\n          abortSignal,\n        )\n        const folders = res.data.files ?? []\n        currentFolderID.current = res.data.currentFolderID\n        totalRef.current = res.data.total\n        setFolderList(folders)\n        setIsLoading(false)\n      } catch (e) {\n        console.log(\"e\", e)\n      }\n    },\n    [currentFolderPath, currentFolderID],\n  )\n\n  useEffect(() => {\n    const abortController = new AbortController()\n    handleInitFIleList(abortController.signal)\n\n    return () => {\n      abortController.abort()\n    }\n  }, [handleInitFIleList])\n\n  return (\n    <div css={containerStyle}>\n      <div css={contentHeaderStyle}>\n        <span>{title ?? t(\"drive.upload.modal.title\")}</span>\n        <span css={closeStyle} onClick={() => setFolderOperateVisible(false)}>\n          <CloseIcon size=\"12px\" />\n        </span>\n      </div>\n      <div css={breadcrumbContainerStyle}>\n        <span css={spanBreadcrumbStyle}>{subTitle}: </span>\n        <Breadcrumb\n          blockRouterChange\n          flexWrap=\"wrap\"\n          onClickPath={(path: string, last: boolean) => {\n            !last && setCurrentFolderPath(path)\n          }}\n        >\n          {breadList.map((item, index) => (\n            <BreadcrumbItem key={index} href={item.path}>\n              <span css={breadItemStyle(item.last)}>{item.title}</span>\n            </BreadcrumbItem>\n          ))}\n        </Breadcrumb>\n      </div>\n      <div css={folderListContainerStyle}>\n        <div css={applyInnerFolderListContainerStyle(isLoading)}>\n          {folderList.length > 0 ? (\n            <FolderList\n              listData={folderList}\n              updateListData={handleFetchFileList}\n              key={currentFolderPath}\n            />\n          ) : !isLoading ? (\n            <EmptyState />\n          ) : (\n            <></>\n          )}\n        </div>\n        {isLoading && <LoadingState />}\n      </div>\n      <div css={footerContainerStyle}>\n        <Button\n          variant=\"text\"\n          leftIcon={<PlusIcon />}\n          css={newFolderButtonStyle}\n          onClick={() => {\n            setCreateFolderVisible(true)\n          }}\n        >\n          {t(\"drive.upload.modal.create_folder\")}\n        </Button>\n        <div css={footerOperationsContainerStyle}>\n          <Button\n            colorScheme=\"grayBlue\"\n            onClick={() => setFolderOperateVisible(false)}\n          >\n            {t(\"drive.upload.modal.cancel\")}\n          </Button>\n          {operateChildren}\n        </div>\n      </div>\n      <CreateFolderModal currentFolderID={currentFolderID.current} />\n    </div>\n  )\n}\n\nexport default FolderModalContent\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/FolderModalContent/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { FOLDER_LIST_CONTAINER_HEIGHT } from \"../../constants\"\n\nexport const containerStyle = css`\n  padding: 24px;\n`\n\nexport const contentHeaderStyle = css`\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding-bottom: 8px;\n  & > span {\n    font-size: 16px;\n    font-weight: 600;\n    line-height: 32px;\n  }\n`\n\nexport const applyInnerFolderListContainerStyle = (isLoading: boolean) => {\n  const loadingStyle = css`\n    opacity: 0.5;\n    transition: opacity 0.3s;\n    user-select: none;\n    pointer-events: none;\n  `\n  return css`\n    height: 100%;\n    width: 100%;\n    ${isLoading && loadingStyle};\n  `\n}\n\nexport const breadcrumbContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 16px;\n  padding: 8px 0;\n`\n\nexport const folderListContainerStyle = css`\n  height: ${FOLDER_LIST_CONTAINER_HEIGHT}px;\n  width: 100%;\n  position: relative;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const footerContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding-top: 24px;\n`\n\nexport const footerOperationsContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const newFolderButtonStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  padding: 5px 8px !important;\n`\n\nexport const spanBreadcrumbStyle = css`\n  font-size: 14px;\n  font-weight: 500;\n`\n\nexport const closeStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 6px;\n  cursor: pointer;\n`\n\nexport const breadItemStyle = (isLast: boolean) => css`\n  color: ${isLast ? getColor(\"techPurple\", \"03\") : getColor(\"gray\", \"04\")};\n`\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/LoadingState/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { loadingContainerStyle } from \"./style\"\n\nconst LoadingState: FC = () => {\n  return (\n    <div css={loadingContainerStyle}>\n      <Loading colorScheme=\"techPurple\" />\n    </div>\n  )\n}\n\nexport default LoadingState\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/LoadingState/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { FOLDER_LIST_CONTAINER_HEIGHT } from \"../../constants\"\n\nexport const loadingContainerStyle = css`\n  height: ${FOLDER_LIST_CONTAINER_HEIGHT}px;\n  width: 100%;\n  position: relative;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  position: absolute;\n  top: 0;\n  z-index: 4;\n`\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/SameNameModal/content.tsx",
    "content": "import { DUPLICATION_HANDLER } from \"@illa-public/public-types\"\nimport { FC, useCallback, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button } from \"@illa-design/react\"\nimport { SameNameModalContentProps } from \"./interface\"\nimport { controlContainer } from \"./style\"\n\nconst SameNameModalContent: FC<SameNameModalContentProps> = (props) => {\n  const { objectName, onCancel, createFolder } = props\n  const { t } = useTranslation()\n  const [isLoading, setIsLoading] = useState(false)\n\n  const createFolderEffect = useCallback(\n    (duplicationHandler: DUPLICATION_HANDLER) => {\n      return async () => {\n        setIsLoading(true)\n        try {\n          await createFolder(objectName, duplicationHandler)\n          onCancel()\n        } catch (e) {\n          console.log(e)\n        } finally {\n          setIsLoading(false)\n        }\n      }\n    },\n    [createFolder, objectName, onCancel],\n  )\n  return (\n    <div css={controlContainer}>\n      <Button\n        onClick={createFolderEffect(DUPLICATION_HANDLER.RENAME)}\n        disabled={isLoading}\n      >\n        {t(\"drive.same_name_modal.keep_both\")}\n      </Button>\n      <Button\n        colorScheme=\"red\"\n        onClick={createFolderEffect(DUPLICATION_HANDLER.COVER)}\n        disabled={isLoading}\n      >\n        {t(\"drive.same_name_modal.replace\")}\n      </Button>\n    </div>\n  )\n}\n\nexport default SameNameModalContent\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/SameNameModal/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Modal } from \"@illa-design/react\"\nimport SameNameModalContent from \"./content\"\nimport { SameNameModalProps } from \"./interface\"\n\nexport const SameNameModal: FC<SameNameModalProps> = (props) => {\n  const { objectName, sameModalVisible, setSameModalVisible, createFolder } =\n    props\n\n  const { t } = useTranslation()\n  const onCancel = () => {\n    setSameModalVisible(false)\n  }\n\n  return (\n    <div\n      onClick={(e) => {\n        e.stopPropagation()\n      }}\n    >\n      <Modal\n        closable\n        visible={sameModalVisible}\n        onCancel={onCancel}\n        title={t(\"drive.same_name_modal.this_folder_already\")}\n        footer={false}\n      >\n        <SameNameModalContent\n          objectName={objectName}\n          createFolder={createFolder}\n          onCancel={onCancel}\n        />\n      </Modal>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/SameNameModal/interface.ts",
    "content": "import { DUPLICATION_HANDLER } from \"@illa-public/public-types\"\n\nexport interface SameNameModalProps {\n  sameModalVisible: boolean\n  setSameModalVisible: (open: boolean) => void\n  objectName: string\n  createFolder: (\n    objectName: string,\n    duplicationHandler: DUPLICATION_HANDLER,\n  ) => Promise<void>\n}\n\nexport interface SameNameModalContentProps {\n  objectName: string\n  createFolder: (\n    objectName: string,\n    duplicationHandler: DUPLICATION_HANDLER,\n  ) => Promise<void>\n  onCancel: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/components/SameNameModal/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const controlContainer = css`\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n  gap: 8px;\n`\n\nexport const hasApplyForAllContainer = css`\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n  gap: 8px;\n  margin-top: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/constants.ts",
    "content": "export const FOLDER_LIST_CONTAINER_HEIGHT = 224\nexport const FOLDER_LIST_ITEM_HEIGHT = 32\nexport const FOLDER_LIST_LIMIT_IN_MODAL = 10\nexport const ROOT_PATH = \"root\"\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/context.ts",
    "content": "import { ReactNode, createContext } from \"react\"\n\ninterface Injected {\n  title?: string\n  subTitle: string\n  currentFolderPath: string\n  folderOperateVisible: boolean\n  createFolderVisible: boolean\n  operateChildren: ReactNode\n  setCurrentFolderPath: (path: string) => void\n  setFolderOperateVisible: (v: boolean) => void\n  setCreateFolderVisible: (v: boolean) => void\n}\n\nexport const FolderOperateModalContext = createContext<Injected>({} as Injected)\n"
  },
  {
    "path": "apps/builder/src/components/FolderOperateModal/index.tsx",
    "content": "import { FC, useContext } from \"react\"\nimport { Modal } from \"@illa-design/react\"\nimport FolderModalContent from \"./components/FolderModalContent\"\nimport { FolderOperateModalContext } from \"./context\"\n\nconst FolderOperateModal: FC = () => {\n  const { folderOperateVisible, setFolderOperateVisible } = useContext(\n    FolderOperateModalContext,\n  )\n\n  return (\n    <div\n      onClick={(e) => {\n        e.stopPropagation()\n      }}\n    >\n      <Modal\n        visible={folderOperateVisible}\n        w=\"auto\"\n        footer={false}\n        withoutPadding\n        onCancel={() => setFolderOperateVisible(false)}\n      >\n        <FolderModalContent />\n      </Modal>\n    </div>\n  )\n}\n\nexport default FolderOperateModal\nexport * from \"./constants\"\nexport * from \"./context\"\n"
  },
  {
    "path": "apps/builder/src/components/FullPageLoading/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { fullPageLoadingWrapperStyle, maskStyle } from \"./style\"\n\nexport const FullPageLoading: FC<{ hasMask?: boolean }> = (props) => {\n  return (\n    <div css={fullPageLoadingWrapperStyle}>\n      {props.hasMask && <div css={maskStyle} />}\n      <Loading colorScheme=\"techPurple\" />\n    </div>\n  )\n}\n\nFullPageLoading.displayName = \"FullPageLoading\"\n"
  },
  {
    "path": "apps/builder/src/components/FullPageLoading/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const fullPageLoadingWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  position: absolute;\n  left: 0;\n  top: 0;\n  bottom: 0;\n  right: 0;\n`\n\nexport const maskStyle = css`\n  position: absolute;\n  left: 0;\n  top: 0;\n  bottom: 0;\n  right: 0;\n  opacity: 0.7;\n  background-color: white;\n`\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuideCreateApp/CreateModal/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { useTranslation } from \"react-i18next\"\nimport { AddIcon, CloseIcon, Modal, getColor } from \"@illa-design/react\"\nimport {\n  closeIconStyle,\n  containerStyle,\n  createOptionsContainerStyle,\n  descStyle,\n  headerStyle,\n  iconStyle,\n  operateContainerStyle,\n  titleStyle,\n} from \"./style\"\n\ninterface CreateModalProps {\n  closeGuideCreateAppModal: () => void\n  openCreateFromResourceModal: () => void\n  openCreateFromTemplateModal: () => void\n}\n\nconst CreateModal: FC<CreateModalProps> = ({\n  closeGuideCreateAppModal,\n  openCreateFromResourceModal,\n  openCreateFromTemplateModal,\n}) => {\n  const { t } = useTranslation()\n  return createPortal(\n    <Modal\n      visible\n      footer={false}\n      minW=\"464px\"\n      w=\"464px\"\n      closable\n      onCancel={closeGuideCreateAppModal}\n      withoutPadding\n    >\n      <div css={containerStyle}>\n        <span css={closeIconStyle}>\n          <IconHotSpot onClick={closeGuideCreateAppModal}>\n            <CloseIcon size=\"12px\" color={getColor(\"grayBlue\", \"02\")} />\n          </IconHotSpot>\n        </span>\n        <div css={headerStyle}>\n          <span css={titleStyle}>\n            {t(\"editor.tutorial.panel.onboarding_app.congratulations_title\")}\n          </span>\n          <span css={descStyle}>\n            {t(\"new_dashboard.create_new.onboarding_cloud\")}\n          </span>\n        </div>\n        <div css={operateContainerStyle}>\n          <div\n            css={createOptionsContainerStyle(getColor(\"techPurple\", \"03\"))}\n            onClick={openCreateFromTemplateModal}\n          >\n            <span css={iconStyle}>\n              <AddIcon size=\"16px\" />\n            </span>\n            <span>{t(\"new_dashboard.create_new.create_from_template\")}</span>\n          </div>\n          <div\n            css={createOptionsContainerStyle(\"#1AB0F1\")}\n            onClick={openCreateFromResourceModal}\n          >\n            <span css={iconStyle}>\n              <AddIcon size=\"16px\" />\n            </span>\n            <span>{t(\"new_dashboard.create_new.generate_crud_short\")}</span>\n          </div>\n        </div>\n      </div>\n    </Modal>,\n    document.body,\n  )\n}\n\nexport default CreateModal\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuideCreateApp/CreateModal/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const containerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n  padding: 24px;\n  position: relative;\n`\n\nexport const headerStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n`\n\nexport const closeIconStyle = css`\n  position: absolute;\n  right: 24px;\n  top: 24px;\n  width: 24px;\n  height: 24px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n`\n\nexport const titleStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 16px;\n  font-weight: 500;\n  line-height: 24px;\n`\n\nexport const descStyle = css`\n  color: ${getColor(\"grayBlue\", \"03\")};\n  font-size: 14px;\n  font-weight: 400;\n  line-height: 22px;\n`\n\nexport const operateContainerStyle = css`\n  width: 100%;\n  display: flex;\n  gap: 16px;\n`\n\nexport const createOptionsContainerStyle = (bgColor: string) => css`\n  display: flex;\n  color: ${getColor(\"white\", \"01\")};\n  border-radius: 8px;\n  align-items: center;\n  background-color: ${bgColor};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 22px;\n  cursor: pointer;\n  height: 118px;\n  width: 200px;\n  padding: 24px;\n  flex-direction: column;\n  text-align: center;\n  gap: 8px;\n`\nexport const iconStyle = css`\n  display: flex;\n  padding: 12px;\n  width: 40px;\n  height: 40px;\n  justify-content: center;\n  align-items: center;\n  gap: 8px;\n  border-radius: 50%;\n  background-color: ${getColor(\"white\", \"07\")};\n  position: relative;\n`\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuideCreateApp/index.tsx",
    "content": "import {\n  BuildActionInfo,\n  CreateFromResourceModal,\n  CreateFromTemplateModal,\n  REPORT_PARAMETER,\n  REPORT_TEMPLATE_STATUS,\n  RESOURCE_TYPE,\n  fetchBatchCreateAction,\n} from \"@illa-public/create-app\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport { ComponentTreeNode, Resource } from \"@illa-public/public-types\"\nimport { getAuthToken, getILLABuilderURL } from \"@illa-public/utils\"\nimport { AnimatePresence } from \"framer-motion\"\nimport { FC, useCallback, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { useMessage } from \"@illa-design/react\"\nimport { guideActions } from \"@/redux/guide/guideSlice\"\nimport { getAllResources } from \"@/redux/resource/resourceSelector\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { fetchCreateApp, fetchForkApp } from \"@/services/apps\"\nimport { resourceContextHelper, track } from \"@/utils/mixpanelHelper\"\nimport { getCurrentTeamID } from \"@/utils/team\"\nimport CreateModal from \"./CreateModal\"\n\nconst GuideCreateApp: FC = () => {\n  const message = useMessage()\n  const teamID = useSelector(getCurrentTeamID)!\n  const { teamIdentifier } = useParams()\n  const resourceList = useSelector(getAllResources) || []\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n  const [showCreateFromResourceModal, setShowCreateFromResourceModal] =\n    useState(false)\n\n  const [showCreateFromTemplateModal, setShowCreateFromTemplateModal] =\n    useState(false)\n\n  const closeGuideCreateAppModal = () => {\n    dispatch(guideActions.updateGuideStatusReducer(false))\n  }\n\n  const forkApp = async (appID: string) => {\n    track?.(\n      ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n      ILLA_MIXPANEL_BUILDER_PAGE_NAME.TUTORIAL,\n      {\n        element: \"create_app_modal_use_template\",\n        parameter1: REPORT_PARAMETER.BLANK_TUTORIAL_APP,\n      },\n    )\n    try {\n      const resp = await fetchForkApp(appID)\n      window.open(\n        `${getILLABuilderURL(window.customDomain)}/${teamIdentifier}/app/${\n          resp.data.appId\n        }?token=${getAuthToken()}`,\n        \"_blank\",\n      )\n    } catch (e) {\n      message.error({ content: t(\"create_fail\") })\n    } finally {\n      closeGuideCreateAppModal()\n    }\n  }\n\n  const handleUpdateResource = useCallback(\n    (resource: Resource) => {\n      dispatch(resourceActions.addResourceItemReducer(resource))\n    },\n    [dispatch],\n  )\n\n  const createFromResource = async (\n    appInfo: ComponentTreeNode,\n    actionsInfo: BuildActionInfo[],\n  ) => {\n    try {\n      const resp = await fetchCreateApp({\n        appName: \"Untitled app\",\n        initScheme: appInfo,\n      })\n      await fetchBatchCreateAction(teamID, resp.data.appId, actionsInfo)\n      window.open(\n        `${getILLABuilderURL(window.customDomain)}/${teamIdentifier}/app/${\n          resp.data.appId\n        }?token=${getAuthToken()}`,\n        \"_blank\",\n      )\n    } catch (e) {\n      message.error({ content: t(\"create_fail\") })\n    } finally {\n      closeGuideCreateAppModal()\n    }\n  }\n\n  return (\n    <AnimatePresence>\n      <CreateModal\n        closeGuideCreateAppModal={closeGuideCreateAppModal}\n        openCreateFromResourceModal={() => {\n          track?.(\n            ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n            ILLA_MIXPANEL_BUILDER_PAGE_NAME.TUTORIAL,\n            {\n              element: \"create_app_modal_db\",\n              parameter1: REPORT_PARAMETER.BLANK_TUTORIAL_APP,\n            },\n          )\n          setShowCreateFromResourceModal(true)\n        }}\n        openCreateFromTemplateModal={() => {\n          track?.(\n            ILLA_MIXPANEL_EVENT_TYPE.SHOW,\n            ILLA_MIXPANEL_BUILDER_PAGE_NAME.TUTORIAL,\n            {\n              element: \"create_app_modal\",\n              parameter1: REPORT_PARAMETER.CREATE_APP_MODAL,\n            },\n          )\n          setShowCreateFromTemplateModal(true)\n        }}\n      />\n      {showCreateFromResourceModal && (\n        <MixpanelTrackProvider\n          basicTrack={resourceContextHelper(\n            REPORT_PARAMETER.TUTORIAL_APP_CREATE,\n          )}\n          pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.TUTORIAL}\n        >\n          <CreateFromResourceModal\n            updateResourceList={handleUpdateResource}\n            resourceList={resourceList.filter((item) =>\n              Object.values(RESOURCE_TYPE).includes(\n                item?.resourceType as RESOURCE_TYPE,\n              ),\n            )}\n            createCallBack={createFromResource}\n            closeModal={() => setShowCreateFromResourceModal(false)}\n          />\n        </MixpanelTrackProvider>\n      )}\n      {showCreateFromTemplateModal && (\n        <CreateFromTemplateModal\n          hiddenCreateBlank\n          handleForkApp={async (appID: string) => {\n            track?.(\n              ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n              ILLA_MIXPANEL_BUILDER_PAGE_NAME.TUTORIAL,\n              {\n                element: \"create_app_modal_use_template\",\n                parameter1: REPORT_PARAMETER.CREATE_APP_MODAL,\n                parameter2: REPORT_TEMPLATE_STATUS.IS_MODAL_TEMPLATE,\n                parameter5: appID,\n              },\n            )\n            await forkApp(appID)\n          }}\n          closeModal={() => setShowCreateFromTemplateModal(false)}\n        />\n      )}\n    </AnimatePresence>\n  )\n}\n\nexport default GuideCreateApp\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuideDraggablePopover/index.tsx",
    "content": "import { motion } from \"framer-motion\"\nimport { FC, useMemo } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { applyPopoverStyle } from \"@/components/Guide/GuideDraggablePopover/style\"\nimport { GuidePopover } from \"@/components/Guide/GuidePopover\"\nimport { GUIDE_STEP } from \"@/config/guide/config\"\n\nexport type CurrentMaskPosition = \"top\" | \"bottom\" | \"right\"\n\nexport interface GuideCurrentMaskProps {\n  currentStep: number\n  position?: CurrentMaskPosition\n}\n\nexport const GuideDraggablePopover: FC<GuideCurrentMaskProps> = (props) => {\n  const { currentStep, position = \"bottom\" } = props\n  const { selector, titleKey, descKey, hideExit, doItForMe } =\n    GUIDE_STEP[currentStep]\n  const isLastStep = useMemo(\n    () => currentStep === GUIDE_STEP.length - 1,\n    [currentStep],\n  )\n\n  const domRect = useMemo(() => {\n    if (selector) {\n      const element = document.querySelector(selector)\n      return element?.getBoundingClientRect()\n    }\n  }, [selector])\n\n  return createPortal(\n    <motion.div\n      css={applyPopoverStyle(position, domRect)}\n      drag\n      dragMomentum={false}\n    >\n      <GuidePopover\n        title={titleKey}\n        description={descKey}\n        hideExit={hideExit}\n        isLastStep={isLastStep}\n        onClickDoIt={doItForMe}\n      />\n    </motion.div>,\n    document.body,\n  )\n}\n\nGuideDraggablePopover.displayName = \"GuideDraggablePopover\"\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuideDraggablePopover/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { CurrentMaskPosition } from \"@/components/Guide/GuideDraggablePopover/index\"\n\nconst POPOVER_MARGIN = 14\n\nconst applyTriangleStyle = (position: CurrentMaskPosition) => {\n  if (position === \"right\") return css``\n  // only show triangle for top and bottom\n  const positionStyle =\n    position === \"top\"\n      ? css`\n          bottom: -5px;\n          border-width: 6px 6px 0 6px;\n          border-color: ${getColor(\"techPurple\", \"03\")} transparent transparent\n            transparent;\n        `\n      : css`\n          top: -5px;\n          border-width: 0 6px 6px 6px;\n          border-color: transparent transparent ${getColor(\"techPurple\", \"03\")}\n            transparent;\n        `\n  return css`\n    &::before {\n      content: \"\";\n      position: absolute;\n      ${positionStyle};\n      left: 50%;\n      transform: translateX(-50%);\n      width: 0;\n      height: 0;\n      border-style: solid;\n    }\n  `\n}\n\nexport const applyPopoverStyle = (\n  position: CurrentMaskPosition,\n  domRect?: DOMRect,\n) => {\n  const positionStyle = domRect\n    ? position === \"top\"\n      ? css`\n          bottom: ${window.innerHeight - domRect?.top + POPOVER_MARGIN}px;\n          left: ${domRect?.left - 60}px;\n        `\n      : position === \"right\"\n        ? css`\n            top: ${domRect?.top + POPOVER_MARGIN}px;\n            left: ${domRect?.left - domRect?.width}px;\n          `\n        : css`\n            top: ${domRect?.bottom + POPOVER_MARGIN}px;\n            left: ${domRect?.left - domRect?.width}px;\n          `\n    : css``\n\n  return css`\n    cursor: move;\n    z-index: 11;\n    position: absolute;\n    background-color: ${getColor(\"techPurple\", \"03\")};\n    color: ${getColor(\"white\", \"01\")};\n    padding: 8px 12px;\n    border-radius: 2px;\n    ${positionStyle};\n    ${applyTriangleStyle(position)};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuidePoint/index.tsx",
    "content": "import Lottie from \"lottie-react\"\nimport { FC, HTMLAttributes } from \"react\"\nimport { popoverStyle } from \"@/components/Guide/GuidePoint/style\"\nimport animationData from \"@/components/Guide/assets/lottie/point.json\"\n\nexport const GuidePoint: FC<HTMLAttributes<HTMLDivElement>> = (props) => {\n  return (\n    <div css={popoverStyle} {...props}>\n      <Lottie animationData={animationData} loop={true} autoplay={true} />\n    </div>\n  )\n}\n\nGuidePoint.displayName = \"GuidePoint\"\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuidePoint/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const popoverStyle = css`\n  width: 32px;\n  height: 32px;\n  z-index: 2;\n  position: absolute;\n  top: 0;\n  left: 50%;\n  transform: translateX(-50%);\n  pointer-events: none;\n`\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuidePopover/index.tsx",
    "content": "import { TextLink } from \"@illa-public/text-link\"\nimport { FC, HTMLAttributes } from \"react\"\nimport { Trans, useTranslation } from \"react-i18next\"\nimport { useDispatch } from \"react-redux\"\nimport { useModal } from \"@illa-design/react\"\nimport {\n  actionStyle,\n  applyHiddenStyle,\n  buttonStyle,\n  decsStyle,\n  guidePopoverStyle,\n  linkStyle,\n  titleStyle,\n} from \"@/components/Guide/GuidePopover/style\"\nimport { guideActions } from \"@/redux/guide/guideSlice\"\nimport { openDiscord } from \"@/utils/navigate\"\n\nexport interface GuidePopoverProps extends HTMLAttributes<HTMLDivElement> {\n  title: string\n  description: string\n  hideExit?: boolean\n  isLastStep?: boolean\n  onClickDoIt?: () => void\n}\n\nexport const GuidePopover: FC<GuidePopoverProps> = (props) => {\n  const { title, description, hideExit, isLastStep, onClickDoIt, ...rest } =\n    props\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n\n  const modal = useModal()\n\n  const handleExitGuide = () => {\n    modal.show({\n      id: \"exitGuide\",\n      title: t(\"tutorial.modal.tutorial.exit_confirm.title\"),\n      children: t(\"tutorial.modal.tutorial.exit_confirm.description\"),\n      cancelText: t(\"tutorial.modal.tutorial.exit_confirm.cancel\"),\n      okText: t(\"tutorial.modal.tutorial.exit_confirm.exit\"),\n      okButtonProps: {\n        colorScheme: \"techPurple\",\n      },\n      onOk: () => {\n        dispatch(guideActions.updateGuideStatusReducer(false))\n      },\n    })\n  }\n\n  return (\n    <div css={guidePopoverStyle} {...rest}>\n      <div css={titleStyle}>{t(title)}</div>\n      <div css={decsStyle}>\n        <Trans\n          i18nKey={description}\n          t={t}\n          components={[\n            <TextLink\n              key=\"openDiscord\"\n              css={linkStyle}\n              onClick={openDiscord}\n            />,\n          ]}\n        />\n      </div>\n      <div css={actionStyle}>\n        <span\n          css={[buttonStyle, applyHiddenStyle(isLastStep || hideExit)]}\n          onClick={handleExitGuide}\n        >\n          {t(\"editor.tutorial.panel.onboarding_app.exit\")}\n        </span>\n        <span\n          css={[buttonStyle]}\n          onClick={() => {\n            onClickDoIt?.()\n          }}\n        >\n          {isLastStep\n            ? t(\"editor.tutorial.panel.onboarding_app.congratulations_button\")\n            : hideExit\n              ? t(\"editor.tutorial.panel.onboarding_app.test_it_button\")\n              : t(\"editor.tutorial.panel.onboarding_app.do_it\")}\n        </span>\n      </div>\n    </div>\n  )\n}\n\nGuidePopover.displayName = \"GuidePopover\"\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuidePopover/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const topStyle = css`\n  position: absolute;\n  top: 0;\n  transform: translateY(calc(-100% - 20px));\n  z-index: 2;\n  color: ${getColor(\"white\", \"01\")};\n  padding: 16px;\n  border-radius: 2px;\n`\nexport const bottomStyle = css`\n  position: absolute;\n  top: calc(100% + 10px);\n  z-index: 2;\n  color: ${getColor(\"white\", \"01\")};\n  padding: 16px;\n  border-radius: 2px;\n`\n\nexport const guidePopoverStyle = css`\n  background-color: ${getColor(\"techPurple\", \"03\")};\n  padding: 8px 4px;\n  max-width: 264px;\n`\n\nexport const titleStyle = css`\n  font-weight: 500;\n  font-size: 16px;\n  line-height: 24px;\n`\n\nexport const decsStyle = css`\n  margin-top: 8px;\n  margin-bottom: 16px;\n  font-weight: 400;\n  font-size: 14px;\n  line-height: 22px;\n  word-break: break-all;\n  white-space: pre-wrap;\n  text-overflow: ellipsis;\n  overflow: hidden;\n`\n\nexport const linkStyle = css`\n  color: ${getColor(\"white\", \"01\")};\n  text-decoration: underline;\n`\n\nexport const actionStyle = css`\n  display: flex;\n  justify-content: space-between;\n`\n\nexport const triggerStyle = css`\n  & > div > div {\n    & > div {\n      background-color: ${getColor(\"techPurple\", \"03\")};\n      border-radius: 2px;\n    }\n\n    & > svg {\n      color: ${getColor(\"techPurple\", \"03\")};\n    }\n  }\n`\n\nexport const applyHiddenStyle = (hide?: boolean) => {\n  return css`\n    visibility: ${hide ? \"hidden\" : \"visible\"};\n  `\n}\n\nexport const buttonStyle = css`\n  padding: 0 2px;\n  cursor: pointer;\n  font-weight: 500;\n  font-size: 14px;\n  line-height: 22px;\n  color: ${getColor(\"white\", \"01\")};\n`\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuideSuccess/index.tsx",
    "content": "import Lottie from \"lottie-react\"\nimport { FC, useState } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { popoverStyle } from \"@/components/Guide/GuideSuccess/style\"\nimport animationData from \"@/components/Guide/assets/lottie/success.json\"\n\nexport const GuideSuccess: FC = () => {\n  const [showAnimation, setShowAnimation] = useState(true)\n\n  const handleAnimationComplete = () => {\n    setShowAnimation(false)\n  }\n\n  return showAnimation\n    ? createPortal(\n        <div css={popoverStyle}>\n          <Lottie\n            animationData={animationData}\n            loop={false}\n            autoplay={true}\n            onComplete={handleAnimationComplete}\n          />\n        </div>,\n        document.body,\n      )\n    : null\n}\n\nGuideSuccess.displayName = \"GuideSuccess\"\n"
  },
  {
    "path": "apps/builder/src/components/Guide/GuideSuccess/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const popoverStyle = css`\n  position: absolute;\n  top: 0;\n  left: 50%;\n  transform: translateX(-50%);\n  z-index: 2;\n`\n"
  },
  {
    "path": "apps/builder/src/components/Guide/WidgetStepMask/index.tsx",
    "content": "import { FC, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport {\n  applyStepMaskStyle,\n  applyStepMaskWrapperStyle,\n  applyVisibleStyle,\n  ellipsisStyle,\n  moveIconStyle,\n  stepFirstLineStyle,\n} from \"@/components/Guide/WidgetStepMask/style\"\nimport MoveIcon from \"@/components/Guide/assets/move.svg?react\"\nimport { GUIDE_SELECT_WIDGET } from \"@/config/guide/config\"\nimport {\n  DEFAULT_BODY_COLUMNS_NUMBER,\n  UNIT_HEIGHT,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getCanvasShape } from \"@/redux/config/configSelector\"\nimport { widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\n\nexport interface StepMaskProps {\n  currentStep: number\n}\n\nexport const WidgetStepMask: FC<StepMaskProps> = (props) => {\n  const { t } = useTranslation()\n\n  const { currentStep } = props\n  const canvasShape = useSelector(getCanvasShape)\n\n  const unitWidth = useMemo(() => {\n    return canvasShape.canvasWidth / DEFAULT_BODY_COLUMNS_NUMBER\n  }, [canvasShape.canvasWidth])\n\n  const widgetShape = useMemo(() => {\n    return GUIDE_SELECT_WIDGET.map((widget) => {\n      const { w, h } = widgetBuilder(widget).config\n      return {\n        width: w * unitWidth,\n        height: h * UNIT_HEIGHT,\n      }\n    })\n  }, [unitWidth])\n\n  const applyMaskStyle = (step: number) => {\n    return [\n      applyStepMaskStyle(widgetShape[step]),\n      applyVisibleStyle(currentStep <= step),\n    ]\n  }\n\n  return (\n    <div css={applyStepMaskWrapperStyle(currentStep <= 2, unitWidth)}>\n      <div css={stepFirstLineStyle}>\n        <div css={applyMaskStyle(0)}>\n          <MoveIcon css={moveIconStyle} />\n          <span css={ellipsisStyle}>\n            {t(\"editor.tutorial.panel.onboarding_app.drag_input\")}\n          </span>\n        </div>\n        <div css={applyMaskStyle(1)}>\n          <MoveIcon css={moveIconStyle} />\n          <span css={ellipsisStyle}>\n            {t(\"editor.tutorial.panel.onboarding_app.drag_button\")}\n          </span>\n        </div>\n      </div>\n      <div css={applyMaskStyle(2)}>\n        <MoveIcon css={moveIconStyle} />\n        <span css={ellipsisStyle}>\n          {t(\"editor.tutorial.panel.onboarding_app.drag_table\")}\n        </span>\n      </div>\n    </div>\n  )\n}\n\nWidgetStepMask.displayName = \"WidgetStepMask\"\n"
  },
  {
    "path": "apps/builder/src/components/Guide/WidgetStepMask/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\n\nexport const applyStepMaskWrapperStyle = (\n  visible: boolean,\n  unitWidth: number,\n) => {\n  return css`\n    display: ${visible ? \"flex\" : \"none\"};\n    flex-direction: column;\n    position: absolute;\n    top: ${unitWidth * 5}px;\n    left: 50%;\n    transform: translate(-50%, 0);\n    gap: ${UNIT_HEIGHT * 3}px;\n    pointer-events: none;\n    font-size: 14px;\n  `\n}\n\nexport const stepMaskStyle = css`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  background: ${getColor(\"techPurple\", \"08\")};\n  border: 1px dashed ${getColor(\"techPurple\", \"03\")};\n`\n\n// transform stepMaskStyle to function, set {width, height}\nexport const applyStepMaskStyle = (shape: {\n  width: number\n  height: number\n}) => {\n  const { width, height } = shape\n  return css`\n    width: ${width}px;\n    height: ${height}px;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    color: ${getColor(\"grayBlue\", \"04\")};\n    background: ${getColor(\"techPurple\", \"08\")};\n    border: 1px dashed ${getColor(\"techPurple\", \"03\")};\n  `\n}\n\nexport const moveIconStyle = css`\n  width: 24px;\n  height: 24px;\n  margin-right: 4px;\n  flex-shrink: 0;\n`\n\nexport const ellipsisStyle = css`\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  overflow: hidden;\n`\n\nexport const stepFirstLineStyle = css`\n  display: flex;\n  justify-content: space-between;\n`\n\n// hidden function, use visible to control\nexport const applyVisibleStyle = (visible: boolean) => {\n  return css`\n    visibility: ${visible ? \"visible\" : \"hidden\"};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/components/Guide/assets/lottie/point.json",
    "content": "{\n  \"v\": \"5.8.1\",\n  \"fr\": 60,\n  \"ip\": 0,\n  \"op\": 90,\n  \"w\": 32,\n  \"h\": 32,\n  \"nm\": \"Lottie guide point\",\n  \"ddd\": 0,\n  \"assets\": [],\n  \"layers\": [\n    {\n      \"ddd\": 0,\n      \"ind\": 1,\n      \"ty\": 4,\n      \"nm\": \"top\",\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100,\n          \"ix\": 11\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            16,\n            16,\n            0\n          ],\n          \"ix\": 2,\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ],\n          \"ix\": 6,\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"shapes\": [\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"d\": 1,\n              \"ty\": \"el\",\n              \"s\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"i\": {\n                      \"x\": [\n                        0.675,\n                        0.675\n                      ],\n                      \"y\": [\n                        0.573,\n                        0.573\n                      ]\n                    },\n                    \"o\": {\n                      \"x\": [\n                        0.667,\n                        0.667\n                      ],\n                      \"y\": [\n                        0,\n                        0\n                      ]\n                    },\n                    \"t\": 0,\n                    \"s\": [\n                      0,\n                      0\n                    ]\n                  },\n                  {\n                    \"i\": {\n                      \"x\": [\n                        0.533,\n                        0.533\n                      ],\n                      \"y\": [\n                        1,\n                        1\n                      ]\n                    },\n                    \"o\": {\n                      \"x\": [\n                        0.228,\n                        0.228\n                      ],\n                      \"y\": [\n                        0.299,\n                        0.299\n                      ]\n                    },\n                    \"t\": 40,\n                    \"s\": [\n                      8,\n                      8\n                    ]\n                  },\n                  {\n                    \"t\": 60,\n                    \"s\": [\n                      12,\n                      12\n                    ]\n                  }\n                ],\n                \"ix\": 2\n              },\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 3\n              },\n              \"nm\": \"椭圆路径 1\",\n              \"mn\": \"ADBE Vector Shape - Ellipse\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0.396077982585,\n                  0.290195988674,\n                  0.925490016563,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"i\": {\n                      \"x\": [\n                        0.4\n                      ],\n                      \"y\": [\n                        1\n                      ]\n                    },\n                    \"o\": {\n                      \"x\": [\n                        0.6\n                      ],\n                      \"y\": [\n                        0\n                      ]\n                    },\n                    \"t\": 40,\n                    \"s\": [\n                      100\n                    ]\n                  },\n                  {\n                    \"t\": 60,\n                    \"s\": [\n                      0\n                    ]\n                  }\n                ],\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"填充 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"变换\"\n            }\n          ],\n          \"nm\": \"椭圆 1\",\n          \"np\": 3,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 1,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        }\n      ],\n      \"ip\": 0,\n      \"op\": 180,\n      \"st\": 0,\n      \"bm\": 0\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 2,\n      \"ty\": 4,\n      \"nm\": \"bottom\",\n      \"sr\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100,\n          \"ix\": 11\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            16,\n            16,\n            0\n          ],\n          \"ix\": 2,\n          \"l\": 2\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0,\n            0\n          ],\n          \"ix\": 1,\n          \"l\": 2\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ],\n          \"ix\": 6,\n          \"l\": 2\n        }\n      },\n      \"ao\": 0,\n      \"shapes\": [\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"d\": 1,\n              \"ty\": \"el\",\n              \"s\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"i\": {\n                      \"x\": [\n                        0.4,\n                        0.4\n                      ],\n                      \"y\": [\n                        1,\n                        1\n                      ]\n                    },\n                    \"o\": {\n                      \"x\": [\n                        0.6,\n                        0.6\n                      ],\n                      \"y\": [\n                        0,\n                        0\n                      ]\n                    },\n                    \"t\": 0,\n                    \"s\": [\n                      0,\n                      0\n                    ]\n                  },\n                  {\n                    \"t\": 60,\n                    \"s\": [\n                      32,\n                      32\n                    ]\n                  }\n                ],\n                \"ix\": 2\n              },\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 3\n              },\n              \"nm\": \"椭圆路径 1\",\n              \"mn\": \"ADBE Vector Shape - Ellipse\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"fl\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  0.396077982585,\n                  0.290195988674,\n                  0.925490016563,\n                  1\n                ],\n                \"ix\": 4\n              },\n              \"o\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"i\": {\n                      \"x\": [\n                        0.4\n                      ],\n                      \"y\": [\n                        1\n                      ]\n                    },\n                    \"o\": {\n                      \"x\": [\n                        0.6\n                      ],\n                      \"y\": [\n                        0\n                      ]\n                    },\n                    \"t\": 40,\n                    \"s\": [\n                      16\n                    ]\n                  },\n                  {\n                    \"t\": 60,\n                    \"s\": [\n                      0\n                    ]\n                  }\n                ],\n                \"ix\": 5\n              },\n              \"r\": 1,\n              \"bm\": 0,\n              \"nm\": \"填充 1\",\n              \"mn\": \"ADBE Vector Graphic - Fill\",\n              \"hd\": false\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"变换\"\n            }\n          ],\n          \"nm\": \"椭圆 1\",\n          \"np\": 3,\n          \"cix\": 2,\n          \"bm\": 0,\n          \"ix\": 1,\n          \"mn\": \"ADBE Vector Group\",\n          \"hd\": false\n        }\n      ],\n      \"ip\": 0,\n      \"op\": 180,\n      \"st\": 0,\n      \"bm\": 0\n    }\n  ],\n  \"markers\": []\n}"
  },
  {
    "path": "apps/builder/src/components/Guide/assets/lottie/success.json",
    "content": "{\n  \"nm\": \"lottie (mobile)\",\n  \"ddd\": 0,\n  \"h\": 812,\n  \"w\": 609,\n  \"meta\": {\n    \"g\": \"@lottiefiles/toolkit-js 0.25.4\"\n  },\n  \"layers\": [\n    {\n      \"ty\": 0,\n      \"nm\": \"cannon (small - left)\",\n      \"sr\": 1,\n      \"st\": 0,\n      \"op\": 300,\n      \"ip\": 0,\n      \"hd\": false,\n      \"ddd\": 0,\n      \"bm\": 0,\n      \"hasMask\": false,\n      \"ao\": 0,\n      \"ks\": {\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            360,\n            0\n          ],\n          \"ix\": 1\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ],\n          \"ix\": 6\n        },\n        \"sk\": {\n          \"a\": 0,\n          \"k\": 0\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            76,\n            451.99999999999994,\n            0\n          ],\n          \"ix\": 2\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"sa\": {\n          \"a\": 0,\n          \"k\": 0\n        },\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100,\n          \"ix\": 11\n        }\n      },\n      \"ef\": [],\n      \"w\": 480,\n      \"h\": 720,\n      \"refId\": \"comp_0\",\n      \"ind\": 1\n    },\n    {\n      \"ty\": 0,\n      \"nm\": \"cannon (small - right)\",\n      \"sr\": 1,\n      \"st\": 0,\n      \"op\": 300,\n      \"ip\": 0,\n      \"hd\": false,\n      \"ddd\": 0,\n      \"bm\": 0,\n      \"hasMask\": false,\n      \"ao\": 0,\n      \"ks\": {\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            479.994,\n            360,\n            0\n          ],\n          \"ix\": 1\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ],\n          \"ix\": 6\n        },\n        \"sk\": {\n          \"a\": 0,\n          \"k\": 0\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            533,\n            451.99999999999994,\n            0\n          ],\n          \"ix\": 2\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"sa\": {\n          \"a\": 0,\n          \"k\": 0\n        },\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100,\n          \"ix\": 11\n        }\n      },\n      \"ef\": [],\n      \"w\": 480,\n      \"h\": 720,\n      \"refId\": \"comp_2\",\n      \"ind\": 2\n    },\n    {\n      \"ty\": 0,\n      \"nm\": \"cannon (small - top)\",\n      \"sr\": 1,\n      \"st\": 0,\n      \"op\": 300,\n      \"ip\": 0,\n      \"hd\": false,\n      \"ddd\": 0,\n      \"bm\": 0,\n      \"hasMask\": false,\n      \"ao\": 0,\n      \"ks\": {\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            400,\n            400,\n            0\n          ],\n          \"ix\": 1\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            102,\n            102,\n            100\n          ],\n          \"ix\": 6\n        },\n        \"sk\": {\n          \"a\": 0,\n          \"k\": 0\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            304,\n            408,\n            0\n          ],\n          \"ix\": 2\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0,\n          \"ix\": 10\n        },\n        \"sa\": {\n          \"a\": 0,\n          \"k\": 0\n        },\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100,\n          \"ix\": 11\n        }\n      },\n      \"ef\": [],\n      \"w\": 800,\n      \"h\": 800,\n      \"refId\": \"comp_3\",\n      \"ind\": 3\n    }\n  ],\n  \"v\": \"5.5.6\",\n  \"fr\": 70,\n  \"op\": 370,\n  \"ip\": 0,\n  \"assets\": [\n    {\n      \"nm\": \"\",\n      \"id\": \"comp_0\",\n      \"layers\": [\n        {\n          \"ty\": 0,\n          \"nm\": \"_small-side\",\n          \"sr\": 1,\n          \"st\": 15,\n          \"op\": 234,\n          \"ip\": 15,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                400,\n                400,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                -100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 0,\n              \"k\": [\n                218,\n                320,\n                0\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 0,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"w\": 800,\n          \"h\": 800,\n          \"refId\": \"comp_1\",\n          \"ind\": 1\n        }\n      ]\n    },\n    {\n      \"nm\": \"\",\n      \"id\": \"comp_1\",\n      \"layers\": [\n        {\n          \"ty\": 4,\n          \"nm\": \"streamer b\",\n          \"sr\": 1,\n          \"st\": 9,\n          \"op\": 58,\n          \"ip\": 9,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -157,\n                -245,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 0,\n              \"k\": [\n                554,\n                664,\n                0\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 166,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Shape 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sh\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"nm\": \"Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"c\": false,\n                      \"i\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.685,\n                          -13.314\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          1.754,\n                          -14.206\n                        ],\n                        [\n                          -3.934,\n                          -9.465\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          -3.895,\n                          8.562\n                        ],\n                        [\n                          1.872,\n                          14.789\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.314\n                        ],\n                        [\n                          -1.803,\n                          14.605\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -156.5,\n                          -406\n                        ],\n                        [\n                          -166.5,\n                          -367\n                        ],\n                        [\n                          -146.5,\n                          -327\n                        ],\n                        [\n                          -166.5,\n                          -286\n                        ],\n                        [\n                          -146.5,\n                          -246\n                        ],\n                        [\n                          -166.5,\n                          -206\n                        ],\n                        [\n                          -146.5,\n                          -165\n                        ],\n                        [\n                          -166.5,\n                          -127\n                        ],\n                        [\n                          -156.5,\n                          -84\n                        ]\n                      ]\n                    },\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"st\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"nm\": \"Stroke 1\",\n                  \"lc\": 2,\n                  \"lj\": 2,\n                  \"ml\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 1,\n                    \"k\": [\n                      {\n                        \"o\": {\n                          \"x\": 0.167,\n                          \"y\": 0.167\n                        },\n                        \"i\": {\n                          \"x\": 0.833,\n                          \"y\": 0.833\n                        },\n                        \"s\": [\n                          4\n                        ],\n                        \"t\": 9\n                      },\n                      {\n                        \"s\": [\n                          0.5\n                        ],\n                        \"t\": 57\n                      }\n                    ],\n                    \"ix\": 5\n                  },\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 3\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            },\n            {\n              \"ty\": \"tm\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Filter - Trim\",\n              \"nm\": \"Trim Paths 1\",\n              \"ix\": 2,\n              \"e\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 9\n                  },\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.667,\n                      \"y\": 1\n                    },\n                    \"s\": [\n                      35\n                    ],\n                    \"t\": 14\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 57\n                  }\n                ],\n                \"ix\": 2\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 3\n              },\n              \"s\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.667,\n                      \"y\": 1\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 14\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 57\n                  }\n                ],\n                \"ix\": 1\n              },\n              \"m\": 1\n            }\n          ],\n          \"ind\": 1\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"streamer a\",\n          \"sr\": 1,\n          \"st\": 5,\n          \"op\": 49,\n          \"ip\": 5,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -157,\n                -245,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                -100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 0,\n              \"k\": [\n                532,\n                582,\n                0\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 167,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Shape 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sh\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"nm\": \"Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"c\": false,\n                      \"i\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.685,\n                          -13.314\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          1.754,\n                          -14.206\n                        ],\n                        [\n                          -3.934,\n                          -9.465\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          -3.895,\n                          8.562\n                        ],\n                        [\n                          1.872,\n                          14.789\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.314\n                        ],\n                        [\n                          -1.803,\n                          14.605\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -156.5,\n                          -406\n                        ],\n                        [\n                          -166.5,\n                          -367\n                        ],\n                        [\n                          -146.5,\n                          -327\n                        ],\n                        [\n                          -166.5,\n                          -286\n                        ],\n                        [\n                          -146.5,\n                          -246\n                        ],\n                        [\n                          -166.5,\n                          -206\n                        ],\n                        [\n                          -146.5,\n                          -165\n                        ],\n                        [\n                          -166.5,\n                          -127\n                        ],\n                        [\n                          -156.5,\n                          -84\n                        ]\n                      ]\n                    },\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"st\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"nm\": \"Stroke 1\",\n                  \"lc\": 2,\n                  \"lj\": 2,\n                  \"ml\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 1,\n                    \"k\": [\n                      {\n                        \"o\": {\n                          \"x\": 0.167,\n                          \"y\": 0.167\n                        },\n                        \"i\": {\n                          \"x\": 0.833,\n                          \"y\": 0.833\n                        },\n                        \"s\": [\n                          4\n                        ],\n                        \"t\": 5\n                      },\n                      {\n                        \"s\": [\n                          0.5\n                        ],\n                        \"t\": 48\n                      }\n                    ],\n                    \"ix\": 5\n                  },\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 3\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            },\n            {\n              \"ty\": \"tm\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Filter - Trim\",\n              \"nm\": \"Trim Paths 1\",\n              \"ix\": 2,\n              \"e\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 5\n                  },\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.667,\n                      \"y\": 1\n                    },\n                    \"s\": [\n                      35\n                    ],\n                    \"t\": 10\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 48\n                  }\n                ],\n                \"ix\": 2\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 3\n              },\n              \"s\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.667,\n                      \"y\": 1\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 10\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 48\n                  }\n                ],\n                \"ix\": 1\n              },\n              \"m\": 1\n            }\n          ],\n          \"ind\": 2\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"circle a\",\n          \"sr\": 1,\n          \"st\": 1,\n          \"op\": 159,\n          \"ip\": 1,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 1\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 29\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 1,\n                  \"ti\": [\n                    46.667,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -30,\n                    -106.667,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    419.5,\n                    198,\n                    0\n                  ],\n                  \"t\": 29,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -46.667,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    319.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 158\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 1\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    321.019\n                  ],\n                  \"t\": 29\n                },\n                {\n                  \"s\": [\n                    1800\n                  ],\n                  \"t\": 158\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Ellipse 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"el\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Ellipse\",\n                  \"nm\": \"Ellipse Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 3\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"circle b\",\n          \"sr\": 1,\n          \"st\": 3,\n          \"op\": 129,\n          \"ip\": 3,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 3\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 21\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 98\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 3,\n                  \"ti\": [\n                    66.667,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -26.667,\n                    -93.333,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    439.5,\n                    278,\n                    0\n                  ],\n                  \"t\": 21,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -66.667,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    199.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 3\n                },\n                {\n                  \"s\": [\n                    1440\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Ellipse 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"el\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Ellipse\",\n                  \"nm\": \"Ellipse Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 4\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"star a\",\n          \"sr\": 1,\n          \"st\": 1,\n          \"op\": 159,\n          \"ip\": 1,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 1\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 31\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    596.087,\n                    836.292,\n                    0\n                  ],\n                  \"t\": 1,\n                  \"ti\": [\n                    52.765,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -36.098,\n                    -100,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    379.5,\n                    236.292,\n                    0\n                  ],\n                  \"t\": 31,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -52.765,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    279.5,\n                    836.292,\n                    0\n                  ],\n                  \"t\": 158\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 1\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    343.949\n                  ],\n                  \"t\": 31\n                },\n                {\n                  \"s\": [\n                    1800\n                  ],\n                  \"t\": 158\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Polystar 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sr\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Star\",\n                  \"nm\": \"Polystar Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ir\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 6\n                  },\n                  \"is\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 8\n                  },\n                  \"pt\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 3\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"or\": {\n                    \"a\": 0,\n                    \"k\": 12,\n                    \"ix\": 7\n                  },\n                  \"os\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 9\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"sy\": 1\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 5\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"star b\",\n          \"sr\": 1,\n          \"st\": 3,\n          \"op\": 129,\n          \"ip\": 3,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 3\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 23\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 98\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    596.087,\n                    836.292,\n                    0\n                  ],\n                  \"t\": 3,\n                  \"ti\": [\n                    66.098,\n                    1.667,\n                    0\n                  ],\n                  \"to\": [\n                    -39.431,\n                    -113.333,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    359.5,\n                    156.292,\n                    0\n                  ],\n                  \"t\": 23,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -66.098,\n                    -1.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    199.5,\n                    826.292,\n                    0\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 3\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    288\n                  ],\n                  \"t\": 23\n                },\n                {\n                  \"s\": [\n                    1800\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Polystar 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sr\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Star\",\n                  \"nm\": \"Polystar Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ir\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 6\n                  },\n                  \"is\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 8\n                  },\n                  \"pt\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 3\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"or\": {\n                    \"a\": 0,\n                    \"k\": 12,\n                    \"ix\": 7\n                  },\n                  \"os\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 9\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"sy\": 1\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0.9137,\n                      0.9882\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 6\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"rec a\",\n          \"sr\": 1,\n          \"st\": 0,\n          \"op\": 219,\n          \"ip\": 0,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 0\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 33\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 188\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    842,\n                    0\n                  ],\n                  \"t\": 0,\n                  \"ti\": [\n                    41.333,\n                    1.333,\n                    0\n                  ],\n                  \"to\": [\n                    -23.333,\n                    -100,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    459.5,\n                    242,\n                    0\n                  ],\n                  \"t\": 33,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -41.333,\n                    -1.333,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    351.5,\n                    834,\n                    0\n                  ],\n                  \"t\": 218\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 0\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    381.468\n                  ],\n                  \"t\": 33\n                },\n                {\n                  \"s\": [\n                    2520\n                  ],\n                  \"t\": 218\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      8\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      1,\n                      0.698,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 7\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"rec b\",\n          \"sr\": 1,\n          \"st\": 2,\n          \"op\": 192,\n          \"ip\": 2,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 25\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 161\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    842,\n                    0\n                  ],\n                  \"t\": 2,\n                  \"ti\": [\n                    74,\n                    5,\n                    0\n                  ],\n                  \"to\": [\n                    -23.333,\n                    -113.333,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    459.5,\n                    162,\n                    0\n                  ],\n                  \"t\": 25,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -74,\n                    -5,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    155.5,\n                    812,\n                    0\n                  ],\n                  \"t\": 191\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    262.857\n                  ],\n                  \"t\": 25\n                },\n                {\n                  \"s\": [\n                    2160\n                  ],\n                  \"t\": 191\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      8\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 8\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"square a\",\n          \"sr\": 1,\n          \"st\": 0,\n          \"op\": 219,\n          \"ip\": 0,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 0\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 35\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 188\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 0,\n                  \"ti\": [\n                    60,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -43.333,\n                    -123.333,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    339.5,\n                    98,\n                    0\n                  ],\n                  \"t\": 35,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -60,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    239.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 218\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 0\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    462.385\n                  ],\n                  \"t\": 35\n                },\n                {\n                  \"s\": [\n                    2880\n                  ],\n                  \"t\": 218\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0.9137,\n                      0.9882\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 9\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"square b\",\n          \"sr\": 1,\n          \"st\": 2,\n          \"op\": 192,\n          \"ip\": 2,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 27\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 161\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 2,\n                  \"ti\": [\n                    75,\n                    3.333,\n                    0\n                  ],\n                  \"to\": [\n                    -30,\n                    -120,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    419.5,\n                    118,\n                    0\n                  ],\n                  \"t\": 27,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -75,\n                    -3.333,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    149.5,\n                    818,\n                    0\n                  ],\n                  \"t\": 191\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    285.714\n                  ],\n                  \"t\": 27\n                },\n                {\n                  \"s\": [\n                    2160\n                  ],\n                  \"t\": 191\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 10\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"streamer b 2\",\n          \"sr\": 1,\n          \"st\": 13,\n          \"op\": 62,\n          \"ip\": 13,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -157,\n                -245,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 0,\n              \"k\": [\n                543,\n                427,\n                0\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 171,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Shape 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sh\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"nm\": \"Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"c\": false,\n                      \"i\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.685,\n                          -13.314\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          1.754,\n                          -14.206\n                        ],\n                        [\n                          -3.934,\n                          -9.465\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          -3.895,\n                          8.562\n                        ],\n                        [\n                          1.872,\n                          14.789\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.314\n                        ],\n                        [\n                          -1.803,\n                          14.605\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -156.5,\n                          -406\n                        ],\n                        [\n                          -166.5,\n                          -367\n                        ],\n                        [\n                          -146.5,\n                          -327\n                        ],\n                        [\n                          -166.5,\n                          -286\n                        ],\n                        [\n                          -146.5,\n                          -246\n                        ],\n                        [\n                          -166.5,\n                          -206\n                        ],\n                        [\n                          -146.5,\n                          -165\n                        ],\n                        [\n                          -166.5,\n                          -127\n                        ],\n                        [\n                          -156.5,\n                          -84\n                        ]\n                      ]\n                    },\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"st\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"nm\": \"Stroke 1\",\n                  \"lc\": 2,\n                  \"lj\": 2,\n                  \"ml\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 1,\n                    \"k\": [\n                      {\n                        \"o\": {\n                          \"x\": 0.167,\n                          \"y\": 0.167\n                        },\n                        \"i\": {\n                          \"x\": 0.833,\n                          \"y\": 0.833\n                        },\n                        \"s\": [\n                          4\n                        ],\n                        \"t\": 13\n                      },\n                      {\n                        \"s\": [\n                          0.5\n                        ],\n                        \"t\": 61\n                      }\n                    ],\n                    \"ix\": 5\n                  },\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      1,\n                      0.3608,\n                      0.7216\n                    ],\n                    \"ix\": 3\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            },\n            {\n              \"ty\": \"tm\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Filter - Trim\",\n              \"nm\": \"Trim Paths 1\",\n              \"ix\": 2,\n              \"e\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 13\n                  },\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.667,\n                      \"y\": 1\n                    },\n                    \"s\": [\n                      35\n                    ],\n                    \"t\": 18\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 61\n                  }\n                ],\n                \"ix\": 2\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 3\n              },\n              \"s\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.667,\n                      \"y\": 1\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 18\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 61\n                  }\n                ],\n                \"ix\": 1\n              },\n              \"m\": 1\n            }\n          ],\n          \"ind\": 11\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"streamer a 2\",\n          \"sr\": 1,\n          \"st\": 10,\n          \"op\": 54,\n          \"ip\": 10,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -157,\n                -245,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                -100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 0,\n              \"k\": [\n                454,\n                444,\n                0\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 151,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Shape 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sh\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"nm\": \"Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"c\": false,\n                      \"i\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.685,\n                          -13.314\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          1.754,\n                          -14.206\n                        ],\n                        [\n                          -3.934,\n                          -9.465\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          -3.895,\n                          8.562\n                        ],\n                        [\n                          1.872,\n                          14.789\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.314\n                        ],\n                        [\n                          -1.803,\n                          14.605\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -156.5,\n                          -406\n                        ],\n                        [\n                          -166.5,\n                          -367\n                        ],\n                        [\n                          -146.5,\n                          -327\n                        ],\n                        [\n                          -166.5,\n                          -286\n                        ],\n                        [\n                          -146.5,\n                          -246\n                        ],\n                        [\n                          -166.5,\n                          -206\n                        ],\n                        [\n                          -146.5,\n                          -165\n                        ],\n                        [\n                          -166.5,\n                          -127\n                        ],\n                        [\n                          -156.5,\n                          -84\n                        ]\n                      ]\n                    },\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"st\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"nm\": \"Stroke 1\",\n                  \"lc\": 2,\n                  \"lj\": 2,\n                  \"ml\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 1,\n                    \"k\": [\n                      {\n                        \"o\": {\n                          \"x\": 0.167,\n                          \"y\": 0.167\n                        },\n                        \"i\": {\n                          \"x\": 0.833,\n                          \"y\": 0.833\n                        },\n                        \"s\": [\n                          4\n                        ],\n                        \"t\": 10\n                      },\n                      {\n                        \"s\": [\n                          0.5\n                        ],\n                        \"t\": 53\n                      }\n                    ],\n                    \"ix\": 5\n                  },\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 3\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            },\n            {\n              \"ty\": \"tm\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Filter - Trim\",\n              \"nm\": \"Trim Paths 1\",\n              \"ix\": 2,\n              \"e\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 10\n                  },\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.667,\n                      \"y\": 1\n                    },\n                    \"s\": [\n                      35\n                    ],\n                    \"t\": 15\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 53\n                  }\n                ],\n                \"ix\": 2\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 3\n              },\n              \"s\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.667,\n                      \"y\": 1\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 15\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 53\n                  }\n                ],\n                \"ix\": 1\n              },\n              \"m\": 1\n            }\n          ],\n          \"ind\": 12\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"circle a 2\",\n          \"sr\": 1,\n          \"st\": 1,\n          \"op\": 192,\n          \"ip\": 1,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 1\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 29\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 161\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 1,\n                  \"ti\": [\n                    56.667,\n                    -3.333,\n                    0\n                  ],\n                  \"to\": [\n                    -53.333,\n                    -113.333,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    279.5,\n                    158,\n                    0\n                  ],\n                  \"t\": 29,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -56.667,\n                    3.333,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    259.5,\n                    858,\n                    0\n                  ],\n                  \"t\": 191\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 1\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    -371.368\n                  ],\n                  \"t\": 29\n                },\n                {\n                  \"s\": [\n                    -2520\n                  ],\n                  \"t\": 191\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Ellipse 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"el\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Ellipse\",\n                  \"nm\": \"Ellipse Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      1,\n                      0.698,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 13\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"circle b 2\",\n          \"sr\": 1,\n          \"st\": 3,\n          \"op\": 159,\n          \"ip\": 3,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 3\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 21\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 3,\n                  \"ti\": [\n                    63,\n                    -7,\n                    0\n                  ],\n                  \"to\": [\n                    -53.333,\n                    -100,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    279.5,\n                    238,\n                    0\n                  ],\n                  \"t\": 21,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -63,\n                    7,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    221.5,\n                    880,\n                    0\n                  ],\n                  \"t\": 158\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 3\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    -250.839\n                  ],\n                  \"t\": 21\n                },\n                {\n                  \"s\": [\n                    -2160\n                  ],\n                  \"t\": 158\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Ellipse 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"el\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Ellipse\",\n                  \"nm\": \"Ellipse Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0.9137,\n                      0.9882\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 14\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"star a 2\",\n          \"sr\": 1,\n          \"st\": 1,\n          \"op\": 192,\n          \"ip\": 1,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 1\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 31\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 161\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    596.087,\n                    836.292,\n                    0\n                  ],\n                  \"t\": 1,\n                  \"ti\": [\n                    42.765,\n                    -3.333,\n                    0\n                  ],\n                  \"to\": [\n                    -9.431,\n                    -113.333,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    539.5,\n                    156.292,\n                    0\n                  ],\n                  \"t\": 31,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -42.765,\n                    3.333,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    339.5,\n                    856.292,\n                    0\n                  ],\n                  \"t\": 191\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 1\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    -397.895\n                  ],\n                  \"t\": 31\n                },\n                {\n                  \"s\": [\n                    -2520\n                  ],\n                  \"t\": 191\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Polystar 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sr\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Star\",\n                  \"nm\": \"Polystar Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ir\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 6\n                  },\n                  \"is\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 8\n                  },\n                  \"pt\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 3\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"or\": {\n                    \"a\": 0,\n                    \"k\": 12,\n                    \"ix\": 7\n                  },\n                  \"os\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 9\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"sy\": 1\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 15\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"star b 2\",\n          \"sr\": 1,\n          \"st\": 3,\n          \"op\": 159,\n          \"ip\": 3,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 3\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 23\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    596.087,\n                    836.292,\n                    0\n                  ],\n                  \"t\": 3,\n                  \"ti\": [\n                    52.765,\n                    -3.333,\n                    0\n                  ],\n                  \"to\": [\n                    -12.765,\n                    -96.667,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    519.5,\n                    256.292,\n                    0\n                  ],\n                  \"t\": 23,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -52.765,\n                    3.333,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    279.5,\n                    856.292,\n                    0\n                  ],\n                  \"t\": 158\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 3\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    -278.71\n                  ],\n                  \"t\": 23\n                },\n                {\n                  \"s\": [\n                    -2160\n                  ],\n                  \"t\": 158\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Polystar 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sr\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Star\",\n                  \"nm\": \"Polystar Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ir\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 6\n                  },\n                  \"is\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 8\n                  },\n                  \"pt\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 3\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"or\": {\n                    \"a\": 0,\n                    \"k\": 12,\n                    \"ix\": 7\n                  },\n                  \"os\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 9\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"sy\": 1\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 16\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"rec a 2\",\n          \"sr\": 1,\n          \"st\": 0,\n          \"op\": 129,\n          \"ip\": 0,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 0\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 33\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 98\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    842,\n                    0\n                  ],\n                  \"t\": 0,\n                  \"ti\": [\n                    66.667,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -16.667,\n                    -120,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    499.5,\n                    122,\n                    0\n                  ],\n                  \"t\": 33,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -66.667,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    199.5,\n                    842,\n                    0\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 0\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    -556.875\n                  ],\n                  \"t\": 33\n                },\n                {\n                  \"s\": [\n                    -2160\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      8\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0.9137,\n                      0.9882\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 17\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"rec b 2\",\n          \"sr\": 1,\n          \"st\": 2,\n          \"op\": 219,\n          \"ip\": 2,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 25\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 188\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    842,\n                    0\n                  ],\n                  \"t\": 2,\n                  \"ti\": [\n                    2.877,\n                    -2.055,\n                    0\n                  ],\n                  \"to\": [\n                    -22.62,\n                    -109.87,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    339.5,\n                    262,\n                    0\n                  ],\n                  \"t\": 25,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -51.333,\n                    36.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    219.5,\n                    862,\n                    0\n                  ],\n                  \"t\": 218\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    -306.667\n                  ],\n                  \"t\": 25\n                },\n                {\n                  \"s\": [\n                    -2880\n                  ],\n                  \"t\": 218\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      8\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      1,\n                      0.3608,\n                      0.7216\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 18\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"square a 2\",\n          \"sr\": 1,\n          \"st\": 0,\n          \"op\": 129,\n          \"ip\": 0,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 0\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 35\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 98\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 0,\n                  \"ti\": [\n                    36.667,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -20,\n                    -90,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    479.5,\n                    298,\n                    0\n                  ],\n                  \"t\": 35,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -36.667,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    379.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 0\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    -590.625\n                  ],\n                  \"t\": 35\n                },\n                {\n                  \"s\": [\n                    -2160\n                  ],\n                  \"t\": 128\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 19\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"square b 2\",\n          \"sr\": 1,\n          \"st\": 2,\n          \"op\": 219,\n          \"ip\": 2,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    100,\n                    100\n                  ],\n                  \"t\": 27\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 188\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    599.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 2,\n                  \"ti\": [\n                    50,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -10,\n                    -103.333,\n                    0\n                  ]\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    539.5,\n                    218,\n                    0\n                  ],\n                  \"t\": 27,\n                  \"ti\": [\n                    0,\n                    0,\n                    0\n                  ],\n                  \"to\": [\n                    -50,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    299.5,\n                    838,\n                    0\n                  ],\n                  \"t\": 218\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.667,\n                    \"y\": 1\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"o\": {\n                    \"x\": 0.333,\n                    \"y\": 0\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    -333.333\n                  ],\n                  \"t\": 27\n                },\n                {\n                  \"s\": [\n                    -2880\n                  ],\n                  \"t\": 218\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 20\n        }\n      ]\n    },\n    {\n      \"nm\": \"\",\n      \"id\": \"comp_2\",\n      \"layers\": [\n        {\n          \"ty\": 0,\n          \"nm\": \"_small-side\",\n          \"sr\": 1,\n          \"st\": 0,\n          \"op\": 219,\n          \"ip\": 0,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                400,\n                400,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 0,\n              \"k\": [\n                260,\n                320,\n                0\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 0,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"w\": 800,\n          \"h\": 800,\n          \"refId\": \"comp_1\",\n          \"ind\": 1\n        }\n      ]\n    },\n    {\n      \"nm\": \"\",\n      \"id\": \"comp_3\",\n      \"layers\": [\n        {\n          \"ty\": 0,\n          \"nm\": \"left\",\n          \"sr\": 1,\n          \"st\": 13,\n          \"op\": 313,\n          \"ip\": 13,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                400,\n                400,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 0,\n              \"k\": [\n                400,\n                400,\n                0\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 0,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"w\": 800,\n          \"h\": 800,\n          \"refId\": \"comp_4\",\n          \"ind\": 1\n        },\n        {\n          \"ty\": 0,\n          \"nm\": \"right\",\n          \"sr\": 1,\n          \"st\": 30,\n          \"op\": 330,\n          \"ip\": 30,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                400,\n                400,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                -100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 0,\n              \"k\": [\n                400,\n                400,\n                0\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 0,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"w\": 800,\n          \"h\": 800,\n          \"refId\": \"comp_4\",\n          \"ind\": 2\n        }\n      ]\n    },\n    {\n      \"nm\": \"\",\n      \"id\": \"comp_4\",\n      \"layers\": [\n        {\n          \"ty\": 4,\n          \"nm\": \"streamer a 4\",\n          \"sr\": 1,\n          \"st\": 13,\n          \"op\": 174,\n          \"ip\": 13,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -157,\n                -245,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                -100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    219.178,\n                    -190.096,\n                    0\n                  ],\n                  \"t\": 13,\n                  \"ti\": [\n                    167.333,\n                    -560.667,\n                    0\n                  ],\n                  \"to\": [\n                    -95.333,\n                    426.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    179.178,\n                    989.904,\n                    0\n                  ],\n                  \"t\": 173\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 14,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Shape 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sh\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"nm\": \"Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"c\": false,\n                      \"i\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.685,\n                          -13.314\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          1.754,\n                          -14.206\n                        ],\n                        [\n                          -3.934,\n                          -9.465\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          -3.895,\n                          8.562\n                        ],\n                        [\n                          1.872,\n                          14.789\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.314\n                        ],\n                        [\n                          -1.803,\n                          14.605\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -156.5,\n                          -406\n                        ],\n                        [\n                          -166.5,\n                          -367\n                        ],\n                        [\n                          -146.5,\n                          -327\n                        ],\n                        [\n                          -166.5,\n                          -286\n                        ],\n                        [\n                          -146.5,\n                          -246\n                        ],\n                        [\n                          -166.5,\n                          -206\n                        ],\n                        [\n                          -146.5,\n                          -165\n                        ],\n                        [\n                          -166.5,\n                          -127\n                        ],\n                        [\n                          -156.5,\n                          -84\n                        ]\n                      ]\n                    },\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"st\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"nm\": \"Stroke 1\",\n                  \"lc\": 1,\n                  \"lj\": 1,\n                  \"ml\": 4,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 1,\n                    \"k\": [\n                      {\n                        \"o\": {\n                          \"x\": 0.167,\n                          \"y\": 0.167\n                        },\n                        \"i\": {\n                          \"x\": 0.833,\n                          \"y\": 0.833\n                        },\n                        \"s\": [\n                          4\n                        ],\n                        \"t\": 13\n                      },\n                      {\n                        \"s\": [\n                          0.5\n                        ],\n                        \"t\": 176\n                      }\n                    ],\n                    \"ix\": 5\n                  },\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 3\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            },\n            {\n              \"ty\": \"tm\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Filter - Trim\",\n              \"nm\": \"Trim Paths 1\",\n              \"ix\": 2,\n              \"e\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 13\n                  },\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      40\n                    ],\n                    \"t\": 18\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 176\n                  }\n                ],\n                \"ix\": 2\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 3\n              },\n              \"s\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 18\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 176\n                  }\n                ],\n                \"ix\": 1\n              },\n              \"m\": 1\n            }\n          ],\n          \"ind\": 1\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"streamer b 4\",\n          \"sr\": 1,\n          \"st\": 5,\n          \"op\": 174,\n          \"ip\": 5,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -157,\n                -245,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    269.863,\n                    -175.455,\n                    0\n                  ],\n                  \"t\": 5,\n                  \"ti\": [\n                    216,\n                    -599.333,\n                    0\n                  ],\n                  \"to\": [\n                    -110,\n                    415.333,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    69.863,\n                    984.545,\n                    0\n                  ],\n                  \"t\": 173\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": -1.458,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Shape 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sh\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"nm\": \"Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"c\": false,\n                      \"i\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.685,\n                          -13.314\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          1.754,\n                          -14.206\n                        ],\n                        [\n                          -3.934,\n                          -9.465\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          -3.895,\n                          8.562\n                        ],\n                        [\n                          1.872,\n                          14.789\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.314\n                        ],\n                        [\n                          -1.803,\n                          14.605\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -156.5,\n                          -406\n                        ],\n                        [\n                          -166.5,\n                          -367\n                        ],\n                        [\n                          -146.5,\n                          -327\n                        ],\n                        [\n                          -166.5,\n                          -286\n                        ],\n                        [\n                          -146.5,\n                          -246\n                        ],\n                        [\n                          -166.5,\n                          -206\n                        ],\n                        [\n                          -146.5,\n                          -165\n                        ],\n                        [\n                          -166.5,\n                          -127\n                        ],\n                        [\n                          -156.5,\n                          -84\n                        ]\n                      ]\n                    },\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"st\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"nm\": \"Stroke 1\",\n                  \"lc\": 1,\n                  \"lj\": 1,\n                  \"ml\": 4,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 1,\n                    \"k\": [\n                      {\n                        \"o\": {\n                          \"x\": 0.167,\n                          \"y\": 0.167\n                        },\n                        \"i\": {\n                          \"x\": 0.833,\n                          \"y\": 0.833\n                        },\n                        \"s\": [\n                          4\n                        ],\n                        \"t\": 5\n                      },\n                      {\n                        \"s\": [\n                          0.5\n                        ],\n                        \"t\": 173\n                      }\n                    ],\n                    \"ix\": 5\n                  },\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 3\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            },\n            {\n              \"ty\": \"tm\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Filter - Trim\",\n              \"nm\": \"Trim Paths 1\",\n              \"ix\": 2,\n              \"e\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 5\n                  },\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      40\n                    ],\n                    \"t\": 10\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 173\n                  }\n                ],\n                \"ix\": 2\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 3\n              },\n              \"s\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 10\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 173\n                  }\n                ],\n                \"ix\": 1\n              },\n              \"m\": 1\n            }\n          ],\n          \"ind\": 2\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"circle a 4\",\n          \"sr\": 1,\n          \"st\": -7,\n          \"op\": 156,\n          \"ip\": 8,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 8\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 155\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    325.643,\n                    -26.292,\n                    0\n                  ],\n                  \"t\": 8,\n                  \"ti\": [\n                    15.333,\n                    -507.667,\n                    0\n                  ],\n                  \"to\": [\n                    -101.333,\n                    75.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    125.643,\n                    835.708,\n                    0\n                  ],\n                  \"t\": 155\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 8\n                },\n                {\n                  \"s\": [\n                    1800\n                  ],\n                  \"t\": 155\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Ellipse 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"el\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Ellipse\",\n                  \"nm\": \"Ellipse Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 3\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"circle b 4\",\n          \"sr\": 1,\n          \"st\": -13,\n          \"op\": 216,\n          \"ip\": 2,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 215\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    619.5,\n                    -26.292,\n                    0\n                  ],\n                  \"t\": 2,\n                  \"ti\": [\n                    -2,\n                    -497.667,\n                    0\n                  ],\n                  \"to\": [\n                    -138,\n                    77.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    259.5,\n                    835.708,\n                    0\n                  ],\n                  \"t\": 215\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"s\": [\n                    2520\n                  ],\n                  \"t\": 215\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Ellipse 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"el\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Ellipse\",\n                  \"nm\": \"Ellipse Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 4\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"star a 4\",\n          \"sr\": 1,\n          \"st\": -9,\n          \"op\": 246,\n          \"ip\": 6,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 6\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    376.929,\n                    -28,\n                    0\n                  ],\n                  \"t\": 6,\n                  \"ti\": [\n                    173.333,\n                    -127.667,\n                    0\n                  ],\n                  \"to\": [\n                    -213.333,\n                    157.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    116.929,\n                    834,\n                    0\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 6\n                },\n                {\n                  \"s\": [\n                    2880\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Polystar 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sr\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Star\",\n                  \"nm\": \"Polystar Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ir\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 6\n                  },\n                  \"is\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 8\n                  },\n                  \"pt\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 3\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"or\": {\n                    \"a\": 0,\n                    \"k\": 12,\n                    \"ix\": 7\n                  },\n                  \"os\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 9\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"sy\": 1\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 5\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"star b 4\",\n          \"sr\": 1,\n          \"st\": -13,\n          \"op\": 126,\n          \"ip\": 2,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 125\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    171.786,\n                    -28,\n                    0\n                  ],\n                  \"t\": 2,\n                  \"ti\": [\n                    -161.333,\n                    -275.667,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    251.786,\n                    834,\n                    0\n                  ],\n                  \"t\": 125\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"s\": [\n                    1800\n                  ],\n                  \"t\": 125\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Polystar 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sr\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Star\",\n                  \"nm\": \"Polystar Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ir\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 6\n                  },\n                  \"is\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 8\n                  },\n                  \"pt\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 3\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"or\": {\n                    \"a\": 0,\n                    \"k\": 12,\n                    \"ix\": 7\n                  },\n                  \"os\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 9\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"sy\": 1\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0.9137,\n                      0.9882\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 6\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"rec a 4\",\n          \"sr\": 1,\n          \"st\": -11,\n          \"op\": 186,\n          \"ip\": 4,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 4\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 185\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    428.214,\n                    -22.292,\n                    0\n                  ],\n                  \"t\": 4,\n                  \"ti\": [\n                    -130.667,\n                    -315.667,\n                    0\n                  ],\n                  \"to\": [\n                    -167.333,\n                    119.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    228.214,\n                    839.708,\n                    0\n                  ],\n                  \"t\": 185\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 4\n                },\n                {\n                  \"s\": [\n                    2520\n                  ],\n                  \"t\": 185\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      8\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      1,\n                      0.698,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 7\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"rec b 4\",\n          \"sr\": 1,\n          \"st\": -9,\n          \"op\": 246,\n          \"ip\": 6,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 6\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    223.071,\n                    -22.292,\n                    0\n                  ],\n                  \"t\": 6,\n                  \"ti\": [\n                    -92.571,\n                    -383.708,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    223.071,\n                    839.708,\n                    0\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 6\n                },\n                {\n                  \"s\": [\n                    2880\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      8\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 8\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"square a 4\",\n          \"sr\": 1,\n          \"st\": -11,\n          \"op\": 218,\n          \"ip\": 4,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 4\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 217\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    120.5,\n                    -26.292,\n                    0\n                  ],\n                  \"t\": 4,\n                  \"ti\": [\n                    52.221,\n                    -418.892,\n                    0\n                  ],\n                  \"to\": [\n                    13,\n                    430.305,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    198.5,\n                    833.708,\n                    0\n                  ],\n                  \"t\": 217\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 4\n                },\n                {\n                  \"s\": [\n                    2520\n                  ],\n                  \"t\": 217\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0.9137,\n                      0.9882\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 9\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"square b 4\",\n          \"sr\": 1,\n          \"st\": -7,\n          \"op\": 216,\n          \"ip\": 8,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 8\n                },\n                {\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 215\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    274.357,\n                    -26.292,\n                    0\n                  ],\n                  \"t\": 8,\n                  \"ti\": [\n                    22.667,\n                    -253.667,\n                    0\n                  ],\n                  \"to\": [\n                    157.333,\n                    415.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    114.357,\n                    835.708,\n                    0\n                  ],\n                  \"t\": 215\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 8\n                },\n                {\n                  \"s\": [\n                    2520\n                  ],\n                  \"t\": 215\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0.9137,\n                      0.9882\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 10\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"streamer a 3\",\n          \"sr\": 1,\n          \"st\": 0,\n          \"op\": 186,\n          \"ip\": 0,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -157,\n                -245,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                -100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    275.178,\n                    -173.096,\n                    0\n                  ],\n                  \"t\": 0,\n                  \"ti\": [\n                    177.333,\n                    -643.333,\n                    0\n                  ],\n                  \"to\": [\n                    -87.333,\n                    413.333,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    219.178,\n                    974.904,\n                    0\n                  ],\n                  \"t\": 185\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 3,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Shape 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sh\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"nm\": \"Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"c\": false,\n                      \"i\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.685,\n                          -13.314\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          1.754,\n                          -14.206\n                        ],\n                        [\n                          -3.934,\n                          -9.465\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          -3.895,\n                          8.562\n                        ],\n                        [\n                          1.872,\n                          14.789\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.314\n                        ],\n                        [\n                          -1.803,\n                          14.605\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -156.5,\n                          -406\n                        ],\n                        [\n                          -166.5,\n                          -367\n                        ],\n                        [\n                          -146.5,\n                          -327\n                        ],\n                        [\n                          -166.5,\n                          -286\n                        ],\n                        [\n                          -146.5,\n                          -246\n                        ],\n                        [\n                          -166.5,\n                          -206\n                        ],\n                        [\n                          -146.5,\n                          -165\n                        ],\n                        [\n                          -166.5,\n                          -127\n                        ],\n                        [\n                          -156.5,\n                          -84\n                        ]\n                      ]\n                    },\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"st\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"nm\": \"Stroke 1\",\n                  \"lc\": 2,\n                  \"lj\": 2,\n                  \"ml\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 1,\n                    \"k\": [\n                      {\n                        \"o\": {\n                          \"x\": 0.167,\n                          \"y\": 0.167\n                        },\n                        \"i\": {\n                          \"x\": 0.833,\n                          \"y\": 0.833\n                        },\n                        \"s\": [\n                          4\n                        ],\n                        \"t\": 0\n                      },\n                      {\n                        \"s\": [\n                          0.5\n                        ],\n                        \"t\": 177\n                      }\n                    ],\n                    \"ix\": 5\n                  },\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 3\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            },\n            {\n              \"ty\": \"tm\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Filter - Trim\",\n              \"nm\": \"Trim Paths 1\",\n              \"ix\": 2,\n              \"e\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 0\n                  },\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      40\n                    ],\n                    \"t\": 5\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 177\n                  }\n                ],\n                \"ix\": 2\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 3\n              },\n              \"s\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 5\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 177\n                  }\n                ],\n                \"ix\": 1\n              },\n              \"m\": 1\n            }\n          ],\n          \"ind\": 11\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"streamer b 3\",\n          \"sr\": 1,\n          \"st\": 11,\n          \"op\": 218,\n          \"ip\": 11,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                -157,\n                -245,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 0,\n              \"k\": [\n                100,\n                100,\n                100\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    199.863,\n                    74.545,\n                    0\n                  ],\n                  \"t\": 11,\n                  \"ti\": [\n                    179.333,\n                    -430.667,\n                    0\n                  ],\n                  \"to\": [\n                    -13.363,\n                    405.455,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    139.863,\n                    834.545,\n                    0\n                  ],\n                  \"t\": 217\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 0,\n              \"k\": 9,\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Shape 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sh\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Group\",\n                  \"nm\": \"Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ks\": {\n                    \"a\": 0,\n                    \"k\": {\n                      \"c\": false,\n                      \"i\": [\n                        [\n                          0,\n                          0\n                        ],\n                        [\n                          -1.685,\n                          -13.314\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -14.907\n                        ],\n                        [\n                          0,\n                          -15.206\n                        ],\n                        [\n                          1.754,\n                          -14.206\n                        ],\n                        [\n                          -3.934,\n                          -9.465\n                        ]\n                      ],\n                      \"o\": [\n                        [\n                          -3.895,\n                          8.562\n                        ],\n                        [\n                          1.872,\n                          14.789\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          14.907\n                        ],\n                        [\n                          0,\n                          15.206\n                        ],\n                        [\n                          0,\n                          14.314\n                        ],\n                        [\n                          -1.803,\n                          14.605\n                        ],\n                        [\n                          0,\n                          0\n                        ]\n                      ],\n                      \"v\": [\n                        [\n                          -156.5,\n                          -406\n                        ],\n                        [\n                          -166.5,\n                          -367\n                        ],\n                        [\n                          -146.5,\n                          -327\n                        ],\n                        [\n                          -166.5,\n                          -286\n                        ],\n                        [\n                          -146.5,\n                          -246\n                        ],\n                        [\n                          -166.5,\n                          -206\n                        ],\n                        [\n                          -146.5,\n                          -165\n                        ],\n                        [\n                          -166.5,\n                          -127\n                        ],\n                        [\n                          -156.5,\n                          -84\n                        ]\n                      ]\n                    },\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"st\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Stroke\",\n                  \"nm\": \"Stroke 1\",\n                  \"lc\": 2,\n                  \"lj\": 2,\n                  \"ml\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 4\n                  },\n                  \"w\": {\n                    \"a\": 1,\n                    \"k\": [\n                      {\n                        \"o\": {\n                          \"x\": 0.167,\n                          \"y\": 0.167\n                        },\n                        \"i\": {\n                          \"x\": 0.833,\n                          \"y\": 0.833\n                        },\n                        \"s\": [\n                          4\n                        ],\n                        \"t\": 11\n                      },\n                      {\n                        \"s\": [\n                          0.5\n                        ],\n                        \"t\": 199\n                      }\n                    ],\n                    \"ix\": 5\n                  },\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      1,\n                      0.3608,\n                      0.7216\n                    ],\n                    \"ix\": 3\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            },\n            {\n              \"ty\": \"tm\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Filter - Trim\",\n              \"nm\": \"Trim Paths 1\",\n              \"ix\": 2,\n              \"e\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 11\n                  },\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      40\n                    ],\n                    \"t\": 16\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 199\n                  }\n                ],\n                \"ix\": 2\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 3\n              },\n              \"s\": {\n                \"a\": 1,\n                \"k\": [\n                  {\n                    \"o\": {\n                      \"x\": 0.167,\n                      \"y\": 0.167\n                    },\n                    \"i\": {\n                      \"x\": 0.833,\n                      \"y\": 0.833\n                    },\n                    \"s\": [\n                      0\n                    ],\n                    \"t\": 16\n                  },\n                  {\n                    \"s\": [\n                      100\n                    ],\n                    \"t\": 199\n                  }\n                ],\n                \"ix\": 1\n              },\n              \"m\": 1\n            }\n          ],\n          \"ind\": 12\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"circle a 3\",\n          \"sr\": 1,\n          \"st\": -13,\n          \"op\": 126,\n          \"ip\": 2,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 125\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    365.643,\n                    -26.292,\n                    0\n                  ],\n                  \"t\": 2,\n                  \"ti\": [\n                    15.333,\n                    -507.667,\n                    0\n                  ],\n                  \"to\": [\n                    -101.333,\n                    75.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    165.643,\n                    835.708,\n                    0\n                  ],\n                  \"t\": 125\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"s\": [\n                    -1800\n                  ],\n                  \"t\": 125\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Ellipse 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"el\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Ellipse\",\n                  \"nm\": \"Ellipse Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      1,\n                      0.698,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 13\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"circle b 3\",\n          \"sr\": 1,\n          \"st\": -7,\n          \"op\": 246,\n          \"ip\": 8,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 8\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    519.5,\n                    -26.292,\n                    0\n                  ],\n                  \"t\": 8,\n                  \"ti\": [\n                    -2,\n                    -497.667,\n                    0\n                  ],\n                  \"to\": [\n                    -138,\n                    77.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    159.5,\n                    835.708,\n                    0\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 8\n                },\n                {\n                  \"s\": [\n                    -2880\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Ellipse 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"el\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Ellipse\",\n                  \"nm\": \"Ellipse Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0.9137,\n                      0.9882\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 14\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"star a 3\",\n          \"sr\": 1,\n          \"st\": -9,\n          \"op\": 246,\n          \"ip\": 6,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 6\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    416.929,\n                    -28,\n                    0\n                  ],\n                  \"t\": 6,\n                  \"ti\": [\n                    173.333,\n                    -127.667,\n                    0\n                  ],\n                  \"to\": [\n                    -213.333,\n                    157.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    156.929,\n                    834,\n                    0\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 6\n                },\n                {\n                  \"s\": [\n                    -2880\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Polystar 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sr\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Star\",\n                  \"nm\": \"Polystar Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ir\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 6\n                  },\n                  \"is\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 8\n                  },\n                  \"pt\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 3\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"or\": {\n                    \"a\": 0,\n                    \"k\": 12,\n                    \"ix\": 7\n                  },\n                  \"os\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 9\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"sy\": 1\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 15\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"star b 3\",\n          \"sr\": 1,\n          \"st\": -7,\n          \"op\": 156,\n          \"ip\": 8,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 8\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 155\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    211.786,\n                    -28,\n                    0\n                  ],\n                  \"t\": 8,\n                  \"ti\": [\n                    -161.333,\n                    -275.667,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    0,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    291.786,\n                    834,\n                    0\n                  ],\n                  \"t\": 155\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 8\n                },\n                {\n                  \"s\": [\n                    -2160\n                  ],\n                  \"t\": 155\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Polystar 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"sr\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Star\",\n                  \"nm\": \"Polystar Path 1\",\n                  \"ix\": 1,\n                  \"d\": 1,\n                  \"ir\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 6\n                  },\n                  \"is\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 8\n                  },\n                  \"pt\": {\n                    \"a\": 0,\n                    \"k\": 5,\n                    \"ix\": 3\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 4\n                  },\n                  \"or\": {\n                    \"a\": 0,\n                    \"k\": 12,\n                    \"ix\": 7\n                  },\n                  \"os\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 9\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"sy\": 1\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 16\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"rec a 3\",\n          \"sr\": 1,\n          \"st\": -11,\n          \"op\": 186,\n          \"ip\": 4,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 4\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 185\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    468.214,\n                    -22.292,\n                    0\n                  ],\n                  \"t\": 4,\n                  \"ti\": [\n                    -130.667,\n                    -315.667,\n                    0\n                  ],\n                  \"to\": [\n                    -167.333,\n                    119.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    268.214,\n                    839.708,\n                    0\n                  ],\n                  \"t\": 185\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 4\n                },\n                {\n                  \"s\": [\n                    -2160\n                  ],\n                  \"t\": 185\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      8\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0.9137,\n                      0.9882\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 17\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"rec b 3\",\n          \"sr\": 1,\n          \"st\": -9,\n          \"op\": 246,\n          \"ip\": 6,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 6\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    263.071,\n                    -22.292,\n                    0\n                  ],\n                  \"t\": 6,\n                  \"ti\": [\n                    -114.571,\n                    -267.708,\n                    0\n                  ],\n                  \"to\": [\n                    0,\n                    143.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    263.071,\n                    839.708,\n                    0\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 6\n                },\n                {\n                  \"s\": [\n                    -2880\n                  ],\n                  \"t\": 245\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      8\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      1,\n                      0.3608,\n                      0.7216\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 18\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"square a 3\",\n          \"sr\": 1,\n          \"st\": -13,\n          \"op\": 218,\n          \"ip\": 2,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 217\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    160.5,\n                    -26.292,\n                    0\n                  ],\n                  \"t\": 2,\n                  \"ti\": [\n                    52.221,\n                    -418.892,\n                    0\n                  ],\n                  \"to\": [\n                    13,\n                    430.305,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    238.5,\n                    833.708,\n                    0\n                  ],\n                  \"t\": 217\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 2\n                },\n                {\n                  \"s\": [\n                    -2520\n                  ],\n                  \"t\": 217\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 100,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 19\n        },\n        {\n          \"ty\": 4,\n          \"nm\": \"square b 3\",\n          \"sr\": 1,\n          \"st\": -11,\n          \"op\": 186,\n          \"ip\": 4,\n          \"hd\": false,\n          \"ddd\": 0,\n          \"bm\": 0,\n          \"hasMask\": false,\n          \"ao\": 0,\n          \"ks\": {\n            \"a\": {\n              \"a\": 0,\n              \"k\": [\n                0,\n                0,\n                0\n              ],\n              \"ix\": 1\n            },\n            \"s\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    100,\n                    50,\n                    100\n                  ],\n                  \"t\": 4\n                },\n                {\n                  \"s\": [\n                    50,\n                    100,\n                    100\n                  ],\n                  \"t\": 185\n                }\n              ],\n              \"ix\": 6\n            },\n            \"sk\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"p\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    314.357,\n                    -26.292,\n                    0\n                  ],\n                  \"t\": 4,\n                  \"ti\": [\n                    22.667,\n                    -253.667,\n                    0\n                  ],\n                  \"to\": [\n                    157.333,\n                    415.667,\n                    0\n                  ]\n                },\n                {\n                  \"s\": [\n                    154.357,\n                    835.708,\n                    0\n                  ],\n                  \"t\": 185\n                }\n              ],\n              \"ix\": 2\n            },\n            \"r\": {\n              \"a\": 1,\n              \"k\": [\n                {\n                  \"o\": {\n                    \"x\": 0.167,\n                    \"y\": 0.167\n                  },\n                  \"i\": {\n                    \"x\": 0.833,\n                    \"y\": 0.833\n                  },\n                  \"s\": [\n                    0\n                  ],\n                  \"t\": 4\n                },\n                {\n                  \"s\": [\n                    -2160\n                  ],\n                  \"t\": 185\n                }\n              ],\n              \"ix\": 10\n            },\n            \"sa\": {\n              \"a\": 0,\n              \"k\": 0\n            },\n            \"o\": {\n              \"a\": 0,\n              \"k\": 50,\n              \"ix\": 11\n            }\n          },\n          \"ef\": [],\n          \"shapes\": [\n            {\n              \"ty\": \"gr\",\n              \"bm\": 0,\n              \"hd\": false,\n              \"mn\": \"ADBE Vector Group\",\n              \"nm\": \"Rectangle 1\",\n              \"ix\": 1,\n              \"cix\": 2,\n              \"np\": 2,\n              \"it\": [\n                {\n                  \"ty\": \"rc\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Shape - Rect\",\n                  \"nm\": \"Rectangle Path 1\",\n                  \"d\": 1,\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 3\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      16,\n                      16\n                    ],\n                    \"ix\": 2\n                  }\n                },\n                {\n                  \"ty\": \"fl\",\n                  \"bm\": 0,\n                  \"hd\": false,\n                  \"mn\": \"ADBE Vector Graphic - Fill\",\n                  \"nm\": \"Fill 1\",\n                  \"c\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0.3961,\n                      0.2902,\n                      0.9255\n                    ],\n                    \"ix\": 4\n                  },\n                  \"r\": 1,\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 5\n                  }\n                },\n                {\n                  \"ty\": \"tr\",\n                  \"a\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 1\n                  },\n                  \"s\": {\n                    \"a\": 0,\n                    \"k\": [\n                      100,\n                      100\n                    ],\n                    \"ix\": 3\n                  },\n                  \"sk\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 4\n                  },\n                  \"p\": {\n                    \"a\": 0,\n                    \"k\": [\n                      0,\n                      0\n                    ],\n                    \"ix\": 2\n                  },\n                  \"r\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 6\n                  },\n                  \"sa\": {\n                    \"a\": 0,\n                    \"k\": 0,\n                    \"ix\": 5\n                  },\n                  \"o\": {\n                    \"a\": 0,\n                    \"k\": 100,\n                    \"ix\": 7\n                  }\n                }\n              ]\n            }\n          ],\n          \"ind\": 20\n        }\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "apps/builder/src/components/Guide/index.tsx",
    "content": "import { Global } from \"@emotion/react\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { FC, RefObject, useEffect, useRef, useState } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { useSelector } from \"react-redux\"\nimport { GuideDraggablePopover } from \"@/components/Guide/GuideDraggablePopover\"\nimport { GuidePoint } from \"@/components/Guide/GuidePoint\"\nimport { GuideSuccess } from \"@/components/Guide/GuideSuccess\"\nimport { WidgetStepMask } from \"@/components/Guide/WidgetStepMask\"\nimport {\n  actionShiftStyle,\n  applyGuideStyle,\n  shiftStyle,\n} from \"@/components/Guide/style\"\nimport { GUIDE_STEP } from \"@/config/guide/config\"\nimport { getCurrentStep } from \"@/redux/guide/guideSelector\"\nimport GuideCreateApp from \"./GuideCreateApp\"\n\nexport interface GuideProps {\n  canvasRef: RefObject<HTMLDivElement>\n}\n\nexport const Guide: FC<GuideProps> = (props) => {\n  const { canvasRef } = props\n  const currentStep = useSelector(getCurrentStep)\n  const [firstStepElement, setFirstStepElement] = useState<Element | null>()\n\n  const { selector } = GUIDE_STEP[currentStep]\n  const postgresqlQuery = document.querySelector(\".postgresql1-query\")\n  const currentElement = selector && document.querySelector(selector)\n\n  const timeout = useRef<number>()\n\n  useEffect(() => {\n    // get first step element\n    if (currentStep === 0 && selector) {\n      timeout.current = window.setTimeout(() => {\n        const element = document.querySelector(selector)\n        setFirstStepElement(element)\n      }, 10)\n    }\n    return () => {\n      window.clearTimeout(timeout.current)\n    }\n  }, [currentStep, selector])\n\n  return (\n    <>\n      <Global styles={applyGuideStyle(currentStep)} />\n      {canvasRef.current?.children?.[0] &&\n        createPortal(\n          <WidgetStepMask currentStep={currentStep} />,\n          canvasRef.current.children[0],\n        )}\n      {/* widget tip */}\n      {currentStep === 0 && firstStepElement && (\n        <>\n          {createPortal(<GuidePoint />, firstStepElement)}\n          <GuideDraggablePopover currentStep={0} position=\"bottom\" />\n        </>\n      )}\n      {/* action tip */}\n      {(currentStep === 3 || currentStep === 4) && postgresqlQuery && (\n        <GuideDraggablePopover currentStep={currentStep} position=\"top\" />\n      )}\n      {currentStep === 3 &&\n        postgresqlQuery &&\n        createPortal(<GuidePoint css={actionShiftStyle} />, postgresqlQuery)}\n      {currentStep === 11 && currentElement && (\n        <GuideDraggablePopover currentStep={currentStep} position=\"right\" />\n      )}\n      {(currentStep === 4 || currentStep === 5 || currentStep === 7) &&\n        currentElement &&\n        createPortal(<GuidePoint css={shiftStyle} />, currentElement)}\n      {/* success tip */}\n      {currentStep === 12 && <GuideSuccess />}\n      {currentStep === 12 && currentElement ? (\n        isCloudVersion ? (\n          <GuideCreateApp />\n        ) : (\n          <GuideDraggablePopover currentStep={currentStep} position=\"right\" />\n        )\n      ) : null}\n    </>\n  )\n}\n\nGuide.displayName = \"Guide\"\n"
  },
  {
    "path": "apps/builder/src/components/Guide/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { GUIDE_SELECT_WIDGET, SELECT_WIDGET_ITEM } from \"@/config/guide/config\"\n\nconst applyHighlightStyle = (currentStep: number) => css`\n  [data-onboarding-session=\"COMMON\"] {\n    ${GUIDE_SELECT_WIDGET.slice(currentStep).map((widget) => {\n      const { highlightIcon } = SELECT_WIDGET_ITEM[widget]\n      return css`\n        [data-onboarding-icon=${widget}] {\n          content: url(${highlightIcon});\n        }\n      `\n    })}\n  }\n`\n\nexport const applyGuideStyle = (currentStep: number) => {\n  switch (currentStep) {\n    case 0:\n    case 1:\n    case 2:\n      return applyHighlightStyle(currentStep)\n    default:\n      return css``\n  }\n}\n\nexport const shiftStyle = css`\n  top: -15px;\n`\n\nexport const actionShiftStyle = css`\n  left: 84px;\n`\n"
  },
  {
    "path": "apps/builder/src/components/ILLAMarkdown/index.tsx",
    "content": "import { FC } from \"react\"\nimport ReactMarkdown from \"react-markdown\"\nimport remarkGfm from \"remark-gfm\"\nimport { Link } from \"@illa-design/react\"\nimport { ILLAMarkdownProps } from \"@/components/ILLAMarkdown/interface\"\nimport { applyMarkdownPStyle } from \"./style\"\n\nexport const ILLAMarkdown: FC<ILLAMarkdownProps> = (props) => {\n  const { textString, textColor = \"white\", urlColor = \"white\" } = props\n  return (\n    <ReactMarkdown\n      remarkPlugins={[remarkGfm]}\n      components={{\n        a: ({ ...aProps }) => (\n          <Link href={aProps.href} colorScheme={urlColor} target=\"_blank\">\n            {aProps.children}\n          </Link>\n        ),\n        p: ({ children }) => (\n          <span css={applyMarkdownPStyle(textColor)}>{children}</span>\n        ),\n      }}\n    >\n      {textString ?? \"\"}\n    </ReactMarkdown>\n  )\n}\n\nILLAMarkdown.displayName = \"ILLAMarkdown\"\n"
  },
  {
    "path": "apps/builder/src/components/ILLAMarkdown/interface.ts",
    "content": "export interface ILLAMarkdownProps {\n  textString?: string\n  textColor?: string\n  urlColor?: string\n}\n"
  },
  {
    "path": "apps/builder/src/components/ILLAMarkdown/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\n\nexport const applyMarkdownPStyle = (textColorScheme: string) => css`\n  color: ${getSpecialThemeColor(textColorScheme)};\n  font-size: 14px;\n  white-space: break-spaces;\n  word-break: break-all;\n`\n"
  },
  {
    "path": "apps/builder/src/components/Iframe/index.tsx",
    "content": "import { FC, IframeHTMLAttributes, useState } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { loadingStyle } from \"./style\"\n\nexport const Iframe: FC<IframeHTMLAttributes<HTMLIFrameElement>> = (props) => {\n  const [isLoading, setIsLoading] = useState(true)\n\n  const onLoad = () => {\n    setIsLoading(false)\n  }\n\n  return (\n    <>\n      {isLoading && (\n        <div css={loadingStyle}>\n          <Loading colorScheme=\"techPurple\" />\n        </div>\n      )}\n      <iframe\n        onLoad={onLoad}\n        style={{ display: isLoading ? \"none\" : \"block\" }}\n        {...props}\n      />\n    </>\n  )\n}\n\nIframe.displayName = \"Iframe\"\n"
  },
  {
    "path": "apps/builder/src/components/Iframe/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const loadingStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/builder/src/components/LayoutAutoChange/index.tsx",
    "content": "import { FC, ReactNode, lazy } from \"react\"\nimport { useWindowSize } from \"react-use\"\nimport { lazyLoad } from \"@/router/utils/lazyLoad\"\nimport { isMobileByWindowSize } from \"@/utils/screen\"\n\ninterface LayoutAutoChangeProps {\n  desktopPage: ReactNode\n}\n\nexport const LayoutAutoChange: FC<LayoutAutoChangeProps> = (props) => {\n  const { desktopPage } = props\n  const { width } = useWindowSize()\n  const isMobile = isMobileByWindowSize(width)\n  return (\n    <>\n      {isMobile\n        ? lazyLoad(lazy(() => import(\"@/page/Status/MobileFobidden\")))\n        : desktopPage}\n    </>\n  )\n}\n\nexport default LayoutAutoChange\n"
  },
  {
    "path": "apps/builder/src/components/Modal/Body/index.tsx",
    "content": "import { FC } from \"react\"\nimport { ModalBodyProps } from \"@/components/Modal/Body/interface\"\nimport { applyModalBodyWrapperStyle } from \"@/components/Modal/Body/style\"\nimport { stopDragAndDrop } from \"@/components/Modal/utils/stopDragAndDrop\"\n\nexport const ModalBody: FC<ModalBodyProps> = (props) => {\n  const { children, footerHeight } = props\n  return (\n    <div\n      css={applyModalBodyWrapperStyle(footerHeight)}\n      onMouseDown={stopDragAndDrop}\n    >\n      {children}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/Modal/Body/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface ModalBodyProps {\n  children: ReactNode\n  footerHeight: number\n}\n"
  },
  {
    "path": "apps/builder/src/components/Modal/Body/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const applyModalBodyWrapperStyle = (footerHeight: number) => css`\n  width: 100%;\n  height: calc(100% - 48px - ${`${footerHeight}px`});\n  cursor: auto;\n  padding: 0 16px;\n  overflow-y: auto;\n`\n"
  },
  {
    "path": "apps/builder/src/components/Modal/Footer/index.tsx",
    "content": "import { ForwardedRef, forwardRef } from \"react\"\nimport ResizeBarIcon from \"@/assets/public/resize-bar-icon.svg?react\"\nimport { ModalFooterProps } from \"@/components/Modal/Footer/interface\"\nimport {\n  applyModalFooterWrapperStyle,\n  resizeBarIconStyle,\n} from \"@/components/Modal/Footer/style\"\nimport { stopDragAndDrop } from \"@/components/Modal/utils/stopDragAndDrop\"\n\nconst ModalFooter = (\n  props: ModalFooterProps,\n  ref: ForwardedRef<HTMLDivElement>,\n) => {\n  const { children, hasFooterChildren, canMove } = props\n\n  return (\n    <div\n      css={applyModalFooterWrapperStyle(hasFooterChildren)}\n      onMouseDown={stopDragAndDrop}\n      ref={ref}\n    >\n      {children}\n      {canMove && <ResizeBarIcon css={resizeBarIconStyle} />}\n    </div>\n  )\n}\n\nexport default forwardRef<HTMLDivElement, ModalFooterProps>(ModalFooter)\n"
  },
  {
    "path": "apps/builder/src/components/Modal/Footer/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface ModalFooterProps {\n  children?: ReactNode\n  hasFooterChildren: boolean\n  canMove?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/components/Modal/Footer/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const applyModalFooterWrapperStyle = (hasChildren: boolean) => css`\n  width: 100%;\n  display: flex;\n  align-items: center;\n  position: relative;\n  cursor: auto;\n  padding: 0 16px;\n  height: ${hasChildren ? \"auto\" : \"16px\"};\n  flex: none;\n`\n\nexport const resizeBarIconStyle = css`\n  position: absolute;\n  bottom: 0;\n  right: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/components/Modal/Header/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC } from \"react\"\nimport { Link } from \"react-router-dom\"\nimport {\n  CloseIcon,\n  DocsIcon,\n  DragPointIcon,\n  getColor,\n} from \"@illa-design/react\"\nimport { HeaderProps } from \"@/components/Modal/Header/interface\"\nimport {\n  dragIconStyle,\n  headerContainerStyle,\n  headerWrapperStyle,\n  titleStyle,\n} from \"@/components/Modal/Header/style\"\n\nexport const ModalHeader: FC<HeaderProps> = (props) => {\n  const { title, canMove, docLink, onClose } = props\n  return (\n    <div css={headerWrapperStyle}>\n      <div css={headerContainerStyle}>\n        {canMove && <DragPointIcon css={dragIconStyle} />}\n        <span css={titleStyle}>{title}</span>\n        {docLink && (\n          <Link to={docLink} target=\"_blank\">\n            <IconHotSpot>\n              <DocsIcon />\n            </IconHotSpot>\n          </Link>\n        )}\n      </div>\n      <IconHotSpot onClick={onClose} inactiveColor={getColor(\"grayBlue\", \"02\")}>\n        <CloseIcon />\n      </IconHotSpot>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/Modal/Header/interface.ts",
    "content": "export interface HeaderProps {\n  title: string\n  docLink?: string\n  canMove?: boolean\n  onClose: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/components/Modal/Header/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const headerWrapperStyle = css`\n  width: 100%;\n  height: 48px;\n  display: flex;\n  align-items: center;\n  justify-content: space-around;\n  flex: none;\n  padding: 16px;\n  padding-left: 4px;\n  padding-bottom: 8px;\n  position: relative;\n`\n\nexport const titleStyle = css`\n  font-size: 16px;\n  font-weight: 600;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  display: inline-block;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  max-width: calc(100% - 64px);\n  flex: none;\n`\n\nexport const dragIconStyle = css`\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 16px;\n  flex: none;\n`\n\nexport const headerContainerStyle = css`\n  display: flex;\n  gap: 4px;\n  align-items: center;\n  width: calc(100% - 32px);\n`\n"
  },
  {
    "path": "apps/builder/src/components/Modal/index.tsx",
    "content": "import { FC } from \"react\"\nimport useMeasure from \"react-use-measure\"\nimport { ModalBody } from \"@/components/Modal/Body\"\nimport ModalFooter from \"@/components/Modal/Footer\"\nimport { ModalHeader } from \"@/components/Modal/Header\"\nimport { ModalProps } from \"@/components/Modal/interface\"\nimport { applyModalWrapperStyle } from \"@/components/Modal/style\"\n\nexport const BuilderModal: FC<ModalProps> = (props) => {\n  const { bodyContent, title, footerContent, canMove, w, h, onClose, docLink } =\n    props\n\n  const hasFooterChildren =\n    (Array.isArray(footerContent) && footerContent.length > 0) ||\n    footerContent != null\n\n  const [ref, rect] = useMeasure()\n\n  return (\n    <div css={applyModalWrapperStyle(w, h)}>\n      <ModalHeader\n        title={title}\n        onClose={onClose}\n        canMove={canMove}\n        docLink={docLink}\n      />\n      <ModalBody footerHeight={rect.height}>{bodyContent}</ModalBody>\n      <ModalFooter\n        hasFooterChildren={hasFooterChildren}\n        canMove={canMove}\n        ref={ref}\n      >\n        {footerContent}\n      </ModalFooter>\n    </div>\n  )\n}\n\nBuilderModal.displayName = \"Modal\"\n"
  },
  {
    "path": "apps/builder/src/components/Modal/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface BaseModalProps {\n  title: string\n  bodyContent: ReactNode\n  footerContent?: ReactNode\n  docLink?: string\n  onClose: () => void\n}\n\nexport interface ModalProps extends BaseModalProps {\n  docLink?: string\n  canMove?: boolean\n  w?: number\n  h?: number\n}\n\nexport interface MovableModalProps extends BaseModalProps {\n  defaultPosition?: {\n    x: number\n    y: number\n    width: number\n    height: number\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/components/Modal/movableModal.tsx",
    "content": "import { FC } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { useSelector } from \"react-redux\"\nimport { Rnd } from \"react-rnd\"\nimport { useWindowSize } from \"react-use\"\nimport { BuilderModal } from \"@/components/Modal\"\nimport { MovableModalProps } from \"@/components/Modal/interface\"\nimport { getIsDragging } from \"@/redux/currentApp/executionTree/executionSelector\"\n\nexport const MovableModal: FC<MovableModalProps> = (props) => {\n  const {\n    bodyContent,\n    title,\n    footerContent,\n    onClose,\n    defaultPosition,\n    docLink,\n  } = props\n  const { width, height } = useWindowSize()\n  const isDraggingInGlobal = useSelector(getIsDragging)\n\n  return createPortal(\n    <Rnd\n      default={\n        defaultPosition ?? {\n          x: width / 2 - 200,\n          y: height - 300 - 263,\n          width: 400,\n          height: 263,\n        }\n      }\n      style={{\n        zIndex: 10,\n        pointerEvents: isDraggingInGlobal ? \"none\" : \"auto\",\n        opacity: isDraggingInGlobal ? 0.5 : 1,\n      }}\n      minWidth={400}\n      minHeight={263}\n      bounds=\"window\"\n    >\n      <BuilderModal\n        title={title}\n        bodyContent={bodyContent}\n        onClose={onClose}\n        footerContent={footerContent}\n        canMove\n        docLink={docLink}\n      />\n    </Rnd>,\n    document.body,\n  )\n}\n\nMovableModal.displayName = \"MovableModal\"\n"
  },
  {
    "path": "apps/builder/src/components/Modal/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const applyModalWrapperStyle = (w?: number, h?: number) => css`\n  width: ${w != undefined ? `${w}px` : \"100%\"};\n  height: ${w != undefined ? `${h}px` : \"100%\"};\n  background-color: ${getColor(\"white\", \"01\")};\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n  border-radius: 8px;\n  display: flex;\n  flex-direction: column;\n`\n"
  },
  {
    "path": "apps/builder/src/components/Modal/utils/stopDragAndDrop.ts",
    "content": "import { MouseEvent } from \"react\"\n\nexport const stopDragAndDrop = (e: MouseEvent<HTMLElement>) => {\n  e.stopPropagation()\n}\n"
  },
  {
    "path": "apps/builder/src/components/PanelBar/index.tsx",
    "content": "import { AnimatePresence, motion } from \"framer-motion\"\nimport { FC, MouseEvent, memo, useCallback, useRef, useState } from \"react\"\nimport { UpIcon } from \"@illa-design/react\"\nimport { PanelBarProps } from \"./interface\"\nimport {\n  applyPanelBarHeaderStyle,\n  applyPanelBarOpenedIconStyle,\n  applyPanelBarTitleStyle,\n  customIconHotpotStyle,\n  panelBarItemContainerAnimationVariants,\n  panelBarItemContentStyle,\n} from \"./style\"\n\nexport const PanelBar: FC<PanelBarProps> = memo((props: PanelBarProps) => {\n  const {\n    title,\n    size = \"default\",\n    children,\n    customIcon,\n    destroyChildrenWhenClose = false,\n    isOpened = true,\n    saveToggleState,\n    onIllaFocus,\n  } = props\n  const [isOpenedState, setIsOpenedState] = useState(isOpened)\n  const containerRef = useRef<HTMLDivElement>(null)\n\n  const handleToggle = useCallback(\n    (e: MouseEvent<HTMLDivElement>) => {\n      const target = e.target as HTMLElement\n      if (containerRef.current?.contains(target)) {\n        saveToggleState?.(!isOpenedState)\n        setIsOpenedState(!isOpenedState)\n      }\n    },\n    [isOpenedState, saveToggleState],\n  )\n\n  return (\n    <>\n      <div\n        css={applyPanelBarHeaderStyle(size)}\n        onClick={handleToggle}\n        ref={containerRef}\n      >\n        <span css={applyPanelBarTitleStyle(size)}>{title}</span>\n        {customIcon ? (\n          customIcon\n        ) : (\n          <div css={customIconHotpotStyle}>\n            <UpIcon css={applyPanelBarOpenedIconStyle(isOpenedState, size)} />\n          </div>\n        )}\n      </div>\n\n      {destroyChildrenWhenClose ? (\n        <AnimatePresence initial={false}>\n          {isOpenedState && (\n            <motion.div\n              css={panelBarItemContentStyle}\n              variants={panelBarItemContainerAnimationVariants}\n              animate={isOpenedState ? \"enter\" : \"exit\"}\n              transition={{ duration: 0.2 }}\n              initial=\"exit\"\n              exit=\"exit\"\n              onClick={onIllaFocus}\n            >\n              {children}\n            </motion.div>\n          )}\n        </AnimatePresence>\n      ) : (\n        <AnimatePresence>\n          <motion.div\n            css={panelBarItemContentStyle}\n            variants={panelBarItemContainerAnimationVariants}\n            animate={isOpenedState ? \"enter\" : \"exit\"}\n            transition={{ duration: 0.2 }}\n            exit=\"exit\"\n            onClick={onIllaFocus}\n          >\n            {children}\n          </motion.div>\n        </AnimatePresence>\n      )}\n    </>\n  )\n})\n\nPanelBar.displayName = \"PanelBar\"\n"
  },
  {
    "path": "apps/builder/src/components/PanelBar/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface PanelBarProps {\n  title: string\n  size?: \"default\" | \"small\"\n  children?: ReactNode\n  isOpened?: boolean\n  saveToggleState?: (value: boolean) => void\n  onIllaFocus?: () => void\n  destroyChildrenWhenClose?: boolean\n  customIcon?: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/components/PanelBar/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { Variants } from \"framer-motion\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nconst getPanelBarHeaderHeight = (size: \"default\" | \"small\") => {\n  switch (size) {\n    case \"small\": {\n      return css`\n        height: 32px;\n      `\n    }\n    default:\n    case \"default\": {\n      return css`\n        height: 48px;\n      `\n    }\n  }\n}\n\nconst getPanelBarHeaderBorder = (size: \"default\" | \"small\") => {\n  switch (size) {\n    case \"small\": {\n      return null\n    }\n    default:\n    case \"default\": {\n      return css`\n        &:not(:first-of-type) {\n          border-top: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n        }\n      `\n    }\n  }\n}\n\nexport const applyPanelBarHeaderStyle = (\n  size: \"default\" | \"small\",\n): SerializedStyles => {\n  const heightCss = getPanelBarHeaderHeight(size)\n  const borderCss = getPanelBarHeaderBorder(size)\n  return css`\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    cursor: pointer;\n    ${heightCss};\n    ${borderCss};\n    padding: 0 16px;\n    padding-right: 16px;\n  `\n}\n\nconst getPanelTitleFontStyle = (size: \"default\" | \"small\") => {\n  switch (size) {\n    case \"small\": {\n      return css`\n        color: ${getColor(\"grayBlue\", \"03\")};\n        font-size: 12px;\n        font-weight: 500;\n        font-family: \"Inter\", serif;\n      `\n    }\n    case \"default\":\n    default: {\n      return css`\n        color: ${getColor(\"grayBlue\", \"02\")};\n        font-weight: 500;\n        font-size: 14px;\n      `\n    }\n  }\n}\n\nexport const applyPanelBarTitleStyle = (\n  size: \"default\" | \"small\",\n): SerializedStyles => {\n  return css`\n    ${getPanelTitleFontStyle(size)};\n    overflow: hidden;\n    text-overflow: ellipsis;\n  `\n}\n\nconst getIconColorStyle = (size: \"default\" | \"small\") => {\n  switch (size) {\n    case \"small\": {\n      return css`\n        color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n      `\n    }\n    case \"default\":\n    default: {\n      return css`\n        color: ${globalColor(`--${illaPrefix}-grayBlue-05`)};\n      `\n    }\n  }\n}\n\nexport function applyPanelBarOpenedIconStyle(\n  isOpened: boolean,\n  size: \"default\" | \"small\",\n): SerializedStyles {\n  const fontColorStyle = getIconColorStyle(size)\n  const rotate = isOpened\n    ? \"\"\n    : css`\n        transform: rotate(180deg);\n      `\n  return css`\n    transition: transform 200ms;\n    transform-origin: center;\n    font-size: 16px;\n    ${fontColorStyle};\n    ${rotate}\n  `\n}\n\nexport const panelBarItemContentStyle = css`\n  font-size: 14px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  position: relative;\n  height: auto;\n  padding-bottom: 4px;\n`\n\nexport const panelBarItemContainerAnimationVariants: Variants = {\n  enter: {\n    height: \"auto\",\n    overflowY: \"hidden\",\n    transitionEnd: { overflowY: \"visible\" },\n  },\n  exit: {\n    height: 0,\n    overflowY: \"hidden\",\n    transitionEnd: { overflowY: \"hidden\" },\n  },\n}\n\nexport const customIconHotpotStyle = css`\n  font-size: 16px;\n  padding: 4px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  :hover {\n    color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  }\n  :active {\n    color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/components/RecordEditor/index.tsx",
    "content": "import { FC, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  AddIcon,\n  Button,\n  DeleteIcon,\n  Input,\n  globalColor,\n  illaPrefix,\n} from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { RecordEditorProps } from \"./interface\"\nimport {\n  applyRecordEditorContainerStyle,\n  applyRecordValueStyle,\n  recordEditorLabelStyle,\n  recordEditorStyle,\n  recordKeyStyle,\n  recordStyle,\n  subLabelStyle,\n} from \"./style\"\n\nexport const RecordEditor: FC<RecordEditorProps> = (props) => {\n  const {\n    fillOnly,\n    name,\n    records,\n    customRender,\n    label,\n    subLabel,\n    onSubLabelClick,\n    onDelete,\n    onAdd,\n    withoutCodeMirror,\n    onChangeKey,\n    onChangeValue,\n    valueInputType,\n  } = props\n\n  const { t } = useTranslation()\n\n  const valueExpectedType = useMemo(\n    () =>\n      valueInputType\n        ? valueInputType === VALIDATION_TYPES.ANY\n          ? undefined\n          : valueInputType\n        : VALIDATION_TYPES.STRING,\n    [valueInputType],\n  )\n\n  const recordList = useMemo(() => {\n    return (\n      <>\n        {records?.map((record, index) => {\n          if (customRender) {\n            return (\n              <div css={recordStyle} key={index}>\n                {customRender(record, index, fillOnly)}\n                <Button\n                  type=\"button\"\n                  ml=\"-1px\"\n                  minW=\"32px\"\n                  variant=\"outline\"\n                  bdRadius=\"0 8px 8px 0\"\n                  colorScheme=\"grayBlue\"\n                  onClick={() => {\n                    onDelete?.(index, record, name)\n                  }}\n                  leftIcon={<DeleteIcon />}\n                />\n              </div>\n            )\n          }\n          return (\n            <div css={recordStyle} key={index}>\n              {withoutCodeMirror ? (\n                <Input\n                  colorScheme={\"techPurple\"}\n                  height=\"32px\"\n                  value={record.key}\n                  readOnly={fillOnly}\n                  minW=\"160px\"\n                  width=\"0\"\n                  flexGrow=\"1\"\n                  bdRadius=\"8px 0 0 8px\"\n                  placeholder=\"key\"\n                  onChange={(value) => {\n                    onChangeKey?.(index, value.trim(), record.value, name)\n                  }}\n                />\n              ) : (\n                <CodeEditor\n                  wrapperCss={recordKeyStyle}\n                  height=\"32px\"\n                  editable={!fillOnly}\n                  value={record.key}\n                  lang={CODE_LANG.JAVASCRIPT}\n                  placeholder=\"key\"\n                  expectValueType={VALIDATION_TYPES.STRING}\n                  onChange={(value) => {\n                    onChangeKey?.(index, value.trim(), record.value, name)\n                  }}\n                  singleLine\n                />\n              )}\n              {withoutCodeMirror ? (\n                <Input\n                  colorScheme={\"techPurple\"}\n                  height=\"32px\"\n                  bdRadius={fillOnly ? \"0 8px 8px 0\" : \"0\"}\n                  ml=\"-1px\"\n                  placeholder=\"value\"\n                  minW=\"160px\"\n                  width=\"0\"\n                  flexGrow=\"1\"\n                  value={record.value}\n                  onChange={(value) => {\n                    onChangeValue?.(index, record.key, value.trim(), name)\n                  }}\n                />\n              ) : (\n                <CodeEditor\n                  height=\"32px\"\n                  wrapperCss={applyRecordValueStyle(fillOnly)}\n                  lang={CODE_LANG.JAVASCRIPT}\n                  placeholder=\"value\"\n                  value={record.value}\n                  expectValueType={valueExpectedType}\n                  singleLine\n                  onChange={(value) => {\n                    onChangeValue?.(index, record.key, value.trim(), name)\n                  }}\n                />\n              )}\n              {!fillOnly && (\n                <Button\n                  type=\"button\"\n                  ml=\"-1px\"\n                  minW=\"32px\"\n                  variant=\"outline\"\n                  bdRadius=\"0 8px 8px 0\"\n                  colorScheme=\"grayBlue\"\n                  onClick={() => {\n                    onDelete?.(index, record, name)\n                  }}\n                  leftIcon={<DeleteIcon />}\n                />\n              )}\n            </div>\n          )\n        })}\n      </>\n    )\n  }, [\n    customRender,\n    fillOnly,\n    name,\n    onChangeKey,\n    onChangeValue,\n    onDelete,\n    records,\n    valueExpectedType,\n    withoutCodeMirror,\n  ])\n\n  return (\n    <div css={applyRecordEditorContainerStyle(label)}>\n      {label != \"\" && (\n        <span css={recordEditorLabelStyle}>\n          <span>{label}</span>\n          {subLabel && (\n            <span css={subLabelStyle} onClick={onSubLabelClick}>\n              {subLabel}\n            </span>\n          )}\n        </span>\n      )}\n      <div css={recordEditorStyle}>\n        {recordList}\n        {!fillOnly && (\n          <span>\n            <Button\n              type=\"button\"\n              mb=\"8px\"\n              pd=\"1px 8px\"\n              colorScheme=\"techPurple\"\n              size=\"medium\"\n              variant=\"text\"\n              onClick={() => {\n                onAdd?.(name)\n              }}\n              leftIcon={\n                <AddIcon color={globalColor(`--${illaPrefix}-techPurple-03`)} />\n              }\n            >\n              {t(\"editor.action.panel.btn.new\")}\n            </Button>\n          </span>\n        )}\n      </div>\n    </div>\n  )\n}\n\nRecordEditor.displayName = \"RecordEditor\"\n"
  },
  {
    "path": "apps/builder/src/components/RecordEditor/interface.ts",
    "content": "import { Params } from \"@illa-public/public-types\"\nimport { ReactNode } from \"react\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface RecordEditorProps {\n  label: string\n  subLabel?: string\n  onSubLabelClick?: () => void\n  name?: string\n  fillOnly?: boolean\n  records: Params[] | null\n  onAdd?: (name?: string) => void\n  customRender?: (\n    record: Params,\n    index: number,\n    fillOnly?: boolean,\n  ) => ReactNode\n  withoutCodeMirror?: boolean\n  onDelete?: (index: number, record: Params, name?: string) => void\n  onChangeKey?: (\n    index: number,\n    key: string,\n    value: string,\n    name?: string,\n  ) => void\n  onChangeValue?: (\n    index: number,\n    key: string,\n    value: string,\n    name?: string,\n  ) => void\n  valueInputType?: VALIDATION_TYPES\n}\n"
  },
  {
    "path": "apps/builder/src/components/RecordEditor/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport function applyRecordEditorContainerStyle(label: string) {\n  return css`\n    display: flex;\n    padding-right: ${label !== \"\" ? \"16px\" : \"0\"};\n    flex-direction: row;\n  `\n}\n\nexport const recordEditorStyle = css`\n  display: flex;\n  flex-grow: 1;\n  flex-direction: column;\n`\n\nexport const recordStyle = css`\n  display: inline-flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 48px;\n\n  & > button {\n    color: ${globalColor(`--${illaPrefix}-grayBlue-05`)};\n\n    :hover {\n      color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n      transition: color 200ms ease-in-out;\n    }\n  }\n`\n\nexport const recordKeyStyle = css`\n  min-width: 160px;\n  flex-grow: 1;\n  width: 0;\n  height: auto;\n\n  .ͼ1.cm-editor {\n    border-radius: 8px 0 0 8px;\n  }\n`\n\nexport const recordValueStyle = css`\n  margin-left: -1px;\n  flex-grow: 1;\n  width: 0;\n  height: auto;\n\n  .ͼ1.cm-editor {\n    border-radius: 0;\n  }\n`\n\nexport function applyRecordValueStyle(fillOnly?: boolean): SerializedStyles {\n  const fillStyle = fillOnly\n    ? css`\n        .ͼ1.cm-editor {\n          border-radius: 0 8px 8px 0;\n        }\n      `\n    : css`\n        .ͼ1.cm-editor {\n          border-radius: 0;\n        }\n      `\n\n  return css`\n    margin-left: -1px;\n    flex-grow: 1;\n    width: 0;\n    height: auto;\n    ${fillStyle};\n  `\n}\n\nexport const recordEditorLabelStyle = css`\n  min-width: 160px;\n  margin-left: 16px;\n  margin-right: 16px;\n  height: 48px;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: end;\n  font-size: 14px;\n  font-weight: 500;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const subLabelStyle = css`\n  line-height: 20px;\n  color: ${getColor(\"techPurple\", \"03\")};\n  font-size: 12px;\n  cursor: pointer;\n`\n"
  },
  {
    "path": "apps/builder/src/components/Tabs/constant.tsx",
    "content": "import { lazy } from \"react\"\nimport i18n from \"@/i18n/config\"\nimport ComponentPanel from \"@/page/App/components/ComponentPanel\"\nimport { SimpleTabsItem } from \"./interface\"\n\nconst ConfigPanel = lazy(() => import(\"@/page/App/components/ConfigPanel\"))\nconst PagePanel = lazy(() => import(\"@/page/App/components/PagePanel\"))\n\nexport const ACTION_PANEL_TABS: SimpleTabsItem[] = [\n  {\n    key: \"general\",\n    title: i18n.t(\"editor.action.resource.db.title.general_option\"),\n  },\n  {\n    key: \"advanced\",\n    title: i18n.t(\"editor.action.panel.label.advanced.advanced\"),\n  },\n]\n\nexport const COMPONENT_MANAGER_TABS: SimpleTabsItem[] = [\n  {\n    key: \"Page\",\n    title: i18n.t(\"editor.page.tab_title\"),\n    element: <PagePanel />,\n  },\n  {\n    key: \"Inspect\",\n    title: i18n.t(\"editor.inspect.tab_title\"),\n    element: <ConfigPanel />,\n  },\n  {\n    key: \"Insert\",\n    title: i18n.t(\"editor.widget_picker.tab_title\"),\n    element: <ComponentPanel />,\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/components/Tabs/index.tsx",
    "content": "import { FC, useCallback, useEffect, useState } from \"react\"\nimport { SimpleTabsItem, SimpleTabsProps } from \"./interface\"\nimport { applyTabsHeaderItemStyle, tabsHeaderContainerStyle } from \"./style\"\n\nexport const getRenderBody = (activeKey: string, items: SimpleTabsItem[]) => {\n  const item = items.find((item) => item.key === activeKey)\n  if (item) {\n    return item.element\n  }\n  return null\n}\n\nexport const SimpleTabs: FC<SimpleTabsProps> = (props) => {\n  const { items, activeKey, containerStyle, handleClickChangeTab } = props\n  const [innerActiveKey, setInnerActiveKey] = useState(activeKey)\n  const handleChangeTab = useCallback(\n    (e: React.MouseEvent<HTMLDivElement>) => {\n      const target = e.target as HTMLSpanElement\n      const key = target.dataset.key\n      if (key) {\n        handleClickChangeTab(key)\n        setInnerActiveKey(key)\n      }\n    },\n    [handleClickChangeTab],\n  )\n\n  useEffect(() => {\n    if (activeKey !== innerActiveKey) {\n      setInnerActiveKey(activeKey)\n    }\n  }, [activeKey, innerActiveKey])\n  return (\n    <>\n      <div\n        css={[tabsHeaderContainerStyle, containerStyle]}\n        onClick={handleChangeTab}\n      >\n        {items.map((item) => (\n          <span\n            key={item.key}\n            css={applyTabsHeaderItemStyle(innerActiveKey === item.key)}\n            data-key={item.key}\n          >\n            {item.title}\n          </span>\n        ))}\n      </div>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/Tabs/interface.ts",
    "content": "import { SerializedStyles } from \"@emotion/react\"\nimport { ReactNode } from \"react\"\n\nexport interface SimpleTabsItem {\n  title: string\n  key: string\n  element?: ReactNode\n}\n\nexport interface SimpleTabsProps {\n  items: SimpleTabsItem[]\n  activeKey: string\n  handleClickChangeTab: (activeKey: string) => void\n  containerStyle?: SerializedStyles\n}\n"
  },
  {
    "path": "apps/builder/src/components/Tabs/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const tabsHeaderContainerStyle = css`\n  display: flex;\n  width: 100%;\n  padding: 12px 16px;\n  gap: 8px;\n`\n\nexport const applyTabsHeaderItemStyle = (isActive: boolean) => css`\n  padding: 1px 4px;\n  height: 24px;\n  line-height: 24px;\n  border-radius: 4px;\n  font-size: 14px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  font-weight: ${isActive ? 500 : 400};\n  color: ${isActive ? getColor(\"grayBlue\", \"02\") : getColor(\"grayBlue\", \"03\")};\n  :hover {\n    background-color: ${getColor(\"grayBlue\", \"09\")};\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/components/UpgradeTag/index.tsx",
    "content": "import { UpgradeIcon } from \"@illa-public/icon\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Tag } from \"@illa-design/react\"\nimport {\n  upgradeTagContainerStyle,\n  upgradeTagContentStyle,\n  upgradeTagIconStyle,\n} from \"./style\"\n\nexport const UpgradeTag: FC = () => {\n  const { t } = useTranslation()\n\n  return (\n    <Tag colorScheme=\"techPurple\" css={upgradeTagContainerStyle}>\n      <span css={upgradeTagContentStyle}>\n        <span css={upgradeTagIconStyle}>\n          <UpgradeIcon />\n        </span>\n        <span>{t(\"billing.homepage.upgrade\")}</span>\n      </span>\n    </Tag>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/components/UpgradeTag/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const upgradeTagContainerStyle = css`\n  padding: 1px 8px;\n  box-sizing: content-box;\n`\nexport const upgradeTagContentStyle = css`\n  display: inline-flex;\n  align-items: center;\n  gap: 4px;\n  text-align: right;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 22px;\n  text-transform: capitalize;\n`\n\nexport const upgradeTagIconStyle = css`\n  width: 12px;\n  height: 12px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/config/AppWithAgent/index.ts",
    "content": "import { ACTION_RUN_TIME, Agent } from \"@illa-public/public-types\"\nimport {\n  CONTAINER_TYPE,\n  ComponentTreeNode,\n  Params,\n} from \"@illa-public/public-types\"\nimport { AiAgentActionContent } from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { klona } from \"klona/json\"\nimport { searchDSLFromTree } from \"@/redux/currentApp/components/componentsSelector\"\nimport { TEST_ROOT_NODE } from \"./templateNode\"\n\nconst NODE_START_POSITION_Y = 26\nconst NODE_SPACE_STEP = 6\nconst SEND_CONTENT_LABEL = \"Send content\"\n\nconst buildVariableInput = (\n  variableKey: string,\n  index: number,\n): {\n  variableKey: string\n  inputNode: ComponentTreeNode\n} => {\n  const displayName = `input${index}`\n  return {\n    variableKey,\n    inputNode: {\n      w: 32,\n      h: 5,\n      minW: 1,\n      minH: 3,\n      x: 0,\n      y: NODE_START_POSITION_Y + index * NODE_SPACE_STEP,\n      z: 0,\n      showName: \"input\",\n      type: \"INPUT_WIDGET\",\n      displayName: `${displayName}`,\n      containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n      parentNode: \"canvas1\",\n      childrenNode: [],\n      props: {\n        value: \"\",\n        label: variableKey,\n        labelAlign: \"left\",\n        labelPosition: \"left\",\n        labelWidth: \"{{33}}\",\n        colorScheme: \"blue\",\n        hidden: false,\n        formDataKey: `{{${displayName}.displayName}}`,\n        placeholder: \"input sth\",\n        $dynamicAttrPaths: [\"labelWidth\", \"formDataKey\", \"showVisibleButton\"],\n        type: \"input\",\n        showVisibleButton: \"{{true}}\",\n      },\n      version: 0,\n    },\n  }\n}\n\nconst buildRunActionButton = (\n  beforeComponentNum: number,\n): ComponentTreeNode => {\n  return {\n    w: 32,\n    h: 6,\n    minW: 1,\n    minH: 3,\n    x: 0,\n    y: NODE_START_POSITION_Y + beforeComponentNum * NODE_SPACE_STEP,\n    z: 0,\n    showName: \"button\",\n    type: \"BUTTON_WIDGET\",\n    displayName: \"button1\",\n    containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n    parentNode: \"canvas1\",\n    childrenNode: [],\n    props: {\n      text: \"Generate\",\n      variant: \"fill\",\n      colorScheme: \"blue\",\n      hidden: false,\n      $dynamicAttrPaths: [\"loading\"],\n      events: [\n        {\n          actionType: \"datasource\",\n          id: \"events-a7afae35-b079-44fd-aa0a-4be7ffec1ee4\",\n          eventType: \"click\",\n          queryID: \"aiagent1\",\n        },\n      ],\n      loading: \"{{aiagent1.isRunning}}\",\n    },\n    version: 0,\n  }\n}\n\nconst buildResultContainer = (\n  beforeComponentNum: number,\n): ComponentTreeNode => {\n  return {\n    version: 0,\n    displayName: \"container2\",\n    parentNode: \"canvas1\",\n    showName: \"container\",\n    childrenNode: [\n      {\n        version: 0,\n        displayName: \"canvas4\",\n        parentNode: \"container2\",\n        showName: \"canvas\",\n        childrenNode: [\n          {\n            version: 0,\n            displayName: \"text1\",\n            parentNode: \"canvas4\",\n            showName: \"text\",\n            childrenNode: [],\n            type: \"TEXT_WIDGET\",\n            containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n            h: 159,\n            w: 32,\n            minH: 3,\n            minW: 1,\n            x: 0,\n            y: 6,\n            z: 0,\n            props: {\n              $dynamicAttrPaths: [\"value\"],\n              colorScheme: \"grayBlue\",\n              disableMarkdown: false,\n              dynamicHeight: \"auto\",\n              fs: \"14px\",\n              hidden: false,\n              horizontalAlign: \"start\",\n              resizeDirection: \"HORIZONTAL\",\n              value: \"{{aiagent1.data[0].content}}\",\n              verticalAlign: \"center\",\n            },\n          },\n          {\n            version: 0,\n            displayName: \"text4\",\n            parentNode: \"canvas4\",\n            showName: \"text\",\n            childrenNode: [],\n            type: \"TEXT_WIDGET\",\n            containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n            h: 4,\n            w: 29,\n            minH: 3,\n            minW: 1,\n            x: 0,\n            y: 0,\n            z: 0,\n            props: {\n              $dynamicAttrPaths: [],\n              colorScheme: \"grayBlue\",\n              disableMarkdown: false,\n              dynamicHeight: \"auto\",\n              fs: \"14px\",\n              hidden: false,\n              horizontalAlign: \"start\",\n              resizeDirection: \"HORIZONTAL\",\n              value: \"**Generated content**\",\n              verticalAlign: \"center\",\n            },\n          },\n          {\n            version: 0,\n            displayName: \"icon1\",\n            parentNode: \"canvas4\",\n            showName: \"icon\",\n            childrenNode: [],\n            type: \"ICON_WIDGET\",\n            containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n            h: 4,\n            w: 3,\n            minH: 3,\n            minW: 1,\n            x: 29,\n            y: 0,\n            z: 0,\n            props: {\n              $dynamicAttrPaths: [\"hidden\", \"events[0].copiedValue\"],\n              colorScheme: \"grayBlue\",\n              events: [\n                {\n                  actionType: \"copyToClipboard\",\n                  copiedValue: \"{{text1.value}}\",\n                  eventType: \"click\",\n                  id: \"events-ed68fd85-5321-4c1f-9610-be91d66a2bb2\",\n                },\n              ],\n              hidden: \"{{text1.value == undefined}}\",\n              hiddenDynamic: true,\n              iconName: \"TbCopy\",\n            },\n          },\n        ],\n        type: \"CANVAS\",\n        containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n        h: 0,\n        w: 0,\n        minH: 0,\n        minW: 1,\n        x: -1,\n        y: -1,\n        z: 0,\n        props: {},\n      },\n      {\n        version: 0,\n        displayName: \"canvas5\",\n        parentNode: \"container2\",\n        showName: \"canvas\",\n        childrenNode: [],\n        type: \"CANVAS\",\n        containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n        h: 0,\n        w: 0,\n        minH: 0,\n        minW: 1,\n        x: -1,\n        y: -1,\n        z: 0,\n        props: {},\n      },\n      {\n        version: 0,\n        displayName: \"canvas6\",\n        parentNode: \"container2\",\n        showName: \"canvas\",\n        childrenNode: [],\n        type: \"CANVAS\",\n        containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n        h: 0,\n        w: 0,\n        minH: 0,\n        minW: 1,\n        x: -1,\n        y: -1,\n        z: 0,\n        props: {},\n      },\n    ],\n    type: \"CONTAINER_WIDGET\",\n    containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n    h: 17,\n    w: 32,\n    minH: 3,\n    minW: 1,\n    x: 0,\n    y: NODE_START_POSITION_Y + beforeComponentNum * NODE_SPACE_STEP,\n    z: 0,\n    props: {\n      $dynamicAttrPaths: [],\n      backgroundColor: \"#f7f4f4ff\",\n      currentIndex: 0,\n      currentKey: \"View 1\",\n      dynamicHeight: \"auto\",\n      padding: {\n        mode: \"all\",\n        size: \"24\",\n      },\n      radius: \"4px\",\n      resizeDirection: \"HORIZONTAL\",\n      shadow: \"none\",\n      viewList: [\n        {\n          id: \"cbbe4404-18e0-428f-bc7d-1adaca2f3794\",\n          key: \"View 1\",\n          label: \"View 1\",\n        },\n        {\n          id: \"0769430a-44f3-45e8-97d8-17e51ae2534d\",\n          key: \"View 2\",\n          label: \"View 2\",\n        },\n        {\n          id: \"f81ebc97-ac04-4b6e-b192-e3998d9bc3c9\",\n          key: \"View 3\",\n          label: \"View 3\",\n        },\n      ],\n    },\n  }\n}\n\nexport const buildAppWithAgentSchema = (variableKeys: string[]) => {\n  const appInfo = klona(TEST_ROOT_NODE)\n  const containerNode = searchDSLFromTree(appInfo, \"canvas1\")!\n\n  const variableKeyInputs = variableKeys.map((variableKey, index) =>\n    buildVariableInput(variableKey, index),\n  )\n  const sendContentInput = buildVariableInput(\n    SEND_CONTENT_LABEL,\n    variableKeys.length,\n  )\n  const inputNodes = variableKeyInputs.map(({ inputNode }) => inputNode)\n  const runActionButton = buildRunActionButton(inputNodes.length + 1 + 1)\n  const resultNode = buildResultContainer(inputNodes.length + 1 + 1 + 1)\n  containerNode.childrenNode.push(\n    ...inputNodes,\n    sendContentInput.inputNode,\n    runActionButton,\n    resultNode,\n  )\n\n  const variableKeyMapInputNodeDisplayName: Record<string, string> = {}\n  ;[...variableKeyInputs, sendContentInput].forEach(\n    ({ inputNode, variableKey }) => {\n      variableKeyMapInputNodeDisplayName[variableKey] = inputNode.displayName\n    },\n  )\n\n  return {\n    appInfo,\n    variableKeyMapInputNodeDisplayName,\n  }\n}\n\nexport const buildActionInfo = (\n  agentInfo: Agent,\n  variableKeyMapInputNodeDisplayName: Record<string, string>,\n): Partial<ActionItem<AiAgentActionContent>> => {\n  const variables: Params[] = agentInfo.variables.map((variable) => ({\n    key: variable.key,\n    value: `{{${variableKeyMapInputNodeDisplayName[variable.key]}.value}}`,\n  }))\n  return {\n    actionType: \"aiagent\",\n    displayName: \"aiagent1\",\n    resourceID: agentInfo.aiAgentID,\n    content: {\n      agentType: agentInfo.agentType,\n      model: agentInfo.model,\n      variables: variables,\n      input: `{{${variableKeyMapInputNodeDisplayName[SEND_CONTENT_LABEL]}.value}}`,\n      modelConfig: {\n        stream: false,\n      },\n      virtualResource: agentInfo,\n    },\n    isVirtualResource: true,\n    transformer: {\n      rawData: \"\",\n      enable: false,\n    },\n    triggerMode: \"manually\",\n    config: {\n      public: false,\n      advancedConfig: {\n        runtime: ACTION_RUN_TIME.NONE,\n        pages: [],\n        delayWhenLoaded: \"\",\n        displayLoadingPage: false,\n        isPeriodically: false,\n        periodInterval: \"\",\n      },\n      icon: agentInfo.icon,\n    },\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/config/AppWithAgent/templateNode.ts",
    "content": "import { CONTAINER_TYPE, ComponentTreeNode } from \"@illa-public/public-types\"\n\nexport const TIP_NODES: ComponentTreeNode = {\n  version: 0,\n  displayName: \"container3\",\n  parentNode: \"bodySection1-bodySectionContainer1\",\n  showName: \"container\",\n  childrenNode: [\n    {\n      version: 0,\n      displayName: \"canvas7\",\n      parentNode: \"container3\",\n      showName: \"canvas\",\n      childrenNode: [\n        {\n          version: 0,\n          displayName: \"text2\",\n          parentNode: \"canvas7\",\n          showName: \"text\",\n          childrenNode: [],\n          type: \"TEXT_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 4,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 0,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            colorScheme: \"grayBlue\",\n            disableMarkdown: false,\n            dynamicHeight: \"auto\",\n            fs: \"14px\",\n            hidden: false,\n            horizontalAlign: \"start\",\n            resizeDirection: \"HORIZONTAL\",\n            value: \"# How to Build your AI tools\",\n            verticalAlign: \"center\",\n          },\n        },\n        {\n          version: 0,\n          displayName: \"divider1\",\n          parentNode: \"canvas7\",\n          showName: \"divider\",\n          childrenNode: [],\n          type: \"DIVIDER_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 5,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 12,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            colorScheme: \"grayBlue\",\n            fs: \"14px\",\n            hidden: false,\n          },\n        },\n        {\n          version: 0,\n          displayName: \"text5\",\n          parentNode: \"canvas7\",\n          showName: \"text\",\n          childrenNode: [],\n          type: \"TEXT_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 4,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 20,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            colorScheme: \"grayBlue\",\n            disableMarkdown: false,\n            dynamicHeight: \"auto\",\n            fs: \"14px\",\n            hidden: false,\n            horizontalAlign: \"start\",\n            resizeDirection: \"HORIZONTAL\",\n            value:\n              \"**🪵 Drag-and-drop components to building frontend interfaces**\",\n            verticalAlign: \"center\",\n          },\n        },\n        {\n          version: 0,\n          displayName: \"text7\",\n          parentNode: \"canvas7\",\n          showName: \"text\",\n          childrenNode: [],\n          type: \"TEXT_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 4,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 71,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            colorScheme: \"grayBlue\",\n            disableMarkdown: false,\n            dynamicHeight: \"auto\",\n            fs: \"14px\",\n            hidden: false,\n            horizontalAlign: \"start\",\n            resizeDirection: \"HORIZONTAL\",\n            value: \"**📃 Create actions with your data source or AI Agent**\",\n            verticalAlign: \"center\",\n          },\n        },\n        {\n          version: 0,\n          displayName: \"container5\",\n          parentNode: \"canvas7\",\n          showName: \"container\",\n          childrenNode: [\n            {\n              version: 0,\n              displayName: \"canvas13\",\n              parentNode: \"container5\",\n              showName: \"canvas\",\n              childrenNode: [\n                {\n                  version: 0,\n                  displayName: \"text8\",\n                  parentNode: \"canvas13\",\n                  showName: \"text\",\n                  childrenNode: [],\n                  type: \"TEXT_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 5,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 0,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    colorScheme: \"grayBlue\",\n                    disableMarkdown: false,\n                    dynamicHeight: \"auto\",\n                    fs: \"14px\",\n                    hidden: false,\n                    horizontalAlign: \"start\",\n                    resizeDirection: \"HORIZONTAL\",\n                    value:\n                      \"This step allows you to connect to your own data source, perform queries, and other operations. You can also integrate the AI Agent into your tool to make it smarter.\\n***We have automatically created an action with AI Agent. You can still add new ones by clicking `+ New`  at the bottom of the page.***\",\n                    verticalAlign: \"center\",\n                  },\n                },\n                {\n                  version: 0,\n                  displayName: \"image4\",\n                  parentNode: \"canvas13\",\n                  showName: \"image\",\n                  childrenNode: [],\n                  type: \"IMAGE_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 37,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 10,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    hidden: false,\n                    imageSrc:\n                      \"https://cloud-api.illacloud.com/drive/f/f554ff2c-f245-41b4-8ccc-f80da547d8ae\",\n                    imageSrcByURL:\n                      \"https://cloud-api.illacloud.com/drive/f/f554ff2c-f245-41b4-8ccc-f80da547d8ae\",\n                    objectFit: \"scale-down\",\n                    radius: \"0px\",\n                  },\n                },\n              ],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n            {\n              version: 0,\n              displayName: \"canvas14\",\n              parentNode: \"container5\",\n              showName: \"canvas\",\n              childrenNode: [],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n            {\n              version: 0,\n              displayName: \"canvas15\",\n              parentNode: \"container5\",\n              showName: \"canvas\",\n              childrenNode: [],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n          ],\n          type: \"CONTAINER_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 59,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 78,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            backgroundColor: \"#f3f3f3ff\",\n            currentIndex: 0,\n            currentKey: \"View 1\",\n            dynamicHeight: \"auto\",\n            padding: {\n              mode: \"all\",\n              size: \"24\",\n            },\n            radius: \"4px\",\n            resizeDirection: \"HORIZONTAL\",\n            shadow: \"none\",\n            viewList: [\n              {\n                id: \"1b063da1-bb04-4321-be13-ee13e2178141\",\n                key: \"View 1\",\n                label: \"View 1\",\n              },\n              {\n                id: \"0fea99bb-df46-45ef-aa46-c6b05c6ac074\",\n                key: \"View 2\",\n                label: \"View 2\",\n              },\n              {\n                id: \"10817fe8-3c53-4bbb-af8c-ab076d324c27\",\n                key: \"View 3\",\n                label: \"View 3\",\n              },\n            ],\n          },\n        },\n        {\n          version: 0,\n          displayName: \"text9\",\n          parentNode: \"canvas7\",\n          showName: \"text\",\n          childrenNode: [],\n          type: \"TEXT_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 4,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 140,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            colorScheme: \"grayBlue\",\n            disableMarkdown: false,\n            dynamicHeight: \"auto\",\n            fs: \"14px\",\n            hidden: false,\n            horizontalAlign: \"start\",\n            resizeDirection: \"HORIZONTAL\",\n            value: \"**🔗 Connect components and actions**\",\n            verticalAlign: \"center\",\n          },\n        },\n        {\n          version: 0,\n          displayName: \"container6\",\n          parentNode: \"canvas7\",\n          showName: \"container\",\n          childrenNode: [\n            {\n              version: 0,\n              displayName: \"canvas16\",\n              parentNode: \"container6\",\n              showName: \"canvas\",\n              childrenNode: [\n                {\n                  version: 0,\n                  displayName: \"text10\",\n                  parentNode: \"canvas16\",\n                  showName: \"text\",\n                  childrenNode: [],\n                  type: \"TEXT_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 12,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 3,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    borderWidth: \"14px\",\n                    colorScheme: \"grayBlue\",\n                    disableMarkdown: false,\n                    dynamicHeight: \"auto\",\n                    fs: \"14px\",\n                    hidden: false,\n                    horizontalAlign: \"start\",\n                    resizeDirection: \"HORIZONTAL\",\n                    value:\n                      \"Configure the inputs of Actions with the data of components. Click </> on the left panel to  check the data of any conmponents or data sources. For example, the data of input components is `displayName.value`. Please make sure to enclose the data with `{{`\",\n                    verticalAlign: \"center\",\n                  },\n                },\n                {\n                  version: 0,\n                  displayName: \"image5\",\n                  parentNode: \"canvas16\",\n                  showName: \"image\",\n                  childrenNode: [],\n                  type: \"IMAGE_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 45,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 15,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    hidden: false,\n                    imageSrc:\n                      \"https://cloud-api.illacloud.com/drive/f/cff4d7a0-b06b-4bb1-b375-d9e013c1b713\",\n                    imageSrcByURL:\n                      \"https://cloud-api.illacloud.com/drive/f/cff4d7a0-b06b-4bb1-b375-d9e013c1b713\",\n                    objectFit: \"scale-down\",\n                    radius: \"0px\",\n                  },\n                },\n                {\n                  version: 0,\n                  displayName: \"text17\",\n                  parentNode: \"canvas16\",\n                  showName: \"text\",\n                  childrenNode: [],\n                  type: \"TEXT_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 8,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 60,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    colorScheme: \"grayBlue\",\n                    disableMarkdown: false,\n                    dynamicHeight: \"auto\",\n                    fs: \"14px\",\n                    hidden: false,\n                    horizontalAlign: \"start\",\n                    resizeDirection: \"HORIZONTAL\",\n                    value:\n                      \"Display the result of the Actions on the components. The result of actions is usually in actionDisplayname.data. You can check it on left panel.\",\n                    verticalAlign: \"center\",\n                  },\n                },\n                {\n                  version: 0,\n                  displayName: \"text18\",\n                  parentNode: \"canvas16\",\n                  showName: \"text\",\n                  childrenNode: [],\n                  type: \"TEXT_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 6,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 68,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    colorScheme: \"grayBlue\",\n                    disableMarkdown: false,\n                    dynamicHeight: \"auto\",\n                    fs: \"14px\",\n                    hidden: false,\n                    horizontalAlign: \"start\",\n                    resizeDirection: \"HORIZONTAL\",\n                    value:\n                      \"Add event handler to the components to trigger the Action.\",\n                    verticalAlign: \"center\",\n                  },\n                },\n                {\n                  version: 0,\n                  displayName: \"container10\",\n                  parentNode: \"canvas16\",\n                  showName: \"container\",\n                  childrenNode: [\n                    {\n                      version: 0,\n                      displayName: \"canvas28\",\n                      parentNode: \"container10\",\n                      showName: \"canvas\",\n                      childrenNode: [\n                        {\n                          version: 0,\n                          displayName: \"text19\",\n                          parentNode: \"canvas28\",\n                          showName: \"text\",\n                          childrenNode: [],\n                          type: \"TEXT_WIDGET\",\n                          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                          h: 5,\n                          w: 32,\n                          minH: 3,\n                          minW: 1,\n                          x: 0,\n                          y: 0,\n                          z: 0,\n                          props: {\n                            $dynamicAttrPaths: [],\n                            colorScheme: \"grayBlue\",\n                            disableMarkdown: false,\n                            dynamicHeight: \"auto\",\n                            fs: \"14px\",\n                            hidden: false,\n                            horizontalAlign: \"start\",\n                            resizeDirection: \"HORIZONTAL\",\n                            value: \"📖 How to add event handler >\",\n                            verticalAlign: \"center\",\n                          },\n                        },\n                      ],\n                      type: \"CANVAS\",\n                      containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n                      h: 0,\n                      w: 0,\n                      minH: 0,\n                      minW: 1,\n                      x: -1,\n                      y: -1,\n                      z: 0,\n                      props: {},\n                    },\n                  ],\n                  type: \"CONTAINER_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 9,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 74,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    backgroundColor: \"white\",\n                    currentIndex: 0,\n                    currentKey: \"View 1\",\n                    dynamicHeight: \"auto\",\n                    events: [\n                      {\n                        actionType: \"openUrl\",\n                        eventType: \"click\",\n                        id: \"events-3ef1522f-8378-4037-9e5e-2daea9beafc7\",\n                        newTab: true,\n                        url: \"https://docs.illacloud.com/event-handler\",\n                      },\n                    ],\n                    padding: {\n                      mode: \"all\",\n                      size: \"10\",\n                    },\n                    radius: \"4px\",\n                    resizeDirection: \"HORIZONTAL\",\n                    shadow: \"small\",\n                    viewList: [\n                      {\n                        id: \"125370cb-9d3d-4c6e-848d-34bf952550fb\",\n                        key: \"View 1\",\n                        label: \"View 1\",\n                      },\n                    ],\n                  },\n                },\n              ],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n            {\n              version: 0,\n              displayName: \"canvas17\",\n              parentNode: \"container6\",\n              showName: \"canvas\",\n              childrenNode: [],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n            {\n              version: 0,\n              displayName: \"canvas18\",\n              parentNode: \"container6\",\n              showName: \"canvas\",\n              childrenNode: [],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n          ],\n          type: \"CONTAINER_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 92,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 147,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            backgroundColor: \"#f3f3f3ff\",\n            currentIndex: 0,\n            currentKey: \"View 1\",\n            dynamicHeight: \"auto\",\n            padding: {\n              mode: \"all\",\n              size: \"24\",\n            },\n            radius: \"4px\",\n            resizeDirection: \"HORIZONTAL\",\n            shadow: \"none\",\n            viewList: [\n              {\n                id: \"1b063da1-bb04-4321-be13-ee13e2178141\",\n                key: \"View 1\",\n                label: \"View 1\",\n              },\n              {\n                id: \"0fea99bb-df46-45ef-aa46-c6b05c6ac074\",\n                key: \"View 2\",\n                label: \"View 2\",\n              },\n              {\n                id: \"10817fe8-3c53-4bbb-af8c-ab076d324c27\",\n                key: \"View 3\",\n                label: \"View 3\",\n              },\n            ],\n          },\n        },\n        {\n          version: 0,\n          displayName: \"text11\",\n          parentNode: \"canvas7\",\n          showName: \"text\",\n          childrenNode: [],\n          type: \"TEXT_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 12,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 241,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            colorScheme: \"grayBlue\",\n            disableMarkdown: false,\n            dynamicHeight: \"auto\",\n            fs: \"14px\",\n            hidden: false,\n            horizontalAlign: \"start\",\n            resizeDirection: \"HORIZONTAL\",\n            value: \"# Use case\",\n            verticalAlign: \"center\",\n          },\n        },\n        {\n          version: 0,\n          displayName: \"divider2\",\n          parentNode: \"canvas7\",\n          showName: \"divider\",\n          childrenNode: [],\n          type: \"DIVIDER_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 5,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 253,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            colorScheme: \"grayBlue\",\n            fs: \"14px\",\n            hidden: false,\n          },\n        },\n        {\n          version: 0,\n          displayName: \"container9\",\n          parentNode: \"canvas7\",\n          showName: \"container\",\n          childrenNode: [\n            {\n              version: 0,\n              displayName: \"canvas25\",\n              parentNode: \"container9\",\n              showName: \"canvas\",\n              childrenNode: [\n                {\n                  version: 0,\n                  displayName: \"text15\",\n                  parentNode: \"canvas25\",\n                  showName: \"text\",\n                  childrenNode: [],\n                  type: \"TEXT_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 4,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 38,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    colorScheme: \"grayBlue\",\n                    disableMarkdown: false,\n                    dynamicHeight: \"auto\",\n                    fs: \"14px\",\n                    hidden: false,\n                    horizontalAlign: \"start\",\n                    resizeDirection: \"HORIZONTAL\",\n                    value: \"### Marketing content management\",\n                    verticalAlign: \"center\",\n                  },\n                },\n                {\n                  version: 0,\n                  displayName: \"image1\",\n                  parentNode: \"canvas25\",\n                  showName: \"image\",\n                  childrenNode: [],\n                  type: \"IMAGE_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 38,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 0,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    hidden: false,\n                    imageSrc:\n                      \"https://cloud-api.illacloud.com/drive/f/515407ea-3c57-4527-ab9f-9472d55984f0\",\n                    imageSrcByURL:\n                      \"https://cloud-api.illacloud.com/drive/f/515407ea-3c57-4527-ab9f-9472d55984f0\",\n                    objectFit: \"cover\",\n                    radius: \"0px\",\n                  },\n                },\n              ],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n          ],\n          type: \"CONTAINER_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 55,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 374,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            backgroundColor: \"#f6ecf6ff\",\n            currentIndex: 0,\n            currentKey: \"View 1\",\n            dynamicHeight: \"auto\",\n            events: [\n              {\n                actionType: \"openUrl\",\n                eventType: \"click\",\n                id: \"events-acb3455e-c33f-4aff-9b71-2d836c0d166c\",\n                newTab: true,\n                url: \"https://illa.ai/app/ILAcx4p1C7J0/detail\",\n              },\n            ],\n            padding: {\n              mode: \"all\",\n              size: \"24\",\n            },\n            radius: \"4px\",\n            resizeDirection: \"HORIZONTAL\",\n            shadow: \"none\",\n            viewList: [\n              {\n                id: \"1b063da1-bb04-4321-be13-ee13e2178141\",\n                key: \"View 1\",\n                label: \"View 1\",\n              },\n            ],\n          },\n        },\n        {\n          version: 0,\n          displayName: \"container8\",\n          parentNode: \"canvas7\",\n          showName: \"container\",\n          childrenNode: [\n            {\n              version: 0,\n              displayName: \"canvas22\",\n              parentNode: \"container8\",\n              showName: \"canvas\",\n              childrenNode: [\n                {\n                  version: 0,\n                  displayName: \"text14\",\n                  parentNode: \"canvas22\",\n                  showName: \"text\",\n                  childrenNode: [],\n                  type: \"TEXT_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 9,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 38,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    colorScheme: \"grayBlue\",\n                    disableMarkdown: false,\n                    dynamicHeight: \"auto\",\n                    fs: \"14px\",\n                    hidden: false,\n                    horizontalAlign: \"start\",\n                    resizeDirection: \"HORIZONTAL\",\n                    value: \"### CMS - Localization management\",\n                    verticalAlign: \"center\",\n                  },\n                },\n                {\n                  version: 0,\n                  displayName: \"image2\",\n                  parentNode: \"canvas22\",\n                  showName: \"image\",\n                  childrenNode: [],\n                  type: \"IMAGE_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 38,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 0,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    hidden: false,\n                    imageSrc:\n                      \"https://cloud-api.illacloud.com/drive/f/464795e9-5582-4799-aaea-b5ad98e86692\",\n                    imageSrcByURL:\n                      \"https://cloud-api.illacloud.com/drive/f/464795e9-5582-4799-aaea-b5ad98e86692\",\n                    objectFit: \"cover\",\n                    radius: \"0px\",\n                  },\n                },\n              ],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n          ],\n          type: \"CONTAINER_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 55,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 316,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            backgroundColor: \"#f6ecf6ff\",\n            currentIndex: 0,\n            currentKey: \"View 1\",\n            dynamicHeight: \"auto\",\n            events: [\n              {\n                actionType: \"openUrl\",\n                eventType: \"click\",\n                id: \"events-6a3ea8f4-8f3a-4129-9f75-b0a50ff4a59a\",\n                newTab: true,\n                url: \"https://illa.ai/app/ILAcx4p1C7JZ/detail\",\n              },\n            ],\n            padding: {\n              mode: \"all\",\n              size: \"24\",\n            },\n            radius: \"4px\",\n            resizeDirection: \"HORIZONTAL\",\n            shadow: \"none\",\n            viewList: [\n              {\n                id: \"1b063da1-bb04-4321-be13-ee13e2178141\",\n                key: \"View 1\",\n                label: \"View 1\",\n              },\n            ],\n          },\n        },\n        {\n          version: 0,\n          displayName: \"container7\",\n          parentNode: \"canvas7\",\n          showName: \"container\",\n          childrenNode: [\n            {\n              version: 0,\n              displayName: \"canvas19\",\n              parentNode: \"container7\",\n              showName: \"canvas\",\n              childrenNode: [\n                {\n                  version: 0,\n                  displayName: \"text13\",\n                  parentNode: \"canvas19\",\n                  showName: \"text\",\n                  childrenNode: [],\n                  type: \"TEXT_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 4,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 38,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    colorScheme: \"grayBlue\",\n                    disableMarkdown: false,\n                    dynamicHeight: \"auto\",\n                    fs: \"14px\",\n                    hidden: false,\n                    horizontalAlign: \"start\",\n                    resizeDirection: \"HORIZONTAL\",\n                    value: \"### CRM with Email generator\",\n                    verticalAlign: \"center\",\n                  },\n                },\n                {\n                  version: 0,\n                  displayName: \"image3\",\n                  parentNode: \"canvas19\",\n                  showName: \"image\",\n                  childrenNode: [],\n                  type: \"IMAGE_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 38,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 0,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    hidden: false,\n                    imageSrc:\n                      \"https://cloud-api.illacloud.com/drive/f/899c9b4c-516d-4f41-82a0-1821ceaa0120\",\n                    imageSrcByURL:\n                      \"https://cloud-api.illacloud.com/drive/f/899c9b4c-516d-4f41-82a0-1821ceaa0120\",\n                    objectFit: \"cover\",\n                    radius: \"0px\",\n                  },\n                },\n              ],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n          ],\n          type: \"CONTAINER_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 55,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 258,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            backgroundColor: \"#f6ecf6ff\",\n            currentIndex: 0,\n            currentKey: \"View 1\",\n            dynamicHeight: \"auto\",\n            events: [\n              {\n                actionType: \"openUrl\",\n                eventType: \"click\",\n                id: \"events-587f5d59-57b4-4890-a490-fb5466baf16c\",\n                newTab: true,\n                url: \"https://illa.ai/app/ILAfx4p1C7Xj/detail\",\n              },\n            ],\n            padding: {\n              mode: \"all\",\n              size: \"24\",\n            },\n            radius: \"4px\",\n            resizeDirection: \"HORIZONTAL\",\n            shadow: \"none\",\n            viewList: [\n              {\n                id: \"1b063da1-bb04-4321-be13-ee13e2178141\",\n                key: \"View 1\",\n                label: \"View 1\",\n              },\n            ],\n          },\n        },\n        {\n          version: 0,\n          displayName: \"container4\",\n          parentNode: \"canvas7\",\n          showName: \"container\",\n          childrenNode: [\n            {\n              version: 0,\n              displayName: \"canvas10\",\n              parentNode: \"container4\",\n              showName: \"canvas\",\n              childrenNode: [\n                {\n                  version: 0,\n                  displayName: \"text6\",\n                  parentNode: \"canvas10\",\n                  showName: \"text\",\n                  childrenNode: [],\n                  type: \"TEXT_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 23,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 5,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    borderWidth: \"14px\",\n                    colorScheme: \"grayBlue\",\n                    disableMarkdown: false,\n                    dynamicHeight: \"auto\",\n                    fs: \"14px\",\n                    hidden: false,\n                    horizontalAlign: \"start\",\n                    resizeDirection: \"HORIZONTAL\",\n                    value:\n                      \"1. Receive user input as strings: `input`,` text area`, etc.  \\n2. Receive user input as numbers: `number input`, `slider`, etc., or use the `input` component and convert its value to a number type, such as `parseInt(input1.value)`.\\n3. Receive user input as files: `file uploader`.\\n4. Display data: `data grid`, `list`, `chart`, etc.\\n5. Display files: `image`, `video`, `pdf`, etc.\",\n                    verticalAlign: \"center\",\n                  },\n                },\n                {\n                  version: 0,\n                  displayName: \"text16\",\n                  parentNode: \"canvas10\",\n                  showName: \"text\",\n                  childrenNode: [],\n                  type: \"TEXT_WIDGET\",\n                  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n                  h: 5,\n                  w: 32,\n                  minH: 3,\n                  minW: 1,\n                  x: 0,\n                  y: 0,\n                  z: 0,\n                  props: {\n                    $dynamicAttrPaths: [],\n                    borderWidth: \"15px\",\n                    colorScheme: \"grayBlue\",\n                    disableMarkdown: false,\n                    dynamicHeight: \"auto\",\n                    fs: \"15px\",\n                    hidden: false,\n                    horizontalAlign: \"start\",\n                    resizeDirection: \"HORIZONTAL\",\n                    value:\n                      \"The components we provide can address the majority of requirements in most scenarios.\",\n                    verticalAlign: \"center\",\n                  },\n                },\n              ],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n            {\n              version: 0,\n              displayName: \"canvas11\",\n              parentNode: \"container4\",\n              showName: \"canvas\",\n              childrenNode: [],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n            {\n              version: 0,\n              displayName: \"canvas12\",\n              parentNode: \"container4\",\n              showName: \"canvas\",\n              childrenNode: [],\n              type: \"CANVAS\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 1,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n          ],\n          type: \"CONTAINER_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 42,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 25,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            backgroundColor: \"#f5f5f5ff\",\n            currentIndex: 0,\n            currentKey: \"View 1\",\n            dynamicHeight: \"auto\",\n            padding: {\n              mode: \"all\",\n              size: \"24\",\n            },\n            radius: \"4px\",\n            resizeDirection: \"HORIZONTAL\",\n            shadow: \"none\",\n            viewList: [\n              {\n                id: \"1b063da1-bb04-4321-be13-ee13e2178141\",\n                key: \"View 1\",\n                label: \"View 1\",\n              },\n              {\n                id: \"0fea99bb-df46-45ef-aa46-c6b05c6ac074\",\n                key: \"View 2\",\n                label: \"View 2\",\n              },\n              {\n                id: \"10817fe8-3c53-4bbb-af8c-ab076d324c27\",\n                key: \"View 3\",\n                label: \"View 3\",\n              },\n            ],\n          },\n        },\n      ],\n      type: \"CANVAS\",\n      containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n      h: 0,\n      w: 0,\n      minH: 0,\n      minW: 1,\n      x: -1,\n      y: -1,\n      z: 0,\n      props: {},\n    },\n    {\n      version: 0,\n      displayName: \"canvas8\",\n      parentNode: \"container3\",\n      showName: \"canvas\",\n      childrenNode: [],\n      type: \"CANVAS\",\n      containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n      h: 0,\n      w: 0,\n      minH: 0,\n      minW: 1,\n      x: -1,\n      y: -1,\n      z: 0,\n      props: {},\n    },\n    {\n      version: 0,\n      displayName: \"canvas9\",\n      parentNode: \"container3\",\n      showName: \"canvas\",\n      childrenNode: [],\n      type: \"CANVAS\",\n      containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n      h: 0,\n      w: 0,\n      minH: 0,\n      minW: 1,\n      x: -1,\n      y: -1,\n      z: 0,\n      props: {},\n    },\n  ],\n  type: \"CONTAINER_WIDGET\",\n  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n  h: 473,\n  w: 13,\n  minH: 3,\n  minW: 1,\n  x: 0,\n  y: 0,\n  z: 0,\n  props: {\n    $dynamicAttrPaths: [],\n    backgroundColor: \"#ffffffff\",\n    currentIndex: 0,\n    currentKey: \"View 1\",\n    dynamicHeight: \"auto\",\n    padding: {\n      mode: \"all\",\n      size: \"40\",\n    },\n    radius: \"4px\",\n    resizeDirection: \"HORIZONTAL\",\n    shadow: \"small\",\n    viewList: [\n      {\n        id: \"2468b61b-ee26-4279-b65d-0321f6ea94ab\",\n        key: \"View 1\",\n        label: \"View 1\",\n      },\n      {\n        id: \"a564e82e-c76e-491a-b154-84db3077a965\",\n        key: \"View 2\",\n        label: \"View 2\",\n      },\n      {\n        id: \"250a835b-2897-41f8-93a0-25278669160f\",\n        key: \"View 3\",\n        label: \"View 3\",\n      },\n    ],\n  },\n}\n\nexport const AGENT_INPUT_CONTAINER_NODE: ComponentTreeNode = {\n  version: 0,\n  displayName: \"container1\",\n  parentNode: \"bodySection1-bodySectionContainer1\",\n  showName: \"container\",\n  childrenNode: [\n    {\n      version: 0,\n      displayName: \"canvas1\",\n      parentNode: \"container1\",\n      showName: \"canvas\",\n      childrenNode: [\n        {\n          version: 0,\n          displayName: \"text3\",\n          parentNode: \"canvas1\",\n          showName: \"text\",\n          childrenNode: [],\n          type: \"TEXT_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 4,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 21,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            colorScheme: \"grayBlue\",\n            disableMarkdown: false,\n            dynamicHeight: \"auto\",\n            fs: \"14px\",\n            hidden: false,\n            horizontalAlign: \"start\",\n            resizeDirection: \"HORIZONTAL\",\n            value: \"**Send to AI Agent**\",\n            verticalAlign: \"center\",\n          },\n        },\n        {\n          version: 0,\n          displayName: \"text12\",\n          parentNode: \"canvas1\",\n          showName: \"text\",\n          childrenNode: [],\n          type: \"TEXT_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 12,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 0,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            colorScheme: \"grayBlue\",\n            disableMarkdown: false,\n            dynamicHeight: \"auto\",\n            fs: \"14px\",\n            hidden: false,\n            horizontalAlign: \"start\",\n            resizeDirection: \"HORIZONTAL\",\n            value: \"# Demo built with your AI Agent\",\n            verticalAlign: \"center\",\n          },\n        },\n        {\n          version: 0,\n          displayName: \"divider3\",\n          parentNode: \"canvas1\",\n          showName: \"divider\",\n          childrenNode: [],\n          type: \"DIVIDER_WIDGET\",\n          containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n          h: 5,\n          w: 32,\n          minH: 3,\n          minW: 1,\n          x: 0,\n          y: 12,\n          z: 0,\n          props: {\n            $dynamicAttrPaths: [],\n            colorScheme: \"grayBlue\",\n            fs: \"14px\",\n            hidden: false,\n          },\n        },\n      ],\n      type: \"CANVAS\",\n      containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n      h: 0,\n      w: 0,\n      minH: 0,\n      minW: 1,\n      x: -1,\n      y: -1,\n      z: 0,\n      props: {},\n    },\n    {\n      version: 0,\n      displayName: \"canvas2\",\n      parentNode: \"container1\",\n      showName: \"canvas\",\n      childrenNode: [],\n      type: \"CANVAS\",\n      containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n      h: 0,\n      w: 0,\n      minH: 0,\n      minW: 1,\n      x: -1,\n      y: -1,\n      z: 0,\n      props: {},\n    },\n    {\n      version: 0,\n      displayName: \"canvas3\",\n      parentNode: \"container1\",\n      showName: \"canvas\",\n      childrenNode: [],\n      type: \"CANVAS\",\n      containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n      h: 0,\n      w: 0,\n      minH: 0,\n      minW: 1,\n      x: -1,\n      y: -1,\n      z: 0,\n      props: {},\n    },\n  ],\n  type: \"CONTAINER_WIDGET\",\n  containerType: CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n  h: 395,\n  w: 19,\n  minH: 3,\n  minW: 1,\n  x: 13,\n  y: 0,\n  z: 0,\n  props: {\n    $dynamicAttrPaths: [],\n    backgroundColor: \"#ffffffff\",\n    currentIndex: 0,\n    currentKey: \"View 1\",\n    dynamicHeight: \"auto\",\n    padding: {\n      mode: \"all\",\n      size: \"40\",\n    },\n    radius: \"4px\",\n    resizeDirection: \"HORIZONTAL\",\n    shadow: \"small\",\n    viewList: [\n      {\n        id: \"2468b61b-ee26-4279-b65d-0321f6ea94ab\",\n        key: \"View 1\",\n        label: \"View 1\",\n      },\n      {\n        id: \"a564e82e-c76e-491a-b154-84db3077a965\",\n        key: \"View 2\",\n        label: \"View 2\",\n      },\n      {\n        id: \"250a835b-2897-41f8-93a0-25278669160f\",\n        key: \"View 3\",\n        label: \"View 3\",\n      },\n    ],\n  },\n}\n\nexport const TEST_ROOT_NODE: ComponentTreeNode = {\n  version: 0,\n  displayName: \"root\",\n  parentNode: \"\",\n  showName: \"root\",\n  childrenNode: [\n    {\n      version: 0,\n      displayName: \"guide\",\n      parentNode: \"root\",\n      showName: \"page\",\n      childrenNode: [\n        {\n          version: 0,\n          displayName: \"bodySection1\",\n          parentNode: \"guide\",\n          showName: \"bodySection\",\n          childrenNode: [\n            {\n              version: 0,\n              displayName: \"bodySection1-bodySectionContainer1\",\n              parentNode: \"bodySection1\",\n              showName: \"bodySection1-bodySectionContainer1\",\n              childrenNode: [TIP_NODES, AGENT_INPUT_CONTAINER_NODE],\n              type: \"CONTAINER_NODE\",\n              containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n              h: 0,\n              w: 0,\n              minH: 0,\n              minW: 0,\n              x: -1,\n              y: -1,\n              z: 0,\n              props: {},\n            },\n          ],\n          type: \"SECTION_NODE\",\n          containerType: CONTAINER_TYPE.EDITOR_LAYOUT_SQUARE,\n\n          h: 0,\n          w: 0,\n          minH: 0,\n          minW: 0,\n          x: -1,\n          y: -1,\n          z: 0,\n          props: {\n            currentViewIndex: 0,\n            defaultViewKey: \"sub-page1\",\n            sectionViewConfigs: [\n              {\n                id: \"7b9a7598-f6a5-4440-919d-36d1dc26e8e0\",\n                key: \"sub-page1\",\n                path: \"how-to\",\n                viewDisplayName: \"bodySection1-bodySectionContainer1\",\n              },\n            ],\n            style: {\n              padding: {\n                size: \"48\",\n              },\n            },\n            viewSortedKey: [\"bodySection1-bodySectionContainer1\"],\n          },\n        },\n        {\n          version: 0,\n          displayName: \"modalSection1\",\n          parentNode: \"guide\",\n          showName: \"modalSection\",\n          childrenNode: [],\n          type: \"MODAL_SECTION_NODE\",\n          containerType: CONTAINER_TYPE.EDITOR_LAYOUT_SQUARE,\n          h: 0,\n          w: 0,\n          minH: 0,\n          minW: 0,\n          x: -1,\n          y: -1,\n          z: 0,\n          props: {},\n        },\n      ],\n      type: \"PAGE_NODE\",\n      containerType: CONTAINER_TYPE.EDITOR_PAGE_SQUARE,\n      h: 0,\n      w: 0,\n      minH: 0,\n      minW: 0,\n      x: -1,\n      y: -1,\n      z: 0,\n      props: {\n        bodyColumns: 32,\n        bottomHeight: 0,\n        canvasSize: \"fixed\",\n        canvasWidth: 1440,\n        footerColumns: 32,\n        hasFooter: false,\n        hasHeader: false,\n        hasLeft: false,\n        hasRight: false,\n        headerColumns: 32,\n        isFooterFixed: true,\n        isHeaderFixed: true,\n        isLeftFixed: true,\n        isRightFixed: true,\n        layout: \"default\",\n        leftColumns: 8,\n        leftPosition: \"NONE\",\n        leftWidth: 0,\n        rightColumns: 8,\n        rightPosition: \"NONE\",\n        rightWidth: 0,\n        showLeftFoldIcon: false,\n        showRightFoldIcon: false,\n        topHeight: 0,\n      },\n    },\n  ],\n  type: \"DOT_PANEL\",\n  containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n  h: 0,\n  w: 0,\n  minH: 0,\n  minW: 0,\n  x: -1,\n  y: -1,\n  z: 0,\n  props: {\n    currentPageIndex: 0,\n    homepageDisplayName: \"guide\",\n    pageSortedKey: [\"guide\"],\n    viewportSizeType: \"fluid\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/config/guide/actions.json",
    "content": "[\n  {\n    \"displayName\": \"postgresql1\",\n    \"actionType\": \"postgresql\",\n    \"content\": {\n      \"mode\": \"sql\",\n      \"query\": \"\"\n    },\n    \"transformer\": {\n      \"enable\": false,\n      \"rawData\": \"\"\n    },\n    \"triggerMode\": \"automate\",\n    \"config\": {\n      \"public\": false\n    }\n  }\n]"
  },
  {
    "path": "apps/builder/src/config/guide/components.json",
    "content": "[\n  {\n    \"version\": 0,\n    \"displayName\": \"input1\",\n    \"parentNode\": \"bodySection1-bodySectionContainer1\",\n    \"showName\": \"input\",\n    \"childrenNode\": null,\n    \"type\": \"INPUT_WIDGET\",\n    \"containerType\": \"EDITOR_SCALE_SQUARE\",\n    \"h\": 6,\n    \"w\": 8,\n    \"minH\": 3,\n    \"minW\": 1,\n    \"x\": 9,\n    \"y\": 17,\n    \"z\": 0,\n    \"props\": {\n      \"$dynamicAttrPaths\": [\"formDataKey\", \"labelWidth\"],\n      \"colorScheme\": \"blue\",\n      \"formDataKey\": \"{{input1.displayName}}\",\n      \"hidden\": false,\n      \"label\": \"Label\",\n      \"labelAlign\": \"left\",\n      \"labelPosition\": \"left\",\n      \"labelWidth\": \"{{33}}\",\n      \"placeholder\": \"input sth\",\n      \"value\": \"\"\n    }\n  },\n  {\n    \"version\": 0,\n    \"displayName\": \"button1\",\n    \"parentNode\": \"bodySection1-bodySectionContainer1\",\n    \"showName\": \"button\",\n    \"childrenNode\": null,\n    \"type\": \"BUTTON_WIDGET\",\n    \"containerType\": \"EDITOR_SCALE_SQUARE\",\n    \"h\": 5,\n    \"w\": 6,\n    \"minH\": 3,\n    \"minW\": 1,\n    \"x\": 17,\n    \"y\": 17,\n    \"z\": 0,\n    \"props\": {\n      \"$dynamicAttrPaths\": [],\n      \"colorScheme\": \"blue\",\n      \"events\": [\n        {\n          \"actionType\": \"datasource\",\n          \"eventType\": \"click\",\n          \"id\": \"events-dc33da8b-1dec-49ea-b4b6-44d7570e6ec9\",\n          \"queryID\": \"postgresql1\"\n        }\n      ],\n      \"hidden\": false,\n      \"text\": \"Button\",\n      \"variant\": \"fill\"\n    }\n  },\n  {\n    \"w\": 18,\n    \"h\": 50,\n    \"minW\": 1,\n    \"minH\": 3,\n    \"x\": 7,\n    \"y\": 9,\n    \"z\": 0,\n    \"showName\": \"dataGrid\",\n    \"type\": \"DATA_GRID_WIDGET\",\n    \"displayName\": \"dataGrid1\",\n    \"containerType\": \"EDITOR_SCALE_SQUARE\",\n    \"parentNode\": \"bodySection1-bodySectionContainer1\",\n    \"childrenNode\": [],\n    \"props\": {\n      \"dataSourceMode\": \"dynamic\",\n      \"excludeHiddenColumns\": true,\n      \"dataSourceJS\": \"{{[\\n  {\\n    \\\"month\\\": \\\"April\\\",\\n    \\\"users\\\": 3700,\\n    \\\"incomes\\\": 4000\\n  },\\n  {\\n    \\\"month\\\": \\\"May\\\",\\n    \\\"users\\\": 5400,\\n    \\\"incomes\\\": 8700\\n  },\\n  {\\n    \\\"month\\\": \\\"June\\\",\\n    \\\"users\\\": 6000,\\n    \\\"incomes\\\": 12000\\n  },\\n  {\\n    \\\"month\\\": \\\"July\\\",\\n    \\\"users\\\": 8000,\\n    \\\"incomes\\\": 14000\\n  }\\n]}}\",\n      \"dataSource\": [],\n      \"overFlow\": \"scroll\",\n      \"sortOrder\": \"default\",\n      \"$dynamicAttrPaths\": [\"dataSourceJS\"],\n      \"columns\": [\n        {\n          \"field\": \"month\",\n          \"headerName\": \"month\",\n          \"width\": 170,\n          \"isCalc\": true,\n          \"description\": \"\",\n          \"sortable\": true,\n          \"pinnable\": true,\n          \"filterable\": true,\n          \"hideable\": true,\n          \"aggregable\": true,\n          \"groupable\": true,\n          \"resizable\": true,\n          \"columnType\": \"auto\",\n          \"disableReorder\": false,\n          \"headerAlign\": \"left\"\n        },\n        {\n          \"field\": \"users\",\n          \"headerName\": \"users\",\n          \"width\": 170,\n          \"isCalc\": true,\n          \"description\": \"\",\n          \"sortable\": true,\n          \"pinnable\": true,\n          \"filterable\": true,\n          \"hideable\": true,\n          \"aggregable\": true,\n          \"groupable\": true,\n          \"resizable\": true,\n          \"columnType\": \"auto\",\n          \"disableReorder\": false,\n          \"headerAlign\": \"left\"\n        },\n        {\n          \"field\": \"incomes\",\n          \"headerName\": \"incomes\",\n          \"width\": 170,\n          \"isCalc\": true,\n          \"description\": \"\",\n          \"sortable\": true,\n          \"pinnable\": true,\n          \"filterable\": true,\n          \"hideable\": true,\n          \"aggregable\": true,\n          \"groupable\": true,\n          \"resizable\": true,\n          \"columnType\": \"auto\",\n          \"disableReorder\": false,\n          \"headerAlign\": \"left\"\n        }\n      ]\n    },\n    \"version\": 0\n  }\n]\n"
  },
  {
    "path": "apps/builder/src/config/guide/config.tsx",
    "content": "import { MysqlLikeAction } from \"@illa-public/public-types\"\nimport ButtonHighlightIcon from \"@/assets/widgetCover/button-highlight.svg\"\nimport InputHighlightIcon from \"@/assets/widgetCover/input-highlight.svg\"\nimport TableHighlightIcon from \"@/assets/widgetCover/table-highlight.svg\"\nimport { GUIDE_COMPONENTS } from \"@/config/guide/index\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { guideActions } from \"@/redux/guide/guideSlice\"\nimport store from \"@/store\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\n\nexport const SELECT_WIDGET_ITEM = {\n  INPUT_WIDGET: {\n    highlightIcon: InputHighlightIcon,\n    ...widgetBuilder(\"INPUT_WIDGET\").config,\n  },\n  BUTTON_WIDGET: {\n    highlightIcon: ButtonHighlightIcon,\n    ...widgetBuilder(\"BUTTON_WIDGET\").config,\n  },\n  DATA_GRID_WIDGET: {\n    highlightIcon: TableHighlightIcon,\n    ...widgetBuilder(\"DATA_GRID_WIDGET\").config,\n  },\n}\n\nexport type SelectWidget = keyof typeof SELECT_WIDGET_ITEM\n\nexport const GUIDE_SELECT_WIDGET = Object.keys(\n  SELECT_WIDGET_ITEM,\n) as SelectWidget[]\n\nexport const GUIDE_SQL_QUERY =\n  \"select * \\n\" +\n  \"from users\\n\" +\n  \"join orders\\n\" +\n  \"on users.id = orders.id\\n\" +\n  \"where {{!input1.value}} or lower(users.name) like '%{{input1.value.toLowerCase()}}%'\"\n\nexport const GUIDE_STEP = [\n  {\n    // 0\n    step: 0.1,\n    titleKey: \"editor.tutorial.panel.onboarding_app.drag_title\",\n    descKey: \"editor.tutorial.panel.onboarding_app.drag_input\",\n    widgetType: \"INPUT_WIDGET\",\n    selector: `[data-onboarding-element=\"INPUT_WIDGET\"]`,\n    reduxAction: \"components/addComponentReducer\",\n    doItForMe: () => {\n      // filter already generate component\n      const Components = GUIDE_COMPONENTS.filter((componentNode) => {\n        return !DisplayNameGenerator.isAlreadyGenerate(\n          componentNode.displayName,\n        )\n      })\n      Components?.forEach((componentNode) => {\n        DisplayNameGenerator.addComponentDisplayName(componentNode)\n      })\n      store.dispatch(componentsActions.addComponentReducer(Components))\n      store.dispatch(guideActions.updateCurrentStepReducer(3))\n    },\n  },\n  {\n    step: 0.2,\n    titleKey: \"\",\n    descKey: \"\",\n    selector: \"\",\n    widgetType: \"BUTTON_WIDGET\",\n    reduxAction: \"components/addComponentReducer\",\n  },\n  {\n    step: 0.3,\n    titleKey: \"\",\n    descKey: \"\",\n    selector: \"\",\n    widgetType: \"DATA_GRID_WIDGET\",\n    reduxAction: \"components/addComponentReducer\",\n  },\n  {\n    // 1\n    step: 1,\n    titleKey: \"editor.tutorial.panel.onboarding_app.modify_action_title\",\n    descKey:\n      \"editor.tutorial.panel.onboarding_app.modify_action_description_modify\",\n    selector: \".postgresql1-query\",\n    reduxAction: \"config/updateCachedAction\",\n    doItForMe: () => {\n      const currentAction = getCachedAction(store.getState())!!\n      const mysqlContent = currentAction.content as MysqlLikeAction\n      store.dispatch(\n        configActions.updateCachedAction({\n          ...currentAction,\n          content: {\n            ...mysqlContent,\n            query: GUIDE_SQL_QUERY,\n          },\n        }),\n      )\n    },\n  },\n  {\n    step: 2,\n    titleKey: \"editor.tutorial.panel.onboarding_app.modify_action_title\",\n    descKey:\n      \"editor.tutorial.panel.onboarding_app.modify_action_description_click\",\n    selector: \".postgresql1-run\",\n    reduxAction: \"guideActions/updateNextStepReducer\",\n    doItForMe: () => {\n      const element = document.querySelector(\n        \".postgresql1-run\",\n      ) as HTMLButtonElement\n      element?.click()\n    },\n  },\n  {\n    // 2\n    step: 3,\n    titleKey: \"editor.tutorial.panel.onboarding_app.display_data_title\",\n    descKey:\n      \"editor.tutorial.panel.onboarding_app.display_data_description_select\",\n    selector: `[data-displayname=\"dataGrid1\"]`,\n    displayName: `dataGrid1`,\n    reduxAction: \"config/updateSelectedComponent\",\n    doItForMe: () => {\n      store.dispatch(configActions.updateSelectedComponent([\"dataGrid1\"]))\n    },\n  },\n  {\n    step: 4,\n    titleKey: \"editor.tutorial.panel.onboarding_app.display_data_title\",\n    descKey:\n      \"editor.tutorial.panel.onboarding_app.display_data_description_modify\",\n    selector: \"dataGrid-data-source\",\n    doItForMe: () => {\n      store.dispatch(\n        componentsActions.updateComponentPropsReducer({\n          displayName: \"dataGrid1\",\n          updateSlice: {\n            dataSourceJS: \"{{postgresql1.data}}\",\n          },\n        }),\n      )\n    },\n  },\n  {\n    // 3\n    step: 5,\n    titleKey: \"editor.tutorial.panel.onboarding_app.event_handler_title\",\n    descKey: \"editor.tutorial.panel.onboarding_app.event_handler_description_1\",\n    selector: `[data-displayname=\"button1\"]`,\n    displayName: `button1`,\n    reduxAction: \"config/updateSelectedComponent\",\n    doItForMe: () => {\n      store.dispatch(configActions.updateSelectedComponent([\"button1\"]))\n    },\n  },\n  {\n    step: 6,\n    titleKey: \"editor.tutorial.panel.onboarding_app.event_handler_title\",\n    descKey:\n      \"editor.tutorial.panel.onboarding_app.event_handler_description_all\",\n    selector: \"button-interaction-event-handler\",\n    doItForMe: () => {\n      // whole event\n      store.dispatch(\n        componentsActions.updateComponentPropsReducer({\n          displayName: \"button1\",\n          updateSlice: {\n            \"events.0\": {\n              id: \"events-3e2c0390-b4f7-4570-9f4b-93c5d59e4c13\",\n              eventType: \"click\",\n              queryID: \"postgresql1\",\n              actionType: \"datasource\",\n              method: \"trigger\",\n            },\n          },\n        }),\n      )\n      // to last step\n      store.dispatch(guideActions.updateCurrentStepReducer(11))\n    },\n  },\n  {\n    step: 8,\n    titleKey: \"editor.tutorial.panel.onboarding_app.event_handler_title\",\n    descKey: \"editor.tutorial.panel.onboarding_app.event_handler_description_4\",\n    selector: \"button-interaction-event-handler-action\",\n    hideTrigger: true,\n  },\n  {\n    step: 9,\n    titleKey: \"editor.tutorial.panel.onboarding_app.event_handler_title\",\n    descKey: \"editor.tutorial.panel.onboarding_app.event_handler_description_5\",\n    selector: \"button-interaction-event-handler-query\",\n    hideTrigger: true,\n  },\n  {\n    // 4\n    step: 10,\n    titleKey: \"editor.tutorial.panel.onboarding_app.test_it_title\",\n    descKey: \"editor.tutorial.panel.onboarding_app.test_it_description\",\n    selector: `[data-onboarding-comp=\"componentsManager\"]`,\n    hideExit: true,\n    doItForMe: () => {\n      store.dispatch(guideActions.updateCurrentStepReducer(12))\n    },\n  },\n  {\n    // success\n    step: 10,\n    titleKey: \"editor.tutorial.panel.onboarding_app.congratulations_title\",\n    descKey: \"editor.tutorial.panel.onboarding_app.congratulations_description\",\n    selector: `[data-onboarding-comp=\"componentsManager\"]`,\n    doItForMe: () => {\n      store.dispatch(guideActions.updateGuideStatusReducer(false))\n    },\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/config/guide/data.json",
    "content": "{\n  \"appInfo\": {\n    \"appId\": \"ILAex4p1C72V\",\n    \"uid\": \"00000000-0000-0000-0000-000000000000\",\n    \"teamID\": \"ILAfx4p1C7d0\",\n    \"appName\": \"Onboarding\",\n    \"releaseVersion\": 0,\n    \"mainlineVersion\": 0,\n    \"config\": {\n      \"public\": false\n    },\n    \"updatedBy\": \"ILAfx4p1C7dY\",\n    \"updatedAt\": \"2023-03-23T12:34:13.257406Z\",\n    \"appActivity\": {\n      \"modifier\": \"\",\n      \"modifiedAt\": \"2023-03-23T12:34:13.257406Z\"\n    }\n  },\n  \"actions\": [\n    {\n      \"actionID\": \"ILAfx4p1C7uH\",\n      \"uid\": \"ae9a691d-cc16-48fe-8f57-addfbfe55f0c\",\n      \"teamID\": \"ILAfx4p1C7en\",\n      \"resourceID\": \"ILAfx4p1C7cn\",\n      \"displayName\": \"postgresql1\",\n      \"actionType\": \"postgresql\",\n      \"content\": {\n        \"mode\": \"sql\",\n        \"query\": \"\"\n      },\n      \"transformer\": {\n        \"enable\": false,\n        \"rawData\": \"\"\n      },\n      \"triggerMode\": \"manually\",\n      \"config\": {\n        \"public\": false\n      },\n      \"createdAt\": \"2023-03-22T12:06:12.256742Z\",\n      \"createdBy\": \"ILAfx4p1C7eb\",\n      \"updatedAt\": \"2023-03-22T14:04:51.111263Z\",\n      \"updatedBy\": \"ILAfx4p1C7dY\"\n    }\n  ],\n  \"components\": {\n    \"displayName\": \"root\",\n    \"parentNode\": \"\",\n    \"showName\": \"root\",\n\n    \"childrenNode\": [\n      {\n        \"displayName\": \"page1\",\n        \"parentNode\": \"root\",\n        \"showName\": \"page\",\n\n        \"childrenNode\": [\n          {\n            \"displayName\": \"bodySection1\",\n            \"parentNode\": \"page1\",\n            \"showName\": \"bodySection\",\n\n            \"childrenNode\": [\n              {\n                \"displayName\": \"bodySection1-bodySectionContainer1\",\n                \"parentNode\": \"bodySection1\",\n                \"showName\": \"bodySection1-bodySectionContainer1\",\n\n                \"childrenNode\": null,\n                \"type\": \"CONTAINER_NODE\",\n                \"containerType\": \"EDITOR_DOT_PANEL\",\n\n                \"h\": 0,\n                \"w\": 0,\n                \"minH\": 0,\n                \"minW\": 0,\n\n                \"x\": -1,\n                \"y\": -1,\n                \"z\": 0,\n                \"props\": {}\n              }\n            ],\n            \"type\": \"SECTION_NODE\",\n            \"containerType\": \"EDITOR_LAYOUT_SQUARE\",\n\n            \"h\": 0,\n            \"w\": 0,\n            \"minH\": 0,\n            \"minW\": 0,\n\n            \"x\": -1,\n            \"y\": -1,\n            \"z\": 0,\n            \"props\": {\n              \"currentViewIndex\": 0,\n              \"defaultViewKey\": \"View 1\",\n              \"sectionViewConfigs\": [\n                {\n                  \"id\": \"db44821a-9b18-4756-ab0d-dd3a1d499fe7\",\n                  \"key\": \"View 1\",\n                  \"path\": \"View 1\",\n                  \"viewDisplayName\": \"bodySection1-bodySectionContainer1\"\n                }\n              ],\n              \"viewSortedKey\": [\"bodySection1-bodySectionContainer1\"]\n            }\n          },\n          {\n            \"displayName\": \"modalSection1\",\n            \"parentNode\": \"page1\",\n            \"showName\": \"modalSection\",\n\n            \"childrenNode\": null,\n            \"type\": \"MODAL_SECTION_NODE\",\n            \"containerType\": \"EDITOR_LAYOUT_SQUARE\",\n\n            \"h\": 0,\n            \"w\": 0,\n            \"minH\": 0,\n            \"minW\": 0,\n\n            \"x\": -1,\n            \"y\": -1,\n            \"z\": 0,\n            \"props\": {}\n          }\n        ],\n        \"type\": \"PAGE_NODE\",\n        \"containerType\": \"EDITOR_PAGE_SQUARE\",\n\n        \"h\": 0,\n        \"w\": 0,\n        \"minH\": 0,\n        \"minW\": 0,\n\n        \"x\": -1,\n        \"y\": -1,\n        \"z\": 0,\n        \"props\": {\n          \"bodyColumns\": 32,\n          \"bottomHeight\": 0,\n          \"canvasSize\": \"auto\",\n          \"canvasWidth\": 100,\n          \"footerColumns\": 32,\n          \"hasFooter\": false,\n          \"hasHeader\": false,\n          \"hasLeft\": false,\n          \"hasRight\": false,\n          \"headerColumns\": 32,\n          \"isFooterFixed\": true,\n          \"isHeaderFixed\": true,\n          \"isLeftFixed\": true,\n          \"isRightFixed\": true,\n          \"layout\": \"default\",\n          \"leftColumns\": 32,\n          \"leftPosition\": \"NONE\",\n          \"leftWidth\": 0,\n          \"rightColumns\": 32,\n          \"rightPosition\": \"NONE\",\n          \"rightWidth\": 0,\n          \"showLeftFoldIcon\": false,\n          \"showRightFoldIcon\": false,\n          \"topHeight\": 0\n        }\n      }\n    ],\n    \"type\": \"DOT_PANEL\",\n    \"containerType\": \"EDITOR_DOT_PANEL\",\n\n    \"h\": 0,\n    \"w\": 0,\n    \"minH\": 0,\n    \"minW\": 0,\n\n    \"x\": -1,\n    \"y\": -1,\n    \"z\": 0,\n    \"props\": {\n      \"currentPageIndex\": 0,\n      \"pageSortedKey\": [\"page1\"]\n    }\n  },\n  \"dependenciesState\": {},\n  \"dragShadowState\": {},\n  \"dottedLineSquareState\": {},\n  \"displayNameState\": []\n}\n"
  },
  {
    "path": "apps/builder/src/config/guide/index.ts",
    "content": "import {\n  ActionContent,\n  ActionItem,\n  ComponentTreeNode,\n  Resource,\n  ResourceContent,\n} from \"@illa-public/public-types\"\nimport { isEqual } from \"lodash-es\"\nimport { v4 } from \"uuid\"\nimport { createResource } from \"@/api/actions\"\nimport Actions from \"@/config/guide/actions.json\"\nimport Components from \"@/config/guide/components.json\"\nimport data from \"@/config/guide/data.json\"\nimport Resources from \"@/config/guide/resources.json\"\nimport { TemplateActions, TemplateResources } from \"@/config/template/interface\"\nimport { fixedActionToNewAction } from \"@/hooks/utils/fixedAction\"\nimport { CurrentAppResp } from \"@/page/App/resp/currentAppResp\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { getAllResources } from \"@/redux/resource/resourceSelector\"\nimport store from \"@/store\"\n\nexport const GUIDE_COMPONENTS = Components as unknown as ComponentTreeNode[]\nexport const GUIDE_RESOURCES = Resources as Resource<ResourceContent>[]\nexport const GUIDE_ACTIONS = Actions\n\n// [TODO] remove actionID when test run. @xiaoyu @karminski\nexport const GUIDE_DEFAULT_ACTION_ID = \"ILAfx4p1C7d0\"\n\nexport const GUIDE_DATA = data as unknown as CurrentAppResp\n\nconst formatAppDataToConfig = (currentApp: CurrentAppResp) => {\n  const resourceIDList = currentApp.actions.map((action) => action.resourceID)\n\n  // get resources form resourceIDList, and generate filter\n  const resources = GUIDE_RESOURCES.filter((resource) =>\n    resourceIDList.includes(resource.resourceID),\n  ).map(({ resourceName, resourceType, content }) => ({\n    resourceName,\n    resourceType,\n    content,\n  })) as TemplateResources\n\n  // Add the resourceIndex attribute to actions\n  const actions = currentApp.actions.map(\n    ({\n      resourceID,\n      displayName,\n      actionType,\n      transformer,\n      triggerMode,\n      content,\n      config,\n    }) => {\n      const resourceIndex = resourceIDList.indexOf(resourceID)\n      return {\n        resourceID,\n        displayName,\n        actionType,\n        transformer,\n        triggerMode,\n        content,\n        config,\n        resourceIndex,\n      }\n    },\n  ) as TemplateActions\n\n  return {\n    resources,\n    actions,\n  }\n}\n\nexport const GUIDE_CONFIG = formatAppDataToConfig(GUIDE_DATA)\n\nexport const initGuideApp = async (): Promise<CurrentAppResp> => {\n  const { actions, resources } = GUIDE_CONFIG\n  const currentResources = getAllResources(store.getState())\n  const resourceList = await Promise.all(\n    resources.map((data) => {\n      const resource = currentResources.find(\n        (item) =>\n          item.resourceName === data.resourceName &&\n          item.resourceType === data.resourceType &&\n          isEqual(item.content, data.content),\n      )\n      return resource ? resource.resourceID : createResource(data)\n    }),\n  )\n  // init actions\n  let actionList\n  if (resourceList.length) {\n    actionList = await Promise.all(\n      actions.map((data) => {\n        const { resourceIndex, ...actionData } = data\n        const resourceID = resourceList[resourceIndex] || \"\"\n        return {\n          ...actionData,\n          resourceID,\n          actionID: v4(),\n        } as ActionItem<ActionContent>\n      }),\n    )\n    if (actionList?.length) {\n      const currentAction = fixedActionToNewAction(actionList)[0]\n      store.dispatch(actionActions.addActionItemReducer(currentAction))\n      store.dispatch(configActions.changeSelectedAction(currentAction))\n    }\n  }\n\n  return {\n    ...GUIDE_DATA,\n    actions: actionList ?? [],\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/config/guide/resources.json",
    "content": "[\n  {\n    \"resourceID\": \"ILAfx4p1C7cn\",\n    \"uid\": \"518778b8-7b56-409b-8b57-244abb624d7e\",\n    \"teamID\": \"ILAfx4p1C7en\",\n    \"resourceIndex\": 0,\n    \"resourceName\": \"Onboarding DB\",\n    \"resourceType\": \"postgresql\",\n    \"content\": {\n      \"databaseName\": \"illa_demo\",\n      \"databasePassword\": \"illa2022\",\n      \"databaseUsername\": \"illa\",\n      \"host\": \"onboarding-postgres01v.illacloud.com\",\n      \"port\": \"30739\",\n      \"ssl\": {\n        \"clientCert\": \"\",\n        \"clientKey\": \"\",\n        \"serverCert\": \"\",\n        \"ssl\": false\n      }\n    },\n    \"createdAt\": \"2023-03-14T12:31:02.198393Z\",\n    \"createdBy\": \"ILAfx4p1C7eb\",\n    \"updatedAt\": \"2023-03-15T11:08:05.864299Z\",\n    \"updatedBy\": \"ILAfx4p1C7eb\"\n  }\n]\n"
  },
  {
    "path": "apps/builder/src/config/template/interface.ts",
    "content": "import {\n  ActionContent,\n  ResourceContent,\n  ResourceType,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\n\nexport type TemplateResources = {\n  resourceName: string\n  resourceType: ResourceType\n  content: ResourceContent\n}[]\n\nexport type TemplateAction<T extends ActionContent> = Partial<ActionItem<T>> & {\n  // The resourceIndex here is used to replace the real resourceID later.\n  resourceIndex: number\n}\n\nexport type TemplateActions = TemplateAction<ActionContent>[]\n"
  },
  {
    "path": "apps/builder/src/constants/currency.ts",
    "content": "export const CurrencyCode = {\n  AED: \"د.إ\",\n  AFN: \"؋\",\n  ALL: \"L\",\n  AMD: \"֏\",\n  ANG: \"ƒ\",\n  AOA: \"Kz\",\n  ARS: \"$\",\n  AUD: \"$\",\n  AWG: \"ƒ\",\n  AZN: \"₼\",\n  BAM: \"KM\",\n  BBD: \"$\",\n  BDT: \"৳\",\n  BGN: \"лв\",\n  BHD: \".د.ب\",\n  BIF: \"FBu\",\n  BMD: \"$\",\n  BND: \"$\",\n  BOB: \"$b\",\n  BRL: \"R$\",\n  BSD: \"$\",\n  BTC: \"₿\",\n  BTN: \"Nu.\",\n  BWP: \"P\",\n  BYR: \"Br\",\n  BYN: \"Br\",\n  BZD: \"BZ$\",\n  CAD: \"$\",\n  CDF: \"FC\",\n  CHF: \"CHF\",\n  CLP: \"$\",\n  CNY: \"¥\",\n  COP: \"$\",\n  CRC: \"₡\",\n  CUC: \"$\",\n  CUP: \"₱\",\n  CVE: \"$\",\n  CZK: \"Kč\",\n  DJF: \"Fdj\",\n  DKK: \"kr\",\n  DOP: \"RD$\",\n  DZD: \"دج\",\n  EEK: \"kr\",\n  EGP: \"£\",\n  ERN: \"Nfk\",\n  ETB: \"Br\",\n  ETH: \"Ξ\",\n  EUR: \"€\",\n  FJD: \"$\",\n  FKP: \"£\",\n  GBP: \"£\",\n  GEL: \"₾\",\n  GGP: \"£\",\n  GHC: \"₵\",\n  GHS: \"GH₵\",\n  GIP: \"£\",\n  GMD: \"D\",\n  GNF: \"FG\",\n  GTQ: \"Q\",\n  GYD: \"$\",\n  HKD: \"$\",\n  HNL: \"L\",\n  HRK: \"kn\",\n  HTG: \"G\",\n  HUF: \"Ft\",\n  IDR: \"Rp\",\n  ILS: \"₪\",\n  IMP: \"£\",\n  INR: \"₹\",\n  IQD: \"ع.د\",\n  IRR: \"﷼\",\n  ISK: \"kr\",\n  JEP: \"£\",\n  JMD: \"J$\",\n  JOD: \"JD\",\n  JPY: \"¥\",\n  KES: \"KSh\",\n  KGS: \"лв\",\n  KHR: \"៛\",\n  KMF: \"CF\",\n  KPW: \"₩\",\n  KRW: \"₩\",\n  KWD: \"KD\",\n  KYD: \"$\",\n  KZT: \"лв\",\n  LAK: \"₭\",\n  LBP: \"£\",\n  LKR: \"₨\",\n  LRD: \"$\",\n  LSL: \"M\",\n  LTC: \"Ł\",\n  LTL: \"Lt\",\n  LVL: \"Ls\",\n  LYD: \"LD\",\n  MAD: \"MAD\",\n  MDL: \"lei\",\n  MGA: \"Ar\",\n  MKD: \"ден\",\n  MMK: \"K\",\n  MNT: \"₮\",\n  MOP: \"MOP$\",\n  MRO: \"UM\",\n  MRU: \"UM\",\n  MUR: \"₨\",\n  MVR: \"Rf\",\n  MWK: \"MK\",\n  MXN: \"$\",\n  MYR: \"RM\",\n  MZN: \"MT\",\n  NAD: \"$\",\n  NGN: \"₦\",\n  NIO: \"C$\",\n  NOK: \"kr\",\n  NPR: \"₨\",\n  NZD: \"$\",\n  OMR: \"﷼\",\n  PAB: \"B/.\",\n  PEN: \"S/\",\n  PGK: \"K\",\n  PHP: \"₱\",\n  PKR: \"₨\",\n  PLN: \"zł\",\n  PYG: \"Gs\",\n  QAR: \"﷼\",\n  RMB: \"￥\",\n  RON: \"lei\",\n  RSD: \"Дин.\",\n  RUB: \"₽\",\n  RWF: \"R₣\",\n  SAR: \"﷼\",\n  SBD: \"$\",\n  SCR: \"₨\",\n  SDG: \"ج.س.\",\n  SEK: \"kr\",\n  SGD: \"S$\",\n  SHP: \"£\",\n  SLL: \"Le\",\n  SOS: \"S\",\n  SRD: \"$\",\n  SSP: \"£\",\n  STD: \"Db\",\n  STN: \"Db\",\n  SVC: \"$\",\n  SYP: \"£\",\n  SZL: \"E\",\n  THB: \"฿\",\n  TJS: \"SM\",\n  TMT: \"T\",\n  TND: \"د.ت\",\n  TOP: \"T$\",\n  TRL: \"₤\",\n  TRY: \"₺\",\n  TTD: \"TT$\",\n  TVD: \"$\",\n  TWD: \"NT$\",\n  TZS: \"TSh\",\n  UAH: \"₴\",\n  UGX: \"USh\",\n  USD: \"$\",\n  UYU: \"$U\",\n  UZS: \"so'm\",\n  VEF: \"Bs\",\n  VND: \"₫\",\n  VUV: \"VT\",\n  WST: \"WS$\",\n  XAF: \"FCFA\",\n  XBT: \"Ƀ\",\n  XCD: \"$\",\n  XOF: \"CFA\",\n  XPF: \"₣\",\n  YER: \"﷼\",\n  ZAR: \"R\",\n  ZMK: \"ZK\",\n  ZWD: \"Z$\",\n}\n\nexport const isValidCurrencyCode = (currencyCode: string, strict?: boolean) => {\n  const currencyCodeRegex = /^[A-Z]{3}$/\n  const isValidCode = currencyCodeRegex.test(currencyCode)\n  const isCurrencyCode = currencyCode in CurrencyCode\n\n  return strict ? isCurrencyCode : isValidCode\n}\n"
  },
  {
    "path": "apps/builder/src/env.d.ts",
    "content": "interface ImportMetaEnv {\n  readonly ILLA_API_BASE_URL: string\n  readonly ILLA_MARKET_URL: string\n  readonly ILLA_INSTANCE_ID: string\n  readonly ILLA_SENTRY_ENV: string\n  readonly ILLA_SENTRY_SERVER_API: string\n  readonly ILLA_APP_VERSION: string\n  readonly ILLA_APP_ENV: string\n  readonly ILLA_GOOGLE_MAP_KEY: string\n  readonly ILLA_BUILDER_URL: string\n  readonly ILLA_CLOUD_URL: string\n}\n\ninterface ImportMeta {\n  readonly env: ImportMetaEnv\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/useDestoryExecutionTree.ts",
    "content": "import { useEffect } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { cursorActions } from \"@/redux/currentApp/cursor/cursorSlice\"\nimport { dragShadowActions } from \"@/redux/currentApp/dragShadow/dragShadowSlice\"\nimport { destroyExecutionTree } from \"@/redux/currentApp/executionTree/executionListener\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { removeAllActionPeriod } from \"@/utils/action/runAction\"\nimport IllaUndoRedoManager from \"@/utils/undoRedo/undo\"\n\nexport const useDestroyApp = () => {\n  const dispatch = useDispatch()\n\n  const { appId } = useParams()\n\n  useEffect(() => {\n    return () => {\n      dispatch(executionActions.resetExecutionResultReducer())\n      dispatch(configActions.resetConfig())\n      dispatch(actionActions.resetActionReducer())\n      dispatch(componentsActions.resetComponentsReducer())\n      dispatch(cursorActions.resetCursorReducer())\n      dispatch(dragShadowActions.resetDragShadowInfoReducer())\n      destroyExecutionTree()\n      removeAllActionPeriod()\n      IllaUndoRedoManager.destroy()\n    }\n  }, [dispatch, appId])\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/useGoogleAuthStatus.tsx",
    "content": "import { GoogleSheetAuthStatus } from \"@illa-public/public-types\"\nimport { useEffect } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { useSearchParams } from \"react-router-dom\"\nimport { useMessage } from \"@illa-design/react\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\n\nexport const useGoogleAuthStatus = (\n  finished?: (resourceID: string) => void,\n) => {\n  const message = useMessage()\n  const actions = useSelector(getActionList)\n  const { t } = useTranslation()\n  const [urlParams, setUrlParams] = useSearchParams()\n\n  const status = urlParams.get(\"status\")\n  const resourceID = urlParams.get(\"resourceID\")\n\n  useEffect(() => {\n    if (resourceID == undefined || status == undefined) {\n      return\n    }\n    // redirect url: 1 success, 2 failed, reverse with resource\n    if (status === String(GoogleSheetAuthStatus.NotAuthenticated)) {\n      message.success({\n        content: t(\"editor.action.form.tips.gs.successfully_authent\"),\n      })\n    } else {\n      message.error({\n        content: t(\"editor.action.form.tips.gs.failed_to_authentica\"),\n      })\n    }\n    urlParams.delete(\"status\")\n    urlParams.delete(\"resourceID\")\n    setUrlParams(urlParams)\n    finished?.(resourceID)\n  }, [\n    actions,\n    finished,\n    message,\n    resourceID,\n    setUrlParams,\n    status,\n    t,\n    urlParams,\n  ])\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/useInitApp.tsx",
    "content": "import { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { useCallback, useEffect, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { useDestroyApp } from \"@/hooks/useDestoryExecutionTree\"\nimport { CurrentAppResp } from \"@/page/App/resp/currentAppResp\"\nimport { getIsOnline } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { IllaMode } from \"@/redux/config/configState\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { appInfoActions } from \"@/redux/currentApp/appInfo/appInfoSlice\"\nimport { DashboardAppInitialState } from \"@/redux/currentApp/appInfo/appInfoState\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\n// import { dashboardTeamAIAgentActions } from \"@/redux/dashboard/teamAIAgents/dashboardTeamAIAgentSlice\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { fetchTeamAgent } from \"@/services/agent\"\nimport { fetchPrivateAppInitData } from \"@/services/apps\"\nimport { fetchResources } from \"@/services/resource\"\nimport store from \"@/store\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { aiAgentActions } from \"../redux/aiAgent/dashboardTeamAIAgentSlice\"\nimport { flatTreeToMap } from \"../utils/componentNode/flatTree\"\nimport { fixedActionToNewAction } from \"./utils/fixedAction\"\nimport { fixedComponentsToNewComponents } from \"./utils/fixedComponents\"\n\nexport const updateCurrentAppInfo = (\n  data: CurrentAppResp,\n  mode: IllaMode,\n  appId: string,\n  teamID: string,\n  uid: string,\n) => {\n  store.dispatch(configActions.updateIllaMode(mode))\n  store.dispatch(appInfoActions.updateAppInfoReducer(data.appInfo))\n  const fixedComponents = fixedComponentsToNewComponents(data.components)\n  store.dispatch(\n    componentsActions.initComponentReducer(flatTreeToMap(fixedComponents)),\n  )\n  const fixedActions = fixedActionToNewAction(data.actions)\n  store.dispatch(actionActions.initActionListReducer(fixedActions))\n\n  DisplayNameGenerator.initApp(appId, teamID, uid)\n  DisplayNameGenerator.updateDisplayNameList(data.components, fixedActions)\n  store.dispatch(executionActions.startExecutionReducer())\n  if (mode === \"edit\" && fixedActions.length > 0) {\n    store.dispatch(configActions.changeSelectedAction(fixedActions[0]))\n  }\n}\n\nexport const useInitBuilderApp = (mode: IllaMode) => {\n  const { appId = \"\" } = useParams()\n  const dispatch = useDispatch()\n  const isOnline = useSelector(getIsOnline)\n  const teamInfo = useSelector(getCurrentTeamInfo)\n\n  const [loadingState, setLoadingState] = useState(true)\n  const [errorState, setErrorState] = useState(false)\n\n  // version = -1 represents the latest edited version of the app.\n  // version = -2 represents the latest released version of the user.\n  const version = mode === \"production\" ? \"-2\" : \"0\"\n\n  const { uid, teamID } = {\n    uid: teamInfo?.uid ?? \"\",\n    teamID: teamInfo?.id ?? \"\",\n  }\n\n  useDestroyApp()\n\n  const handleCurrentApp = useCallback(\n    (data: CurrentAppResp) => {\n      updateCurrentAppInfo(data, mode, appId, teamID, uid)\n    },\n    [mode, appId, teamID, uid],\n  )\n\n  useEffect(() => {\n    const controller = new AbortController()\n    if (isOnline) {\n      setErrorState(false)\n      setLoadingState(true)\n      if (isCloudVersion) {\n        Promise.all([\n          fetchPrivateAppInitData(appId, version, controller.signal),\n          fetchResources(controller.signal),\n          fetchTeamAgent(controller.signal),\n        ])\n          .then((res) => {\n            dispatch(resourceActions.updateResourceListReducer(res[1].data))\n            handleCurrentApp(res[0].data)\n            dispatch(\n              aiAgentActions.updateTeamAIAgentListReducer(\n                res[2].data.aiAgentList,\n              ),\n            )\n          })\n          .catch(() => {\n            setErrorState(true)\n          })\n          .finally(() => {\n            setLoadingState(false)\n          })\n      } else {\n        Promise.all([\n          fetchPrivateAppInitData(appId, version, controller.signal),\n          fetchResources(controller.signal),\n        ])\n          .then((res) => {\n            dispatch(resourceActions.updateResourceListReducer(res[1].data))\n            handleCurrentApp(res[0].data)\n          })\n          .catch(() => {\n            setErrorState(true)\n          })\n          .finally(() => {\n            setLoadingState(false)\n          })\n      }\n    }\n\n    return () => {\n      controller.abort()\n      dispatch(appInfoActions.updateAppInfoReducer(DashboardAppInitialState))\n    }\n  }, [appId, dispatch, handleCurrentApp, isOnline, teamID, version])\n\n  return { loadingState, errorState }\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/useInitGuideApp.tsx",
    "content": "import { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { useCallback, useEffect, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { initGuideApp } from \"@/config/guide\"\nimport { useDestroyApp } from \"@/hooks/useDestoryExecutionTree\"\nimport { updateCurrentAppInfo } from \"@/hooks/useInitApp\"\nimport { CurrentAppResp } from \"@/page/App/resp/currentAppResp\"\nimport { getIsOnline } from \"@/redux/config/configSelector\"\nimport { IllaMode } from \"@/redux/config/configState\"\nimport { appInfoActions } from \"@/redux/currentApp/appInfo/appInfoSlice\"\nimport { DashboardAppInitialState } from \"@/redux/currentApp/appInfo/appInfoState\"\nimport { guideActions } from \"@/redux/guide/guideSlice\"\nimport { GuideInitialState } from \"@/redux/guide/guideState\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { fetchResources } from \"@/services/resource\"\n\nexport const useInitGuideApp = (mode: IllaMode = \"template-edit\") => {\n  const { appId = \"\" } = useParams()\n  const dispatch = useDispatch()\n  const isOnline = useSelector(getIsOnline)\n  const teamInfo = useSelector(getCurrentTeamInfo)\n  const { teamIdentifier } = useParams()\n\n  const [loadingState, setLoadingState] = useState(true)\n  const [errorState, setErrorState] = useState(false)\n\n  const { uid, teamID } = {\n    uid: teamInfo?.uid ?? \"\",\n    teamID: teamInfo?.id ?? \"\",\n  }\n\n  useDestroyApp()\n\n  const handleCurrentApp = useCallback(\n    (data: CurrentAppResp) => {\n      updateCurrentAppInfo(data, mode, appId, teamID, uid)\n    },\n    [mode, appId, teamID, uid],\n  )\n\n  useEffect(() => {\n    const controller = new AbortController()\n    if (isOnline) {\n      new Promise<CurrentAppResp>(async (resolve) => {\n        setErrorState(false)\n        setLoadingState(true)\n        fetchResources(controller.signal).then((response) => {\n          dispatch(resourceActions.updateResourceListReducer(response.data))\n          initGuideApp()\n            .then((data) => {\n              handleCurrentApp(data)\n              resolve(data)\n            })\n            .finally(() => {\n              dispatch(guideActions.updateGuideStatusReducer(true))\n              setLoadingState(false)\n            })\n        })\n      })\n    }\n\n    return () => {\n      controller.abort()\n      dispatch(guideActions.updateGuideInfoReducer(GuideInitialState))\n      dispatch(appInfoActions.updateAppInfoReducer(DashboardAppInitialState))\n    }\n  }, [appId, dispatch, isOnline, teamIdentifier, handleCurrentApp])\n\n  return { loadingState, errorState }\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/useOAuthRefresh.tsx",
    "content": "import { useEffect } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { getOAuthRefreshData } from \"@/services/resource\"\n\nexport const useOAuthRefresh = (resourceID?: string) => {\n  const dispatch = useDispatch()\n  useEffect(() => {\n    if (resourceID == undefined) {\n      return\n    }\n    const controller = new AbortController()\n    getOAuthRefreshData(resourceID, controller.signal).then((response) => {\n      const resourceData = response.data\n      dispatch(resourceActions.updateResourceItemReducer(resourceData))\n    })\n    return () => {\n      controller.abort()\n    }\n  }, [dispatch, resourceID])\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/utils/fixComponentsUtils/chart.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\n\nexport const fixedChartComponent = (component: ComponentTreeNode) => {\n  return {\n    ...component,\n    type: \"CHART_WIDGET\",\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/utils/fixComponentsUtils/container.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\n\nexport const fixedContainerComponent = (component: ComponentTreeNode) => {\n  let linkedWidget\n  if (component.props) {\n    linkedWidget =\n      component.props.linkWidgetDisplayName !== undefined &&\n      typeof component.props.linkWidgetDisplayName === \"string\"\n        ? [component.props.linkWidgetDisplayName]\n        : component.props.linkWidgetDisplayName\n  }\n  return {\n    ...component,\n    props: {\n      ...component.props,\n      linkWidgetDisplayName: linkedWidget,\n    },\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/utils/fixComponentsUtils/dataGrid.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\n\nexport const fixedDataGridComponent = (component: ComponentTreeNode) => {\n  let fixedEnablePagination = true\n  if (component.props) {\n    fixedEnablePagination =\n      component.props.enablePagination !== undefined\n        ? component.props.enablePagination\n        : component.props.overflowMethod === \"PAGINATION\"\n  }\n  return {\n    ...component,\n    props: {\n      ...component.props,\n      enablePagination: fixedEnablePagination,\n    },\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/utils/fixComponentsUtils/image.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\n\nexport const fixedImageComponent = (component: ComponentTreeNode) => {\n  let fixedDynamicHeight = \"auto\"\n  if (component.props) {\n    fixedDynamicHeight =\n      component.props.dynamicHeight !== undefined\n        ? component.props.dynamicHeight\n        : fixedDynamicHeight\n  }\n  return {\n    ...component,\n    props: {\n      ...component.props,\n      dynamicHeight: fixedDynamicHeight,\n    },\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/utils/fixComponentsUtils/likeInput.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\n\nexport const fixedLikeInputComponentDefaultValue = (\n  component: ComponentTreeNode,\n) => {\n  return {\n    ...component,\n    props: {\n      ...component.props,\n      value: undefined,\n      defaultValue: component.props?.defaultValue || \"\",\n    },\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/utils/fixComponentsUtils/list.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\n\nexport const fixedListComponent = (component: ComponentTreeNode) => {\n  let fixedEnablePagination = true\n  if (component.props) {\n    fixedEnablePagination =\n      component.props.enablePagination !== undefined\n        ? component.props.enablePagination\n        : component.props.overflowMethod === \"PAGINATION\"\n  }\n  return {\n    ...component,\n    props: {\n      ...component.props,\n      enablePagination: fixedEnablePagination,\n      backgroundColor: \"#ffffffbf\",\n    },\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/utils/fixComponentsUtils/menu.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\n\nexport const fixedMenuComponent = (component: ComponentTreeNode) => {\n  if (component.version === 0 || component.version == undefined) {\n    return {\n      ...component,\n      version: 1,\n      props: {\n        ...component.props,\n        selectedValues:\n          component.props && Array.isArray(component.props?.selectedValues)\n            ? `{{${JSON.stringify(component.props.selectedValues)}}}`\n            : \"{{[]}}\",\n        optionConfigureMode:\n          component.props && component.props.optionConfigureMode === \"dynamic\"\n            ? \"dynamic\"\n            : \"static\",\n        colorScheme:\n          component.props && component.props.colorScheme\n            ? component.props.colorScheme\n            : \"blue\",\n        bgColor:\n          component.props && component.props.bgColor\n            ? component.props.bgColor\n            : \"transparent\",\n        hoverColorScheme:\n          component.props && component.props.hoverColorScheme\n            ? component.props.hoverColorScheme\n            : \"grayBlue\",\n      },\n    }\n  }\n  return component\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/utils/fixedAction.ts",
    "content": "import {\n  INIT_ACTION_ADVANCED_CONFIG,\n  INIT_ACTION_MOCK_CONFIG,\n} from \"@illa-public/public-configs\"\nimport { ACTION_RUN_TIME, ActionContent } from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { klona } from \"klona/json\"\n\nexport const fixedActionToNewAction = (\n  actions?: ActionItem<ActionContent>[],\n) => {\n  return (\n    actions?.map((action) => {\n      if (action.actionType === \"transformer\") {\n        return action\n      }\n      const advancedConfig = klona(INIT_ACTION_ADVANCED_CONFIG)\n      if (action.triggerMode === \"automate\") {\n        advancedConfig.runtime = ACTION_RUN_TIME.APP_LOADED\n      }\n      return {\n        ...action,\n        config: {\n          ...action.config,\n          public: !!action.config?.public,\n          advancedConfig: action.config?.advancedConfig ?? advancedConfig,\n          mockConfig: action.config?.mockConfig ?? INIT_ACTION_MOCK_CONFIG,\n        },\n      }\n    }) ?? []\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/hooks/utils/fixedComponents.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { fixedChartComponent } from \"./fixComponentsUtils/chart\"\nimport { fixedContainerComponent } from \"./fixComponentsUtils/container\"\nimport { fixedDataGridComponent } from \"./fixComponentsUtils/dataGrid\"\nimport { fixedImageComponent } from \"./fixComponentsUtils/image\"\nimport { fixedLikeInputComponentDefaultValue } from \"./fixComponentsUtils/likeInput\"\nimport { fixedListComponent } from \"./fixComponentsUtils/list\"\nimport { fixedMenuComponent } from \"./fixComponentsUtils/menu\"\n\nexport const fixedComponentsToNewComponents = (\n  componentsTree: ComponentTreeNode,\n) => {\n  const newComponentsTree = componentsTree ?? {}\n  if (Array.isArray(newComponentsTree.childrenNode)) {\n    newComponentsTree.childrenNode =\n      newComponentsTree.childrenNode?.map((component) => {\n        switch (component.type) {\n          case \"CHART\": {\n            return fixedChartComponent(component)\n          }\n          case \"MENU_WIDGET\": {\n            return fixedMenuComponent(component)\n          }\n          case \"LIST_WIDGET\":\n            return fixedListComponent(component)\n          case \"DATA_GRID_WIDGET\":\n            return fixedDataGridComponent(component)\n          case \"IMAGE_WIDGET\":\n            return fixedImageComponent(component)\n          case \"CONTAINER_WIDGET\":\n            return fixedContainerComponent(component)\n          case \"JSON_EDITOR_WIDGET\":\n          case \"SLIDER_WIDGET\":\n          case \"TEXTAREA_INPUT_WIDGET\":\n          case \"EDITABLE_TEXT_WIDGET\":\n          case \"NUMBER_INPUT_WIDGET\":\n          case \"INPUT_WIDGET\": {\n            return fixedLikeInputComponentDefaultValue(component)\n          }\n          default: {\n            return fixedComponentsToNewComponents(component)\n          }\n        }\n      }) || []\n  }\n\n  return newComponentsTree\n}\n"
  },
  {
    "path": "apps/builder/src/i18n/config.ts",
    "content": "import i18n from \"i18next\"\nimport LanguageDetector from \"i18next-browser-languagedetector\"\nimport { initReactI18next } from \"react-i18next\"\nimport csCZ from \"./locale/cs-CZ.json\"\nimport daDK from \"./locale/da-DK.json\"\nimport deDE from \"./locale/de-DE.json\"\nimport elGR from \"./locale/el-GR.json\"\nimport enUS from \"./locale/en-US.json\"\nimport esES from \"./locale/es-ES.json\"\nimport fiFI from \"./locale/fi-FI.json\"\nimport frFR from \"./locale/fr-FR.json\"\nimport itIT from \"./locale/it-IT.json\"\nimport jaJP from \"./locale/ja-JP.json\"\nimport koKR from \"./locale/ko-KR.json\"\nimport nlNL from \"./locale/nl-NL.json\"\nimport noNO from \"./locale/no-NO.json\"\nimport plPL from \"./locale/pl-PL.json\"\nimport ptPT from \"./locale/pt-PT.json\"\nimport roRO from \"./locale/ro-RO.json\"\nimport ruRU from \"./locale/ru-RU.json\"\nimport svSE from \"./locale/sv-SE.json\"\nimport ukUA from \"./locale/uk-UA.json\"\nimport zhCN from \"./locale/zh-CN.json\"\n\nexport const resources = {\n  \"en-US\": {\n    translation: enUS,\n  },\n  \"zh-CN\": {\n    translation: zhCN,\n  },\n  \"ja-JP\": {\n    translation: jaJP,\n  },\n  \"ko-KR\": {\n    translation: koKR,\n  },\n  \"cs-CZ\": {\n    translation: csCZ,\n  },\n  \"da-DK\": {\n    translation: daDK,\n  },\n  \"de-DE\": {\n    translation: deDE,\n  },\n  \"el-GR\": {\n    translation: elGR,\n  },\n  \"es-ES\": {\n    translation: esES,\n  },\n  \"fi-FI\": {\n    translation: fiFI,\n  },\n  \"fr-FR\": {\n    translation: frFR,\n  },\n  \"it-IT\": {\n    translation: itIT,\n  },\n  \"nl-NL\": {\n    translation: nlNL,\n  },\n  \"no-NO\": {\n    translation: noNO,\n  },\n  \"pl-PL\": {\n    translation: plPL,\n  },\n  \"pt-PT\": {\n    translation: ptPT,\n  },\n  \"ru-RU\": {\n    translation: ruRU,\n  },\n  \"ro-RO\": {\n    translation: roRO,\n  },\n  \"sv-SE\": {\n    translation: svSE,\n  },\n  \"uk-UA\": {\n    translation: ukUA,\n  },\n} as const\n\nexport const languageKeys = Object.keys(resources)\n\nexport const formatLanguage = (code: string) => {\n  if (code) {\n    if (languageKeys.includes(code)) {\n      return code\n    }\n    const mainLanguage = code.slice(0, 2)\n    for (let i = 0; i < languageKeys.length; i++) {\n      if (languageKeys[i].slice(0, 2) === mainLanguage) {\n        return languageKeys[i]\n      }\n    }\n  }\n  return \"en-US\"\n}\n\ni18n\n  .use(LanguageDetector)\n  .use(initReactI18next)\n  .init({\n    fallbackLng: (code) => {\n      const language = formatLanguage(code)\n      return [language, \"en-US\"]\n    },\n    debug: false,\n    interpolation: {\n      escapeValue: false, // not needed for react as it escapes by default\n    },\n    resources,\n    returnNull: false,\n    detection: {},\n  })\n\nexport const LANG_OPTIONS = Object.keys(resources).map((key) => {\n  return {\n    label: i18n.t(`language.${key}`),\n    value: key,\n  }\n})\n\nexport default i18n\n"
  },
  {
    "path": "apps/builder/src/i18n/i18next.d.ts",
    "content": "import \"i18next\"\n\ndeclare module \"i18next\" {\n  interface CustomTypeOptions {\n    // resources: typeof resources[\"en-US\"]\n    returnNull: false\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/i18n/react-i18next.d.ts",
    "content": "import \"react-i18next\"\nimport { resources } from \"./config\"\n\ndeclare module \"react-i18next\" {\n  interface CustomTypeOptions {\n    resources: (typeof resources)[\"en-US\"]\n    returnNull: false\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/main.tsx",
    "content": "import { ILLAMixpanel } from \"@illa-public/mixpanel-utils\"\nimport { initDateReport, initDayjs } from \"@illa-public/utils\"\nimport { LicenseInfo } from \"@mui/x-data-grid-premium\"\nimport * as Sentry from \"@sentry/react\"\nimport { StrictMode } from \"react\"\nimport { createRoot } from \"react-dom/client\"\nimport { Provider } from \"react-redux\"\nimport \"@/api/http/base\"\nimport \"@/i18n/config\"\nimport App from \"./App\"\nimport store from \"./store\"\n\nif (\n  import.meta.env.ILLA_APP_ENV &&\n  import.meta.env.ILLA_APP_ENV !== \"development\" &&\n  import.meta.env.ILLA_INSTANCE_ID === \"CLOUD\" &&\n  import.meta.env.ILLA_SENTRY_SERVER_API\n) {\n  Sentry.init({\n    dsn: import.meta.env.ILLA_SENTRY_SERVER_API,\n    integrations: [\n      new Sentry.BrowserTracing({\n        // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled\n        tracePropagationTargets: [\"localhost\"],\n      }),\n      new Sentry.Replay({\n        maskAllText: false,\n        blockAllMedia: false,\n      }),\n    ],\n    environment: import.meta.env.ILLA_APP_ENV,\n    tracesSampleRate: 1.0,\n    release: `illa-builder@${import.meta.env.ILLA_APP_VERSION}`,\n  })\n}\n\nif (import.meta.env.ILLA_MUI_LICENSE) {\n  LicenseInfo.setLicenseKey(import.meta.env.ILLA_MUI_LICENSE)\n}\n\ninitDateReport()\nILLAMixpanel.setDeviceID()\ninitDayjs()\n\nconst root = createRoot(document.getElementById(\"root\")!!)\n\nroot.render(\n  <StrictMode>\n    <Provider store={store}>\n      <App />\n    </Provider>\n  </StrictMode>,\n)\n"
  },
  {
    "path": "apps/builder/src/middleware/guideAsync/guideUpdate/index.ts",
    "content": "import { Dispatch, PayloadAction } from \"@reduxjs/toolkit\"\nimport { get, isObject } from \"lodash-es\"\nimport {\n  GUIDE_SELECT_WIDGET,\n  GUIDE_SQL_QUERY,\n  GUIDE_STEP,\n} from \"@/config/guide/config\"\nimport { getCurrentStep } from \"@/redux/guide/guideSelector\"\nimport { guideActions } from \"@/redux/guide/guideSlice\"\nimport { RootState } from \"@/store\"\n\nexport const guideUpdate = (\n  rootState: RootState,\n  dispatch: Dispatch,\n  action: PayloadAction<any>,\n) => {\n  const { type, payload } = action\n  const currentStep = getCurrentStep(rootState)\n\n  const handleNext = (goNext: boolean) => {\n    if (goNext) {\n      dispatch(guideActions.updateCurrentStepReducer(currentStep + 1))\n    }\n  }\n\n  switch (currentStep) {\n    case 0:\n    case 1:\n    case 2: {\n      if (type === \"components/addComponentReducer\") {\n        // exclude the case of doItForMe\n        if (payload.length === 1) {\n          const addedWidget = payload[0].type\n          const isCurrentStepWidget =\n            GUIDE_SELECT_WIDGET[currentStep] === addedWidget\n          handleNext(isCurrentStepWidget)\n        }\n      }\n      break\n    }\n    case 3: {\n      if (type === \"config/updateCachedAction\") {\n        const query = payload?.content?.query\n        handleNext(query === GUIDE_SQL_QUERY)\n      }\n      break\n    }\n    case 4: {\n      if (type === \"execution/updateExecutionByDisplayNameReducer\") {\n        const query = payload.displayName\n        handleNext(query === \"postgresql1\")\n      }\n      break\n    }\n    case 5:\n    case 7: {\n      const { reduxAction, displayName } = GUIDE_STEP[currentStep]\n      if (reduxAction === type) {\n        const selectedWidget = (payload as string[])[0]\n        const isCurrentStepWidget = selectedWidget === displayName\n        handleNext(isCurrentStepWidget)\n      }\n      break\n    }\n    case 6: {\n      if (type === \"components/updateComponentPropsReducer\") {\n        const dataSourceJS = get(payload, \"updateSlice.dataSourceJS\")\n        handleNext(dataSourceJS === \"{{postgresql1.data}}\")\n      }\n      break\n    }\n    case 8: {\n      if (type === \"components/updateComponentPropsReducer\") {\n        const displayName = payload.displayName\n        const events = payload?.updateSlice?.events\n        if (Array.isArray(events) && displayName === \"button1\") {\n          const newEvent = events[events.length - 1]\n          handleNext(\n            newEvent?.targetId === \"query1\" && newEvent?.type === \"datasource\",\n          )\n        }\n      }\n      break\n    }\n    case 9: {\n      if (type === \"components/updateComponentPropsReducer\") {\n        const displayName = payload.displayName\n        const updateSlice = payload.updateSlice\n        if (isObject(updateSlice) && displayName === \"button1\") {\n          const actionType = Object.values(updateSlice).reduce(\n            (result, value) => {\n              if (value?.actionType) {\n                return value.actionType === \"datasource\"\n              }\n              return undefined\n            },\n          )\n          handleNext(actionType)\n        }\n      }\n      break\n    }\n    case 10: {\n      if (type === \"components/updateComponentPropsReducer\") {\n        const displayName = payload.displayName\n        const updateSlice = payload.updateSlice\n        if (isObject(updateSlice) && displayName === \"button1\") {\n          const queryID = Object.values(updateSlice).reduce((result, value) => {\n            if (value?.actionType) {\n              return value.queryID === \"postgresql1\"\n            }\n            return undefined\n          })\n          handleNext(queryID)\n        }\n      }\n      break\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/guideAsync/index.ts",
    "content": "import { Middleware, isAction } from \"@reduxjs/toolkit\"\nimport { guideUpdate } from \"@/middleware/guideAsync/guideUpdate\"\nimport { getGuideStatus } from \"@/redux/guide/guideSelector\"\n\nexport const guideAsync: Middleware = (store) => (next) => (action) => {\n  if (!isAction(action) || !(\"payload\" in action)) {\n    return next(action)\n  }\n  const isGuideOpen = getGuideStatus(store.getState())\n  if (isGuideOpen) {\n    guideUpdate(store.getState(), store.dispatch, action)\n  }\n  return next(action)\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/mixpanelReport/index.ts",
    "content": "import { Middleware, isAction } from \"@reduxjs/toolkit\"\nimport { reportMessage } from \"./reportMessage\"\n\nexport const mixpanelReport: Middleware = (store) => (next) => (action) => {\n  if (!isAction(action) || !(\"payload\" in action)) {\n    return next(action)\n  }\n  const { type } = action\n  const typeList = type.split(\"/\")\n  const isRemoteAction = typeList[typeList.length - 1] === \"remote\"\n  const prevRootState = store.getState()\n  const resp = next(action)\n  if (!isRemoteAction) {\n    reportMessage(prevRootState, store.getState(), action)\n  }\n\n  return resp\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/mixpanelReport/reportMessage/component.ts",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { PayloadAction } from \"@reduxjs/toolkit\"\nimport { searchDSLByDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport { RootState } from \"@/store\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\n\nexport const componentsOperationReport = (\n  reduxAction: string,\n  currentAppID: string,\n  action: PayloadAction<any>,\n  teamID: string,\n  uid: string,\n  prevRootState: RootState,\n  _nextRootState: RootState,\n) => {\n  switch (reduxAction) {\n    case \"addComponentReducer\": {\n      const payload = action.payload as ComponentTreeNode[]\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.ADD, {\n        element: \"component\",\n        parameter1: payload.map((node) => node.type),\n      })\n      break\n    }\n    case \"deleteComponentNodeReducer\": {\n      const payload = action.payload.displayNames as string[]\n      const source = action.payload.source\n      const nodes = payload\n        .map((displayName) =>\n          searchDSLByDisplayName(displayName, prevRootState),\n        )\n        .filter((node) => node)\n      const types = nodes.map((node) => node.type)\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.DELETE, {\n        element: \"component\",\n        parameter1: types,\n        parameter3: source,\n      })\n      break\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/mixpanelReport/reportMessage/index.ts",
    "content": "import { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { PayloadAction } from \"@reduxjs/toolkit\"\nimport store, { RootState } from \"@/store\"\nimport { componentsOperationReport } from \"./component\"\n\nexport const reportMessage = (\n  prevRootState: RootState,\n  nextRootState: RootState,\n  action: PayloadAction<any>,\n) => {\n  const currentAppID = nextRootState.currentApp.appInfo.appId ?? \"\"\n  const { id: teamID = \"\", id = \"\" } =\n    getCurrentTeamInfo(store.getState()) ?? {}\n  const { type } = action\n  const typeList = type.split(\"/\")\n  const reduxType = typeList[0]\n  const reduxAction = typeList[1]\n  switch (reduxType) {\n    case \"components\": {\n      componentsOperationReport(\n        reduxAction,\n        currentAppID,\n        action,\n        teamID,\n        id,\n        prevRootState,\n        nextRootState,\n      )\n      break\n    }\n\n    default:\n      break\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/reduxAsync/index.ts",
    "content": "import { Middleware, isAction } from \"@reduxjs/toolkit\"\nimport { illaSnapshot } from \"@/page/App/components/DotPanel/constant/snapshotNew\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { RootState } from \"@/store\"\nimport { receiveMessage } from \"./receiveMessages\"\nimport { sendMessage } from \"./sendMessage\"\n\nexport const reduxAsync: Middleware = (store) => (next) => (action) => {\n  if (!isAction(action) || !(\"payload\" in action)) {\n    return next(action)\n  }\n  const { type } = action\n  const typeList = type.split(\"/\")\n  const isRemoteAction = typeList[typeList.length - 1] === \"remote\"\n  const currentAppID = store.getState().currentApp.appInfo.appId ?? \"\"\n  if (isRemoteAction) {\n    receiveMessage(action, currentAppID)\n    const resp = next(action) as RootState\n    if (typeList[0] === \"components\") {\n      const nextRootState = store.getState()\n      const snapShot = getClientWidgetLayoutInfo(nextRootState)\n      illaSnapshot.setSnapshot(snapShot)\n    }\n    return resp\n  }\n  const prevRootState = store.getState()\n  const resp = next(action)\n  try {\n    sendMessage(prevRootState, store.getState(), action)\n  } catch (e) {\n    console.log(e)\n  }\n  return resp\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/reduxAsync/receiveMessages/index.ts",
    "content": "import { UnknownAction } from \"@reduxjs/toolkit\"\nimport { REDUX_ACTION_FROM } from \"@/middleware/undoRedo/interface\"\n\nexport const receiveMessage = (action: UnknownAction, currentAppID: string) => {\n  const { type, payload } = action\n  const typeList = type.split(\"/\")\n  const reduxType = typeList[0]\n  const reduxAction = typeList[1]\n  const newType = `${reduxType}/${reduxAction}`\n  action.type = newType\n  action.from = REDUX_ACTION_FROM.WS\n\n  switch (newType) {\n    case \"enter/remote\": {\n      if (currentAppID !== \"\") {\n        action.type = \"collaborators/setInRoomUsers\"\n      }\n      break\n    }\n    case \"attachComponent/remote\": {\n      if (currentAppID !== \"\") {\n        if (\n          typeof payload === \"object\" &&\n          payload !== null &&\n          \"componentAttachedUsers\" in payload\n        ) {\n          action.type = \"collaborators/updateComponentAttachedUsers\"\n          action.payload = payload.componentAttachedUsers\n        }\n      }\n      break\n    }\n    default: {\n      break\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/reduxAsync/sendMessage/actionMethod.ts",
    "content": "import { PayloadAction } from \"@reduxjs/toolkit\"\nimport { Connection, getTextMessagePayload } from \"@/api/ws\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\nimport { RootState } from \"@/store\"\n\nexport const actionsAsync = (\n  reduxAction: string,\n  currentAppID: string,\n  action: PayloadAction<any>,\n  teamID: string,\n  uid: string,\n  _prevRootState: RootState,\n  _nextRootState: RootState,\n) => {\n  const { payload } = action\n  switch (reduxAction) {\n    case \"addActionItemReducer\": {\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.BROADCAST_ONLY,\n          TextTarget.ACTION,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    }\n    case \"batchAddActionItemReducer\": {\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.BROADCAST_ONLY,\n          TextTarget.ACTION,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    }\n    case \"removeActionItemReducer\": {\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.BROADCAST_ONLY,\n          TextTarget.ACTION,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    }\n    case \"updateActionItemReducer\": {\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.BROADCAST_ONLY,\n          TextTarget.ACTION,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    }\n    case \"updateActionDisplayNameReducer\": {\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.BROADCAST_ONLY,\n          TextTarget.ACTION,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    }\n    case \"batchUpdateMultiActionSlicePropsReducer\": {\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.BROADCAST_ONLY,\n          TextTarget.ACTION,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    }\n    case \"batchUpdateResourceID\": {\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.BROADCAST_ONLY,\n          TextTarget.ACTION,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    }\n    case \"batchUpdateActionItemReducer\": {\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.BROADCAST_ONLY,\n          TextTarget.ACTION,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/reduxAsync/sendMessage/agentMethod.ts",
    "content": "import { PayloadAction } from \"@reduxjs/toolkit\"\nimport { Connection, getTextMessagePayload } from \"@/api/ws\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\nimport { RootState } from \"@/store\"\n\nexport const agentAsync = (\n  reduxAction: string,\n  currentAppID: string,\n  action: PayloadAction<any>,\n  teamID: string,\n  uid: string,\n  _prevRootState: RootState,\n  _nextRootState: RootState,\n) => {\n  const { payload } = action\n  switch (reduxAction) {\n    case \"addTeamAIAgentReducer\":\n    case \"removeTeamAIAgentReducer\":\n    case \"modifyTeamAIAgentReducer\":\n      Connection.getTextRoom(\"dashboard\", \"\")?.send(\n        getTextMessagePayload(\n          TextSignal.BROADCAST_ONLY,\n          TextTarget.RESOURCE,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    default:\n      break\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/reduxAsync/sendMessage/appInfoMethod.ts",
    "content": "import { PayloadAction } from \"@reduxjs/toolkit\"\nimport { Connection, getTextMessagePayload } from \"@/api/ws\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\nimport { RootState } from \"@/store\"\n\nexport const appInfoAsync = (\n  reduxAction: string,\n  currentAppID: string,\n  action: PayloadAction<any>,\n  teamID: string,\n  uid: string,\n  _prevRootState: RootState,\n  _nextRootState: RootState,\n) => {\n  const { payload } = action\n  switch (reduxAction) {\n    case \"updateAppContributeReducer\":\n    case \"updateAppPublicReducer\":\n    case \"updateAppDeployedReducer\":\n    case \"updateAppInfoReducer\": {\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.APPS,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/reduxAsync/sendMessage/appsMethod.ts",
    "content": "import { PayloadAction } from \"@reduxjs/toolkit\"\nimport { Connection, getTextMessagePayload } from \"@/api/ws\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\nimport { RootState } from \"@/store\"\n\nexport const appsAsync = (\n  reduxAction: string,\n  currentAppID: string,\n  action: PayloadAction<any>,\n  teamID: string,\n  uid: string,\n  _prevRootState: RootState,\n  _nextRootState: RootState,\n) => {\n  const { payload } = action\n  switch (reduxAction) {\n    case \"addDashboardAppReducer\":\n      Connection.getTextRoom(\"dashboard\", \"\")?.send(\n        getTextMessagePayload(\n          TextSignal.CREATE_STATE,\n          TextTarget.APPS,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    case \"removeDashboardAppReducer\":\n      Connection.getTextRoom(\"dashboard\", \"\")?.send(\n        getTextMessagePayload(\n          TextSignal.DELETE_STATE,\n          TextTarget.APPS,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    case \"updateDashboardAppPublicReducer\":\n    case \"updateDashboardAppContributeReducer\":\n    case \"updateDashboardAppDeployedReducer\":\n    case \"updateDashboardAppReducer\":\n      Connection.getTextRoom(\"dashboard\", \"\")?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.APPS,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload],\n        ),\n      )\n      break\n    default:\n      break\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/reduxAsync/sendMessage/componentsMethod.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { PayloadAction } from \"@reduxjs/toolkit\"\nimport {\n  Connection,\n  getTextMessagePayload,\n  transformComponentReduxPayloadToWsPayload,\n} from \"@/api/ws\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\nimport {\n  UpdateComponentNodeLayoutInfoPayload,\n  UpdateComponentPositionPayload,\n  UpdateComponentSlicePropsPayload,\n} from \"@/redux/currentApp/components/componentsPayload\"\nimport { getNeedDeleteSectionViewDisplayNames } from \"@/redux/currentApp/components/componentsReducer\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n  searchDSLFromTree,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport {\n  AddModalComponentPayload,\n  AddSectionViewPayload,\n  AddTargetPageSectionPayload,\n  DeleteComponentNodePayload,\n  DeletePageNodePayload,\n  DeleteSectionViewPayload,\n  DeleteSubPageViewNodePayload,\n  DeleteTargetPageSectionPayload,\n  SortComponentNodeChildrenPayload,\n  UpdateComponentDisplayNamePayload,\n  UpdateComponentNodeHeightPayload,\n  UpdateComponentPropsPayload,\n  UpdateComponentReflowPayload,\n  UpdateCurrentPageStylePayload,\n  UpdateSectionViewPropsPayload,\n  UpdateTargetPageLayoutPayload,\n  UpdateTargetPagePropsPayload,\n} from \"@/redux/currentApp/components/componentsState\"\nimport { RootState } from \"@/store\"\nimport { buildTreeByMapNode } from \"@/utils/componentNode/flatTree\"\n\nexport const componentsAsync = (\n  reduxAction: string,\n  currentAppID: string,\n  action: PayloadAction<any>,\n  teamID: string,\n  uid: string,\n  prevRootState: RootState,\n  nextRootState: RootState,\n) => {\n  const { payload } = action\n  const prevComponents = getComponentMap(prevRootState)\n  const nextComponents = getComponentMap(nextRootState)\n  switch (reduxAction) {\n    case \"addComponentReducer\": {\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.CREATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          payload,\n        ),\n      )\n      break\n    }\n    case \"addModalComponentReducer\": {\n      const payload = action.payload as AddModalComponentPayload\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n\n      const parentNode = searchDSLFromTree(\n        nextComponentTree,\n        payload.modalComponentNode.parentNode!,\n      )\n      if (!parentNode) return\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.CREATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [payload.modalComponentNode],\n        ),\n      )\n      break\n    }\n    case \"updateComponentReflowReducer\": {\n      const updateComponentReflowPayload: UpdateComponentReflowPayload[] =\n        payload\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n\n      const allEffectComponentDisplayName: string[] =\n        updateComponentReflowPayload\n          .flatMap((payload) => {\n            return payload.childNodes\n          })\n          .map((node) => node.displayName)\n      const allEffectComponentNode = allEffectComponentDisplayName\n        .map((displayName) => searchDSLFromTree(nextComponentTree, displayName))\n        .filter((node) => node !== null) as ComponentTreeNode[]\n      const updateComponentReflowWSPayload =\n        transformComponentReduxPayloadToWsPayload(allEffectComponentNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateComponentReflowWSPayload,\n        ),\n      )\n      break\n    }\n    case \"sortComponentNodeChildrenReducer\": {\n      const sortComponentNodeChildrenPayload: SortComponentNodeChildrenPayload =\n        payload\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const parentNode = searchDSLFromTree(\n        nextComponentTree,\n        sortComponentNodeChildrenPayload.parentDisplayName,\n      )\n      if (!parentNode) return\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.DELETE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [parentNode.displayName!],\n        ),\n      )\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.CREATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [parentNode],\n        ),\n      )\n      break\n    }\n    case \"updateComponentPositionReducer\": {\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const updateComponentContainerPayload: UpdateComponentPositionPayload =\n        payload\n      const {\n        updateSlices,\n        oldParentNodeDisplayName,\n        newParentNodeDisplayName,\n      } = updateComponentContainerPayload\n      const allDisplayNames = updateSlices.map((slice) => slice.displayName)\n      const allNodes = allDisplayNames\n        .map(\n          (displayName) =>\n            searchDSLFromTree(\n              nextComponentTree,\n              displayName,\n            ) as ComponentTreeNode,\n        )\n        .filter((node) => node !== null) as ComponentTreeNode[]\n      if (oldParentNodeDisplayName !== newParentNodeDisplayName) {\n        Connection.getTextRoom(\"app\", currentAppID)?.send(\n          getTextMessagePayload(\n            TextSignal.MOVE_STATE,\n            TextTarget.COMPONENTS,\n            false,\n            null,\n            teamID,\n            uid,\n            allNodes.map((node) => {\n              return {\n                displayName: node.displayName,\n                parentNode: node.parentNode,\n                childrenNode: node.childrenNode,\n              }\n            }),\n          ),\n        )\n      }\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          transformComponentReduxPayloadToWsPayload(allNodes),\n        ),\n      )\n\n      break\n    }\n    case \"setComponentPropsReducer\":\n    case \"updateComponentPropsReducer\": {\n      const updatePayload: UpdateComponentPropsPayload = payload\n      const finalNode = searchComponentFromMap(\n        nextComponents,\n        updatePayload.displayName,\n      )\n      if (finalNode != null) {\n        Connection.getTextRoom(\"app\", currentAppID)?.send(\n          getTextMessagePayload(\n            TextSignal.UPDATE_STATE,\n            TextTarget.COMPONENTS,\n            true,\n            action,\n            teamID,\n            uid,\n            [\n              {\n                before: {\n                  displayName: updatePayload.displayName,\n                },\n                after: finalNode,\n              },\n            ],\n          ),\n        )\n      }\n      break\n    }\n    case \"batchUpdateMultiComponentSlicePropsReducer\": {\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const batchUpdatePayload: UpdateComponentSlicePropsPayload[] = payload\n      const allDisplayNames = batchUpdatePayload.map(\n        ({ displayName }) => displayName,\n      )\n      const allNodes = allDisplayNames\n        .map((displayName) => {\n          return searchDSLFromTree(nextComponentTree, displayName)\n        })\n        .filter((node) => node != null) as ComponentTreeNode[]\n      const wsPayload = transformComponentReduxPayloadToWsPayload(allNodes)\n\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          wsPayload,\n        ),\n      )\n      break\n    }\n    case \"updateMultiComponentPropsReducer\": {\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const updateMultiPayload: UpdateComponentPropsPayload[] = payload\n      const finalNodes = updateMultiPayload\n        .map(({ displayName }) => {\n          return searchDSLFromTree(nextComponentTree, displayName)\n        })\n        .filter((node) => node !== null) as ComponentTreeNode[]\n      if (Array.isArray(finalNodes)) {\n        const wsPayload = transformComponentReduxPayloadToWsPayload(finalNodes)\n        Connection.getTextRoom(\"app\", currentAppID)?.send(\n          getTextMessagePayload(\n            TextSignal.UPDATE_STATE,\n            TextTarget.COMPONENTS,\n            true,\n            action,\n            teamID,\n            uid,\n            wsPayload,\n          ),\n        )\n      }\n      break\n    }\n    case \"deleteComponentNodeReducer\": {\n      const deletePayload: DeleteComponentNodePayload = payload\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.DELETE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          deletePayload.displayNames,\n        ),\n      )\n      break\n    }\n    case \"updateComponentDisplayNameReducer\": {\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n\n      const { displayName, newDisplayName } =\n        action.payload as UpdateComponentDisplayNamePayload\n      const findOldNode = searchDSLFromTree(nextComponentTree, newDisplayName)\n      if (!findOldNode) break\n      const parentNode = searchDSLFromTree(\n        nextComponentTree,\n        findOldNode.parentNode!,\n      )\n      if (!parentNode) break\n      const WSPayload = transformComponentReduxPayloadToWsPayload([\n        parentNode,\n        ...(findOldNode.childrenNode || []),\n      ])\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [\n            {\n              before: {\n                displayName: displayName,\n              },\n              after: {\n                ...findOldNode,\n                displayName: newDisplayName,\n              },\n            },\n            ...WSPayload,\n          ],\n        ),\n      )\n      break\n    }\n    case \"updateTargetPageLayoutReducer\": {\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const { pageName } = action.payload as UpdateTargetPageLayoutPayload\n      const pageNode = searchDSLFromTree(nextComponentTree, pageName)\n      if (!pageNode) break\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.DELETE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          null,\n          teamID,\n          uid,\n          [pageName],\n        ),\n      )\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.CREATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [pageNode],\n        ),\n      )\n      break\n    }\n    case \"deleteTargetPageSectionReducer\": {\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const { pageName, deleteSectionName } =\n        action.payload as DeleteTargetPageSectionPayload\n      const prevComponentTree = buildTreeByMapNode(\"root\", prevComponents)\n      const originFinalNode = searchDSLFromTree(prevComponentTree, pageName)\n      const finalNode = searchDSLFromTree(nextComponentTree, pageName)\n\n      if (!finalNode || !originFinalNode) break\n      const WSPayload = transformComponentReduxPayloadToWsPayload(finalNode)\n      const targetPageChildrenNode = originFinalNode.childrenNode.find(\n        (node) => node.showName === deleteSectionName,\n      )\n      if (!targetPageChildrenNode) return\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.DELETE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [targetPageChildrenNode.displayName],\n        ),\n      )\n\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          null,\n          teamID,\n          uid,\n          WSPayload,\n        ),\n      )\n      break\n    }\n    case \"addTargetPageSectionReducer\": {\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const { pageName, addedSectionName } =\n        action.payload as AddTargetPageSectionPayload\n      const pageNode = searchDSLFromTree(nextComponentTree, pageName)\n      if (!pageNode) break\n      const addSectionNode = pageNode.childrenNode.find(\n        (node) => node.showName === addedSectionName,\n      )\n      if (!addSectionNode) break\n\n      const WSPagePayload = transformComponentReduxPayloadToWsPayload(pageNode)\n\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          null,\n          teamID,\n          uid,\n          WSPagePayload,\n        ),\n      )\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.CREATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [addSectionNode],\n        ),\n      )\n      break\n    }\n    case \"updateTargetPagePropsReducer\": {\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const { pageName } = action.payload as UpdateTargetPagePropsPayload\n      const pageNode = searchDSLFromTree(nextComponentTree, pageName)\n\n      if (!pageNode) break\n      const WSPagePayload = transformComponentReduxPayloadToWsPayload(pageNode)\n\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          WSPagePayload,\n        ),\n      )\n      break\n    }\n    case \"updateViewportSizeReducer\":\n    case \"updateRootNodePropsReducer\": {\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const WSPagePayload =\n        transformComponentReduxPayloadToWsPayload(nextComponentTree)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          WSPagePayload,\n        ),\n      )\n      break\n    }\n    case \"addPageNodeWithSortOrderReducer\": {\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n      const node = action.payload as ComponentTreeNode\n      if (!rootNode || !node) break\n      const rootNodeUpdateWSPayload =\n        transformComponentReduxPayloadToWsPayload(rootNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          null,\n          teamID,\n          uid,\n          rootNodeUpdateWSPayload,\n        ),\n      )\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.CREATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [node],\n        ),\n      )\n      break\n    }\n    case \"deletePageNodeReducer\": {\n      const deletePayload = payload as DeletePageNodePayload\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n      if (!rootNode) break\n      const rootNodeUpdateWSPayload =\n        transformComponentReduxPayloadToWsPayload(rootNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          null,\n          teamID,\n          uid,\n          rootNodeUpdateWSPayload,\n        ),\n      )\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.DELETE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [deletePayload.displayName],\n        ),\n      )\n      break\n    }\n    case \"addSectionViewConfigByConfigReducer\":\n    case \"addSectionViewReducer\": {\n      const { parentNodeName } = payload as AddSectionViewPayload\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n\n      if (!rootNode) break\n      const targetNode = searchDSLFromTree(rootNode, parentNodeName)\n      if (!targetNode) break\n      const { props } = targetNode\n      const { viewSortedKey } = props as Record<string, any>\n      const lastSortedKey = viewSortedKey.at(-1)\n      if (!lastSortedKey) return\n      const sectionNode = targetNode.childrenNode.find((item) => {\n        return item.displayName === lastSortedKey\n      })\n      if (!sectionNode) return\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(targetNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          null,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.CREATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [sectionNode],\n        ),\n      )\n      break\n    }\n    case \"deleteSectionViewReducer\": {\n      const { viewDisplayName, parentNodeName } =\n        payload as DeleteSectionViewPayload\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n      if (!rootNode) break\n      const targetNode = searchDSLFromTree(rootNode, parentNodeName)\n      if (!targetNode) break\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(targetNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.DELETE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          null,\n          teamID,\n          uid,\n          [viewDisplayName],\n        ),\n      )\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      break\n    }\n    case \"updateSectionViewPropsReducer\": {\n      const { parentNodeName } = payload as UpdateSectionViewPropsPayload\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n      if (!rootNode) break\n      const targetNode = searchDSLFromTree(rootNode, parentNodeName)\n      if (!targetNode) break\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(targetNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      break\n    }\n    case \"updateComponentNodeHeightReducer\": {\n      const { displayName } = payload as UpdateComponentNodeHeightPayload\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n      if (!rootNode) break\n      const targetNode = searchDSLFromTree(rootNode, displayName)\n      if (!targetNode) break\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(targetNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      break\n    }\n    case \"batchUpdateComponentLayoutInfoReducer\": {\n      const displayNames = (\n        payload as UpdateComponentNodeLayoutInfoPayload[]\n      ).map((item) => item.displayName)\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n      if (!rootNode) break\n      const targetNodes = displayNames\n        .map((displayName) => searchDSLFromTree(rootNode, displayName))\n        .filter((node) => node !== null) as ComponentTreeNode[]\n      if (targetNodes.length < 1) break\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(targetNodes)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      break\n    }\n    case \"batchUpdateComponentLayoutInfoWhenReflowReducer\": {\n      const displayNames = (\n        payload as UpdateComponentNodeLayoutInfoPayload[]\n      ).map((item) => item.displayName)\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n      if (!rootNode) break\n      const targetNodes = displayNames\n        .map((displayName) => searchDSLFromTree(rootNode, displayName))\n        .filter((node) => node !== null) as ComponentTreeNode[]\n      if (targetNodes.length < 1) break\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(targetNodes)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          false,\n          null,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      break\n    }\n    case \"updateComponentLayoutInfoReducer\": {\n      const displayName = (payload as UpdateComponentNodeLayoutInfoPayload)\n        .displayName\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n      if (!rootNode) break\n      const targetNode = searchDSLFromTree(rootNode, displayName)\n      if (!targetNode) break\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(targetNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      break\n    }\n    case \"setGlobalStateReducer\": {\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n      if (!rootNode) break\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(rootNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      break\n    }\n    case \"deleteGlobalStateByKeyReducer\": {\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n      if (!rootNode) break\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(rootNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      break\n    }\n    case \"deleteSubPageViewNodeReducer\": {\n      const prevComponentTree = buildTreeByMapNode(\"root\", prevComponents)\n      const rootNode = prevComponentTree\n      const nextRootNode = buildTreeByMapNode(\"root\", nextComponents)\n      if (!rootNode) break\n      const { pageName, subPagePath } = payload as DeleteSubPageViewNodePayload\n      const deleteDisplayNames = getNeedDeleteSectionViewDisplayNames(\n        prevComponents,\n        pageName,\n        subPagePath,\n      )\n      const needUpdateParentNode = deleteDisplayNames\n        .map((displayName) => {\n          const currentNode = searchDSLFromTree(rootNode, displayName)\n          if (!currentNode) return null\n          return searchDSLFromTree(nextRootNode, currentNode.parentNode!)\n        })\n        .filter((node) => node !== null) as ComponentTreeNode[]\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(needUpdateParentNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.DELETE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          deleteDisplayNames,\n        ),\n      )\n\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          null,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      break\n    }\n    case \"updateSubPagePathReducer\":\n    case \"updateDefaultSubPagePathReducer\": {\n      const { pageName } = payload as DeleteSubPageViewNodePayload\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const pageNode = searchDSLFromTree(nextComponentTree, pageName)\n      if (!pageNode) return\n      const needUpdateNodes = pageNode.childrenNode?.filter((node) => {\n        return node.type !== \"MODAL_SECTION_NODE\"\n      })\n      if (!Array.isArray(needUpdateNodes)) return\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(needUpdateNodes)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      break\n    }\n    case \"addSubPageReducer\": {\n      const { pageName } = payload as { pageName: string }\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n\n      const pageNode = searchDSLFromTree(nextComponentTree, pageName)\n      if (!pageNode) break\n      const bodySection = pageNode.childrenNode.find(\n        (node) => node.showName === \"bodySection\",\n      )\n      if (!bodySection) break\n      const sectionChildrenNode = bodySection.childrenNode\n      if (!Array.isArray(sectionChildrenNode)) break\n      const addedSectionViewNode =\n        sectionChildrenNode[sectionChildrenNode.length - 1]\n\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(bodySection)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          null,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.CREATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          [addedSectionViewNode],\n        ),\n      )\n    }\n\n    case \"updateCurrentPageStyleReducer\": {\n      const { pageName, sectionName } = payload as UpdateCurrentPageStylePayload\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const pageNode = searchDSLFromTree(nextComponentTree, pageName)\n      if (!pageNode) break\n      const sectionNode = pageNode.childrenNode.find(\n        (node) => node.showName === sectionName,\n      )\n      if (!sectionNode) return\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(sectionNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n    }\n\n    case \"deleteCurrentPageStyleReducer\": {\n      const { pageName, sectionName } = payload as UpdateCurrentPageStylePayload\n      const nextComponentTree = buildTreeByMapNode(\"root\", nextComponents)\n      const pageNode = searchDSLFromTree(nextComponentTree, pageName)\n      if (!pageNode) break\n      const sectionNode = pageNode.childrenNode.find(\n        (node) => node.showName === sectionName,\n      )\n      if (!sectionNode) return\n      const updateWSPayload =\n        transformComponentReduxPayloadToWsPayload(sectionNode)\n      Connection.getTextRoom(\"app\", currentAppID)?.send(\n        getTextMessagePayload(\n          TextSignal.UPDATE_STATE,\n          TextTarget.COMPONENTS,\n          true,\n          action,\n          teamID,\n          uid,\n          updateWSPayload,\n        ),\n      )\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/reduxAsync/sendMessage/index.ts",
    "content": "import { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { PayloadAction } from \"@reduxjs/toolkit\"\nimport { agentAsync } from \"@/middleware/reduxAsync/sendMessage/agentMethod\"\nimport store, { RootState } from \"@/store\"\nimport { actionsAsync } from \"./actionMethod\"\nimport { appInfoAsync } from \"./appInfoMethod\"\nimport { appsAsync } from \"./appsMethod\"\nimport { componentsAsync } from \"./componentsMethod\"\nimport { resourcesAsync } from \"./resourceMethod\"\n\nexport const sendMessage = (\n  prevRootState: RootState,\n  nextRootState: RootState,\n  action: PayloadAction<any>,\n) => {\n  const currentAppID = nextRootState.currentApp.appInfo.appId ?? \"\"\n  const { id: teamID = \"\", id = \"\" } =\n    getCurrentTeamInfo(store.getState()) ?? {}\n  const { type } = action\n  const typeList = type.split(\"/\")\n  const reduxType = typeList[0]\n  const reduxAction = typeList[1]\n  switch (reduxType) {\n    case \"components\": {\n      componentsAsync(\n        reduxAction,\n        currentAppID,\n        action,\n        teamID,\n        id,\n        prevRootState,\n        nextRootState,\n      )\n      break\n    }\n    case \"action\": {\n      actionsAsync(\n        reduxAction,\n        currentAppID,\n        action,\n        teamID,\n        id,\n        prevRootState,\n        nextRootState,\n      )\n      break\n    }\n    case \"apps\": {\n      appsAsync(\n        reduxAction,\n        currentAppID,\n        action,\n        teamID,\n        id,\n        prevRootState,\n        nextRootState,\n      )\n      break\n    }\n    case \"appInfo\": {\n      appInfoAsync(\n        reduxAction,\n        currentAppID,\n        action,\n        teamID,\n        id,\n        prevRootState,\n        nextRootState,\n      )\n      break\n    }\n    case \"resource\": {\n      resourcesAsync(\n        reduxAction,\n        currentAppID,\n        action,\n        teamID,\n        id,\n        prevRootState,\n        nextRootState,\n      )\n      agentAsync(\n        reduxAction,\n        currentAppID,\n        action,\n        teamID,\n        id,\n        prevRootState,\n        nextRootState,\n      )\n      break\n    }\n    default:\n      break\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/reduxAsync/sendMessage/resourceMethod.ts",
    "content": "import { PayloadAction } from \"@reduxjs/toolkit\"\nimport { Connection, getTextMessagePayload } from \"@/api/ws\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\nimport { RootState } from \"@/store\"\n\nexport const resourcesAsync = (\n  reduxAction: string,\n  currentAppID: string,\n  action: PayloadAction<any>,\n  teamID: string,\n  uid: string,\n  _prevRootState: RootState,\n  _nextRootState: RootState,\n) => {\n  const { payload } = action\n  switch (reduxAction) {\n    case \"addResourceItemReducer\": {\n      if (currentAppID) {\n        Connection.getTextRoom(\"app\", currentAppID)?.send(\n          getTextMessagePayload(\n            TextSignal.GLOBAL_BROADCAST_ONLY,\n            TextTarget.RESOURCE,\n            true,\n            action,\n            teamID,\n            uid,\n            [payload],\n          ),\n        )\n      } else {\n        Connection.getTextRoom(\"dashboard\", \"\")?.send(\n          getTextMessagePayload(\n            TextSignal.GLOBAL_BROADCAST_ONLY,\n            TextTarget.RESOURCE,\n            true,\n            action,\n            teamID,\n            uid,\n            [payload],\n          ),\n        )\n      }\n      break\n    }\n    case \"updateResourceItemReducer\": {\n      if (currentAppID) {\n        Connection.getTextRoom(\"app\", currentAppID)?.send(\n          getTextMessagePayload(\n            TextSignal.GLOBAL_BROADCAST_ONLY,\n            TextTarget.RESOURCE,\n            true,\n            action,\n            teamID,\n            uid,\n            [payload],\n          ),\n        )\n      } else {\n        Connection.getTextRoom(\"dashboard\", \"\")?.send(\n          getTextMessagePayload(\n            TextSignal.GLOBAL_BROADCAST_ONLY,\n            TextTarget.RESOURCE,\n            true,\n            action,\n            teamID,\n            uid,\n            [payload],\n          ),\n        )\n      }\n\n      break\n    }\n    case \"removeResourceItemReducer\": {\n      if (currentAppID) {\n        Connection.getTextRoom(\"app\", currentAppID)?.send(\n          getTextMessagePayload(\n            TextSignal.GLOBAL_BROADCAST_ONLY,\n            TextTarget.RESOURCE,\n            true,\n            action,\n            teamID,\n            uid,\n            [payload],\n          ),\n        )\n      } else {\n        Connection.getTextRoom(\"dashboard\", \"\")?.send(\n          getTextMessagePayload(\n            TextSignal.GLOBAL_BROADCAST_ONLY,\n            TextTarget.RESOURCE,\n            true,\n            action,\n            teamID,\n            uid,\n            [payload],\n          ),\n        )\n      }\n      break\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/undoRedo/index.ts",
    "content": "import { Middleware, isAction } from \"@reduxjs/toolkit\"\nimport { REDUX_ACTION_FROM } from \"./interface\"\nimport { undoRedoMethod } from \"./method\"\n\nexport const UndoRedo: Middleware = (store) => (next) => (action) => {\n  if (!isAction(action) || !(\"payload\" in action)) {\n    return next(action)\n  }\n  if (\"from\" in action && action.from && action.from === REDUX_ACTION_FROM.WS) {\n    const resp = next(action)\n    return resp\n  }\n  const prevRootState = store.getState()\n  const resp = next(action)\n  const nextRootState = store.getState()\n  undoRedoMethod(prevRootState, nextRootState, action)\n  return resp\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/undoRedo/interface.ts",
    "content": "export enum REDUX_ACTION_FROM {\n  UNDO = \"undo\",\n  REDO = \"redo\",\n  WS = \"ws\",\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/undoRedo/method/action.tsx",
    "content": "import { AnyAction } from \"@reduxjs/toolkit\"\nimport { REDUX_ACTION_FROM } from \"@/middleware/undoRedo/interface\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport { RootState } from \"@/store\"\nimport IllaUndoRedoManager from \"@/utils/undoRedo/undo\"\n\nexport const actionsSnapShot = (\n  reduxAction: string,\n  action: AnyAction,\n  _prevRootState: RootState,\n  _nextRootState: RootState,\n) => {\n  switch (reduxAction) {\n    case \"addActionItemReducer\": {\n      const newAction = {\n        type: \"action/removeActionItemReducer\",\n        payload: {\n          actionID: action.payload.actionID,\n          displayName: action.payload.displayName,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"removeActionItemReducer\": {\n      const originAction = getActionList(_prevRootState).find(\n        (item) => item.displayName === action.payload.displayName,\n      )\n      const newAction = {\n        type: \"action/addActionItemReducer\",\n        payload: originAction,\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"updateActionItemReducer\": {\n      const originAction = getActionList(_prevRootState).find(\n        (item) => item.displayName === action.payload.displayName,\n      )\n      const newAction = {\n        type: \"action/updateActionItemReducer\",\n        payload: originAction,\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"updateActionDisplayNameReducer\": {\n      const newAction = {\n        type: \"action/updateActionDisplayNameReducer\",\n        payload: {\n          newDisplayName: action.payload.oldDisplayName,\n          oldDisplayName: action.payload.newDisplayName,\n          actionID: action.payload.actionID,\n        },\n        from: action.from,\n      }\n\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/undoRedo/method/components.tsx",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { AnyAction } from \"@reduxjs/toolkit\"\nimport { REDUX_ACTION_FROM } from \"@/middleware/undoRedo/interface\"\nimport { UpdateComponentPositionPayload } from \"@/redux/currentApp/components/componentsPayload\"\nimport {\n  getComponentMap,\n  getOriginalGlobalData,\n  searchDSLByDisplayName,\n  searchDSLFromTree,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { RootState } from \"@/store\"\nimport { buildTreeByMapNode } from \"@/utils/componentNode/flatTree\"\nimport IllaUndoRedoManager from \"@/utils/undoRedo/undo\"\n\nexport const componentsSnapShot = (\n  reduxAction: string,\n  action: AnyAction,\n  prevRootState: RootState,\n  nextRootState: RootState,\n) => {\n  const prevComponents = getComponentMap(prevRootState)\n  const nextComponents = getComponentMap(nextRootState)\n  switch (reduxAction) {\n    // COMPONENT\n    case \"addComponentReducer\": {\n      const newAction = {\n        type: \"components/deleteComponentNodeReducer\",\n        payload: {\n          displayNames: action.payload.map(\n            (item: ComponentTreeNode) => item.displayName,\n          ),\n          source: \"undoRedo\",\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"deleteComponentNodeReducer\": {\n      const originActionComponentNode = action.payload.displayNames\n        .map((displayName: string) => {\n          return buildTreeByMapNode(displayName, prevComponents)\n        })\n        .filter((item: ComponentTreeNode | null) => item != undefined)\n      const newAction = {\n        type: \"components/addComponentReducer\",\n        payload: originActionComponentNode,\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"addModalComponentReducer\": {\n      const newAction = {\n        type: \"components/deleteComponentNodeReducer\",\n        payload: {\n          displayNames: [action.payload.modalComponentNode.displayName],\n          source: \"undoRedo\",\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"updateComponentLayoutInfoReducer\": {\n      const originActionComponentNode = searchDSLByDisplayName(\n        action.payload.displayName,\n        prevRootState,\n      )\n      if (!originActionComponentNode) break\n      const newAction = {\n        type: \"components/updateComponentLayoutInfoReducer\",\n        payload: {\n          displayName: action.payload.displayName,\n          layoutInfo: {\n            x: originActionComponentNode.x,\n            y: originActionComponentNode.y,\n            w: originActionComponentNode.w,\n            h: originActionComponentNode.h,\n          },\n          parentNode: originActionComponentNode.parentNode,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"updateComponentPositionReducer\": {\n      const layoutInfos = getClientWidgetLayoutInfo(prevRootState)\n      const originNodeLayoutInfos = (\n        action.payload as UpdateComponentPositionPayload\n      ).updateSlices.map((item) => {\n        return layoutInfos[item.displayName]\n      })\n      const newUpdateSlices = originNodeLayoutInfos.map((item) => {\n        return {\n          displayName: item.displayName,\n          x: item.layoutInfo.x,\n          y: item.layoutInfo.y,\n          w: item.layoutInfo.w,\n          h: item.layoutInfo.h,\n        }\n      })\n      const newAction = {\n        type: \"components/updateComponentPositionReducer\",\n        payload: {\n          oldParentNodeDisplayName: action.payload.newParentNodeDisplayName,\n          newParentNodeDisplayName: action.payload.oldParentNodeDisplayName,\n          updateSlices: newUpdateSlices,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"updateComponentDisplayNameReducer\": {\n      const { displayName, newDisplayName } = action.payload\n\n      const newAction = {\n        type: \"components/updateComponentDisplayNameReducer\",\n        payload: {\n          displayName: newDisplayName,\n          newDisplayName: displayName,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"setComponentPropsReducer\":\n    case \"updateComponentPropsReducer\": {\n      const { displayName, notUseUndoRedo } = action.payload\n      if (notUseUndoRedo) break\n      const originNode = searchDSLByDisplayName(displayName, prevRootState)\n      if (!originNode) break\n      const newAction = {\n        type: \"components/setComponentPropsReducer\",\n        payload: {\n          displayName,\n          updateSlice: originNode.props,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    // PAGE\n    case \"addTargetPageSectionReducer\": {\n      const { pageName, addedSectionName } = action.payload\n      const newAction = {\n        type: \"components/deleteTargetPageSectionReducer\",\n        payload: {\n          pageName,\n          deleteSectionName: addedSectionName,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"deleteTargetPageSectionReducer\": {\n      const { pageName, deleteSectionName } = action.payload\n      const prevComponentTree = buildTreeByMapNode(\"root\", prevComponents)\n\n      const currentTargeNode = searchDSLFromTree(prevComponentTree, pageName)\n      if (!currentTargeNode) break\n      const originSectionNode = currentTargeNode.childrenNode.find(\n        (node) => node.showName === deleteSectionName,\n      )\n      if (!originSectionNode) break\n\n      const newAction = {\n        type: \"components/addTargetPageSectionReducer\",\n        payload: {\n          pageName,\n          addedSectionName: deleteSectionName,\n          originSectionNode,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"addSectionViewConfigByConfigReducer\":\n    case \"addSectionViewReducer\": {\n      const { parentNodeName } = action.payload\n\n      const originParentNode = searchDSLByDisplayName(\n        parentNodeName,\n        nextRootState,\n      )\n      if (!originParentNode) break\n      const { props } = originParentNode\n      if (!props) break\n      const { viewSortedKey } = props\n      if (!Array.isArray(viewSortedKey)) break\n\n      const lastViewSortedKey = (viewSortedKey as string[]).at(-1)\n      if (!lastViewSortedKey) break\n      const newAction = {\n        type: \"components/deleteSectionViewReducer\",\n        payload: {\n          viewDisplayName: lastViewSortedKey,\n          parentNodeName,\n          originPageSortedKey: viewSortedKey,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"deleteSectionViewReducer\": {\n      const { parentNodeName, viewDisplayName } = action.payload\n      const prevComponentTree = buildTreeByMapNode(\"root\", prevComponents)\n\n      const originParentNode = searchDSLFromTree(\n        prevComponentTree,\n        parentNodeName,\n      )\n\n      if (!originParentNode) break\n\n      const viewNode = originParentNode.childrenNode.find(\n        (node) => node.displayName === viewDisplayName,\n      )\n      if (!viewNode) break\n      const originChildrenNode = viewNode.childrenNode\n\n      const newAction = {\n        type: \"components/addSectionViewReducer\",\n        payload: {\n          parentNodeName,\n          sectionName: originParentNode.showName,\n          originChildrenNode: originChildrenNode,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"updateTargetPagePropsReducer\": {\n      const { pageName, notUseUndoRedo } = action.payload\n      if (notUseUndoRedo) break\n      const originPage = searchDSLByDisplayName(pageName, prevRootState)\n      if (!originPage) break\n      const newAction = {\n        type: \"components/updateTargetPagePropsReducer\",\n        payload: {\n          pageName,\n          newProps: originPage.props,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"addPageNodeWithSortOrderReducer\": {\n      const { displayName } = action.payload\n      const rootNode = buildTreeByMapNode(\"root\", nextComponents)\n\n      if (!rootNode || !rootNode.props) break\n\n      const newAction = {\n        type: \"components/deletePageNodeReducer\",\n        payload: {\n          displayName: displayName,\n          originPageSortedKey: rootNode.props.pageSortedKey,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"deletePageNodeReducer\": {\n      const originPageNode = searchDSLByDisplayName(\n        action.payload.displayName,\n        prevRootState,\n      )\n      if (!originPageNode) break\n      const newAction = {\n        type: \"components/addPageNodeWithSortOrderReducer\",\n        payload: originPageNode,\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"updateTargetPageLayoutReducer\": {\n      const { pageName } = action.payload\n      const prevComponentTree = buildTreeByMapNode(\"root\", prevComponents)\n      const originPageNode = searchDSLFromTree(prevComponentTree, pageName)\n      if (!originPageNode || !originPageNode.props) break\n      const newAction = {\n        type: \"components/updateTargetPageLayoutReducer\",\n        payload: {\n          pageName: pageName,\n          layout: originPageNode.props.layout,\n          originPageNode,\n        },\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"deleteSubPageViewNodeReducer\": {\n      const newAction = {\n        type: \"components/addSubPageReducer\",\n        payload: {\n          pageName: action.payload.pageName,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"addSubPageReducer\": {\n      const { pageName } = action.payload\n      const pageNode = searchDSLFromTree(\n        buildTreeByMapNode(\"root\", nextComponents),\n        pageName,\n      )\n      const bodySectionNode = pageNode?.childrenNode.find(\n        (node) => node.showName === \"bodySection\",\n      )\n      if (!bodySectionNode) break\n      const viewConfigs = bodySectionNode.props!.sectionViewConfigs\n      const lastViewConfig = viewConfigs[viewConfigs.length - 1]\n      if (!lastViewConfig) break\n      const newAction = {\n        type: \"components/deleteSubPageViewNodeReducer\",\n        payload: {\n          pageName: action.payload.pageName,\n          subPagePath: lastViewConfig.path,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"updateSubPagePathReducer\": {\n      const { pageName, subPagePath, oldSubPagePath } = action.payload\n      const newAction = {\n        type: \"components/updateSubPagePathReducer\",\n        payload: {\n          pageName: pageName,\n          subPagePath: oldSubPagePath,\n          oldSubPagePath: subPagePath,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"updateDefaultSubPagePathReducer\": {\n      const { pageName } = action.payload\n      const prevComponentTree = buildTreeByMapNode(\"root\", prevComponents)\n      const pageNode = searchDSLFromTree(prevComponentTree, pageName)\n      const oldBodySectionNode = pageNode?.childrenNode.find(\n        (node) => node.showName === \"bodySection\",\n      )\n      if (!oldBodySectionNode) break\n      const defaultViewKey = oldBodySectionNode.props!.defaultViewKey\n      const newAction = {\n        type: \"components/updateDefaultSubPagePathReducer\",\n        payload: {\n          pageName: pageName,\n          subPagePath: defaultViewKey,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"updateCurrentPageStyleReducer\": {\n      const { pageName, style, sectionName } = action.payload\n      const prevComponentTree = buildTreeByMapNode(\"root\", prevComponents)\n\n      const pageNode = searchDSLFromTree(prevComponentTree, pageName)\n      const updateKeys = Object.keys(style)\n      if (!pageNode) break\n      const sectionNode = pageNode.childrenNode?.find(\n        (node) => node.showName === sectionName,\n      )\n      if (!sectionNode) break\n      const needBackStyle: Record<string, any> = {}\n      updateKeys.forEach((key) => {\n        needBackStyle[key] = sectionNode.props?.style?.[key] ?? undefined\n      })\n      const newAction = {\n        type: \"components/updateCurrentPageStyleReducer\",\n        payload: {\n          pageName: pageName,\n          style: needBackStyle,\n          sectionName: sectionName,\n        },\n        from: action.from,\n      }\n\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([newAction])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([newAction])\n      }\n      break\n    }\n    case \"deleteCurrentPageStyleReducer\": {\n      const { pageName, sectionName } = action.payload\n      const prevComponentTree = buildTreeByMapNode(\"root\", prevComponents)\n      const pageNode = searchDSLFromTree(prevComponentTree, pageName)\n      if (!pageNode) break\n      const sectionNode = pageNode.childrenNode?.find(\n        (node) => node.showName === sectionName,\n      )\n      if (!sectionNode) break\n      const sectionNodeStyle = sectionNode.props?.style\n      if (!sectionNodeStyle) break\n      const newAction = {\n        type: \"components/updateCurrentPageStyleReducer\",\n        payload: {\n          pageName: pageName,\n          style: sectionNodeStyle,\n          sectionName: sectionName,\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"setGlobalStateReducer\": {\n      const { key, oldKey, value } = action.payload\n      let newAction\n      if (!oldKey) {\n        newAction = {\n          type: \"components/deleteGlobalStateByKeyReducer\",\n          payload: { key },\n          from: action.from,\n        }\n      } else {\n        newAction = {\n          type: \"components/setGlobalStateReducer\",\n          payload: { key: oldKey, oldKey: key, value },\n          from: action.from,\n        }\n      }\n\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n    case \"deleteGlobalStateByKeyReducer\": {\n      const prevGlobalState = getOriginalGlobalData(prevRootState)\n      const { key } = action.payload\n      const targetGlobalState = prevGlobalState[key]\n      const newAction = {\n        type: \"components/setGlobalStateReducer\",\n        payload: {\n          key,\n          value: targetGlobalState,\n          oldKey: \"\",\n        },\n        from: action.from,\n      }\n      if (action.from === REDUX_ACTION_FROM.UNDO) {\n        IllaUndoRedoManager.pushToRedoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      } else {\n        IllaUndoRedoManager.pushToUndoStack([\n          JSON.parse(JSON.stringify(newAction)),\n        ])\n      }\n      break\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/middleware/undoRedo/method/index.tsx",
    "content": "import { AnyAction } from \"@reduxjs/toolkit\"\nimport { RootState } from \"@/store\"\nimport { actionsSnapShot } from \"./action\"\nimport { componentsSnapShot } from \"./components\"\n\nexport const undoRedoMethod = (\n  prevRootState: RootState,\n  nextRootState: RootState,\n  action: AnyAction,\n) => {\n  const { type } = action\n  const typeList = type.split(\"/\")\n  const reduxType = typeList[0]\n  const reduxAction = typeList[1]\n  switch (reduxType) {\n    case \"components\": {\n      componentsSnapShot(reduxAction, action, prevRootState, nextRootState)\n      break\n    }\n    case \"action\": {\n      actionsSnapShot(reduxAction, action, prevRootState, nextRootState)\n      break\n    }\n    default:\n      break\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/AIAgent/aiagent.tsx",
    "content": "import { CodeEditor } from \"@illa-public/code-editor\"\nimport { AvatarUpload } from \"@illa-public/cropper\"\nimport { UpgradeIcon } from \"@illa-public/icon\"\nimport {\n  ContributeAgentPC,\n  HASHTAG_REQUEST_TYPE,\n  ShareAgentPC,\n  ShareAgentTab,\n} from \"@illa-public/invite-modal\"\nimport {\n  freeModelList,\n  isPremiumModel,\n  premiumModelList,\n} from \"@illa-public/market-agent\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport {\n  AI_AGENT_MODEL,\n  AI_AGENT_TYPE,\n  Agent,\n  KnowledgeFile,\n  MemberInfo,\n  USER_ROLE,\n  USER_STATUS,\n} from \"@illa-public/public-types\"\nimport { RecordEditor } from \"@illa-public/record-editor\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport {\n  getCurrentTeamInfo,\n  getCurrentUser,\n  getPlanUtils,\n  teamActions,\n} from \"@illa-public/user-data\"\nimport {\n  canManageInvite,\n  canUseUpgradeFeature,\n  openShareAgentModal,\n  showShareAgentModal,\n  showShareAgentModalOnlyForShare,\n} from \"@illa-public/user-role-utils\"\nimport {\n  getAgentPublicLink,\n  getAuthToken,\n  getILLABuilderURL,\n  getILLACloudURL,\n  sendTagEvent,\n} from \"@illa-public/utils\"\nimport { isEqual } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useMemo, useState } from \"react\"\nimport { Helmet } from \"react-helmet-async\"\nimport { Controller, useForm, useFormState, useWatch } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useAsyncValue, useParams } from \"react-router-dom\"\nimport { v4 } from \"uuid\"\nimport {\n  Button,\n  Divider,\n  DocsIcon,\n  Image,\n  Input,\n  Link,\n  PlayFillIcon,\n  PlusIcon,\n  PreviousIcon,\n  RadioGroup,\n  ResetIcon,\n  Select,\n  TextArea,\n  getColor,\n  useMessage,\n} from \"@illa-design/react\"\nimport { createAction } from \"@/api/actions\"\nimport { TextSignal } from \"@/api/ws/textSignal\"\nimport AIIcon from \"@/assets/agent/ai.svg?react\"\nimport { FullPageLoading } from \"@/components/FullPageLoading\"\nimport { buildActionInfo, buildAppWithAgentSchema } from \"@/config/AppWithAgent\"\nimport { AIAgentBlock } from \"@/page/AI/components/AIAgentBlock\"\nimport AILoading from \"@/page/AI/components/AILoading\"\nimport { PreviewChat } from \"@/page/AI/components/PreviewChat\"\nimport { useAgentConnect } from \"@/page/AI/components/ws/useAgentConnect\"\nimport { aiAgentActions } from \"@/redux/aiAgent/dashboardTeamAIAgentSlice\"\nimport { CollaboratorsInfo } from \"@/redux/currentApp/collaborators/collaboratorsState\"\nimport {\n  createAgent,\n  generateDescription,\n  putAgentDetail,\n  uploadAgentIcon,\n} from \"@/services/agent\"\nimport { fetchCreateApp } from \"@/services/apps\"\nimport { copyToClipboard } from \"@/utils/copyToClipboard\"\nimport { track } from \"@/utils/mixpanelHelper\"\nimport { ChatContext } from \"../components/ChatContext\"\nimport { ErrorText } from \"../components/ErrorText\"\nimport KnowledgeUpload from \"../components/KnowledgeUpload\"\nimport {\n  ChatSendRequestPayload,\n  SenderType,\n} from \"../components/PreviewChat/interface\"\nimport { SCROLL_ID } from \"./interface\"\nimport {\n  aiAgentContainerStyle,\n  backTextStyle,\n  buttonContainerStyle,\n  codeEditorErrorStyle,\n  descContainerStyle,\n  descTextStyle,\n  docTextContainerStyle,\n  docTextStyle,\n  labelLogoStyle,\n  labelStyle,\n  labelTextStyle,\n  leftLoadingCoverStyle,\n  leftPanelContainerStyle,\n  leftPanelContentContainerStyle,\n  leftPanelCoverContainer,\n  leftPanelHeaderStyle,\n  leftPanelTitleTextStyle,\n  premiumContainerStyle,\n  rightPanelContainerStyle,\n  uploadContainerStyle,\n  uploadContentContainerStyle,\n  uploadTextStyle,\n} from \"./style\"\nimport { agentData2JSONReport } from \"./utils\"\n\n// TODO: WTF, can edit knowledge file\nconst CAN_EDIT_KNOWLEDGE_FILE = false\n\nexport const AIAgent: FC = () => {\n  const data = useAsyncValue() as {\n    agent: Agent\n  }\n\n  const methods = useForm<Agent>({\n    mode: \"onSubmit\",\n    reValidateMode: \"onSubmit\",\n    defaultValues: {\n      ...data.agent,\n      variables:\n        data.agent.variables.length === 0\n          ? [{ key: \"\", value: \"\" }]\n          : data.agent.variables,\n    },\n  })\n\n  const {\n    control,\n    handleSubmit,\n    getValues,\n    reset,\n    clearErrors,\n    setError,\n    trigger,\n  } = methods\n\n  const { agentID, teamIdentifier } = useParams()\n\n  const { isSubmitting, isDirty, errors } = useFormState({\n    control,\n  })\n\n  const { t } = useTranslation()\n\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)!!\n\n  const message = useMessage()\n  const upgradeModal = useUpgradeModal()\n\n  const currentUserInfo = useSelector(getCurrentUser)\n\n  const dispatch = useDispatch()\n\n  // page state\n  const [generateDescLoading, setGenerateDescLoading] = useState(false)\n  const [isRunning, setIsRunning] = useState(false)\n  const [isConnecting, setIsConnecting] = useState(false)\n  const [shareDialogVisible, setShareDialogVisible] = useState(false)\n  const [contributedDialogVisible, setContributedDialogVisible] =\n    useState(false)\n  const [defaultShareTag, setDefaultShareTag] = useState<ShareAgentTab>(\n    ShareAgentTab.SHARE_WITH_TEAM,\n  )\n\n  // data state\n  const [inRoomUsers, setInRoomUsers] = useState<CollaboratorsInfo[]>([])\n  const [isReceiving, setIsReceiving] = useState(false)\n  const [lastRunAgent, setLastRunAgent] = useState<Agent | undefined>()\n\n  // premium dialog\n  const canUseBillingFeature = canUseUpgradeFeature(\n    currentTeamInfo?.myRole,\n    getPlanUtils(currentTeamInfo),\n    currentTeamInfo?.totalTeamLicense?.teamLicensePurchased,\n    currentTeamInfo?.totalTeamLicense?.teamLicenseAllPaid,\n  )\n\n  // ui state\n\n  const [isFullPageLoading, setIsFullPageLoading] = useState(false)\n\n  const updateLocalIcon = useCallback(\n    (icon: string, newRoomUsers: CollaboratorsInfo[]) => {\n      const updateRoomUsers = [...newRoomUsers]\n      let index = -1\n      if (getValues(\"aiAgentID\")) {\n        index = updateRoomUsers.findIndex(\n          (user) => user.id === getValues(\"aiAgentID\"),\n        )\n      } else {\n        index = updateRoomUsers.findIndex(\n          (user) => user.roomRole === SenderType.ANONYMOUS_AGENT,\n        )\n      }\n      if (index != -1) {\n        updateRoomUsers[index].avatar = icon\n      }\n      return updateRoomUsers\n    },\n    [getValues],\n  )\n\n  const updateLocalName = useCallback(\n    (name: string, newRoomUsers: CollaboratorsInfo[]) => {\n      const updateRoomUsers = [...newRoomUsers]\n      let index = -1\n      if (getValues(\"aiAgentID\")) {\n        index = updateRoomUsers.findIndex(\n          (user) => user.id === getValues(\"aiAgentID\"),\n        )\n      } else {\n        index = updateRoomUsers.findIndex(\n          (user) => user.roomRole === SenderType.ANONYMOUS_AGENT,\n        )\n      }\n      if (index != -1) {\n        updateRoomUsers[index].nickname = name\n      }\n      return updateRoomUsers\n    },\n    [getValues],\n  )\n\n  // watch dirty\n  const getRunAgent = useCallback(() => {\n    return {\n      variables: getValues(\"variables\"),\n      model: getValues(\"model\"),\n      prompt: getValues(\"prompt\"),\n      agentType: getValues(\"agentType\"),\n      // TODO: add knowledge\n    } as Agent\n  }, [getValues])\n\n  const fieldArray = useWatch({\n    control: control,\n    name: [\"variables\", \"model\", \"prompt\", \"agentType\"],\n  })\n\n  const blockInputDirty = useMemo(() => {\n    if (lastRunAgent === undefined) {\n      return true\n    }\n    return (\n      !isEqual(\n        lastRunAgent.variables.filter((v) => v.key !== \"\" && v.value !== \"\"),\n        fieldArray[0].filter((v) => v.key !== \"\" && v.value !== \"\"),\n      ) ||\n      !isEqual(lastRunAgent.model, fieldArray[1]) ||\n      !isEqual(lastRunAgent.prompt, fieldArray[2]) ||\n      !isEqual(lastRunAgent.agentType, fieldArray[3])\n    )\n  }, [lastRunAgent, fieldArray])\n\n  useEffect(() => {\n    const unload = (e: BeforeUnloadEvent) => {\n      if (isDirty) {\n        e.preventDefault()\n        e.returnValue = \"\"\n      }\n    }\n    window.addEventListener(\"beforeunload\", unload)\n    window.addEventListener(\"onunload\", unload)\n    return () => {\n      window.removeEventListener(\"beforeunload\", unload)\n      window.removeEventListener(\"onunload\", unload)\n    }\n  }, [isDirty])\n\n  const { sendMessage, generationMessage, chatMessages, reconnect, connect } =\n    useAgentConnect({\n      onStartRunning: () => {\n        setLastRunAgent(getRunAgent())\n      },\n      onConnecting: (isConnecting) => {\n        setIsConnecting(isConnecting)\n      },\n      onReceiving: (isReceiving) => {\n        setIsReceiving(isReceiving)\n      },\n      onRunning: (isRunning: boolean) => {\n        setIsRunning(isRunning)\n      },\n      onSendClean: () => {\n        sendMessage(\n          {} as ChatSendRequestPayload,\n          TextSignal.CLEAN,\n          getValues(\"agentType\"),\n          \"clean\",\n          false,\n        )\n      },\n      onSendPrompt: () => {\n        sendMessage(\n          {\n            threadID: v4(),\n            prompt: getValues(\"prompt\"),\n            variables: getValues(\"variables\"),\n            // TODO: add knowledge\n            actionID: getValues(\"aiAgentID\"),\n            modelConfig: getValues(\"modelConfig\"),\n            model: getValues(\"model\"),\n            agentType: getValues(\"agentType\"),\n          } as ChatSendRequestPayload,\n          TextSignal.RUN,\n          getValues(\"agentType\"),\n          \"chat\",\n          false,\n        )\n      },\n      onUpdateRoomUsers: (roomUsers: CollaboratorsInfo[]) => {\n        let newRoomUsers = updateLocalIcon(getValues(\"icon\"), roomUsers)\n        newRoomUsers = updateLocalName(getValues(\"name\"), roomUsers)\n        setInRoomUsers(newRoomUsers)\n      },\n    })\n\n  const handleClickBack = () => {\n    const cloud_url = getILLACloudURL(window.customDomain)\n    if (document.referrer.includes(cloud_url)) {\n      return (location.href = `${cloud_url}/workspace/${teamIdentifier}/ai-agents`)\n    }\n    if (\n      document.referrer.includes(import.meta.env.ILLA_MARKET_URL) &&\n      agentID\n    ) {\n      return (location.href = `${\n        import.meta.env.ILLA_MARKET_URL\n      }/ai-agent/${agentID}/detail`)\n    }\n    return (location.href = cloud_url)\n  }\n\n  const handleScrollToElement = (scrollId: string) => {\n    const el = document.querySelector(`[data-scroll-id=${scrollId}]`)\n    setTimeout(() => {\n      el?.scrollIntoView({ behavior: \"smooth\", block: \"center\" })\n    }, 30)\n  }\n\n  const handleSubmitSave = async (data: Agent) => {\n    let currentData: Agent = { ...data }\n    if (\n      !isPremiumModel(currentData.model) &&\n      currentData.knowledge?.length > 0\n    ) {\n      currentData = {\n        ...currentData,\n        knowledge: [],\n      }\n    }\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n      ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n      {\n        element: \"save\",\n        parameter1: agentData2JSONReport(currentData),\n        parameter5: currentData.aiAgentID || \"-1\",\n      },\n    )\n    let agentInfo: Agent\n    try {\n      let updateIconURL = currentData.icon\n      if (currentData.icon !== undefined && currentData.icon !== \"\") {\n        const iconURL = new URL(currentData.icon)\n        if (iconURL.protocol !== \"http:\" && iconURL.protocol !== \"https:\") {\n          updateIconURL = await uploadAgentIcon(currentData.icon)\n        }\n      }\n      if (currentData.aiAgentID === undefined || currentData.aiAgentID === \"\") {\n        const resp = await createAgent({\n          ...currentData,\n          icon: updateIconURL,\n          variables: currentData.variables.filter(\n            (v) => v.key !== \"\" && v.value !== \"\",\n          ),\n        })\n\n        sendTagEvent(\"create_agent\", currentUserInfo.userID)\n        dispatch(\n          aiAgentActions.addTeamAIAgentReducer({\n            aiAgent: resp.data,\n          }),\n        )\n        reset({\n          ...resp.data,\n          variables:\n            resp.data.variables.length === 0\n              ? [{ key: \"\", value: \"\" }]\n              : resp.data.variables,\n        })\n        agentInfo = resp.data\n      } else {\n        const resp = await putAgentDetail(currentData.aiAgentID, {\n          ...currentData,\n          icon: updateIconURL,\n          variables: data.variables.filter(\n            (v) => v.key !== \"\" && v.value !== \"\",\n          ),\n        })\n        dispatch(\n          aiAgentActions.modifyTeamAIAgentReducer({\n            aiAgentID: resp.data.aiAgentID,\n            modifiedProps: resp.data,\n          }),\n        )\n        reset({\n          ...resp.data,\n          variables:\n            resp.data.variables.length === 0\n              ? [{ key: \"\", value: \"\" }]\n              : resp.data.variables,\n        })\n        agentInfo = resp.data\n      }\n      message.success({\n        content: t(\"dashboard.message.create-suc\"),\n      })\n      return agentInfo\n    } catch (e) {\n      message.error({\n        content: t(\"dashboard.message.create-failed\"),\n      })\n    }\n  }\n\n  const handleVerifyOnSave = async () => {\n    await trigger()\n    let validate = true\n    if (!!errors.prompt) {\n      handleScrollToElement(SCROLL_ID.PROMPT)\n      validate = false\n    } else if (!!errors.knowledge) {\n      handleScrollToElement(SCROLL_ID.KNOWLEDGE)\n      validate = false\n    } else if (!!errors.variables) {\n      handleScrollToElement(SCROLL_ID.VARIABLES)\n      validate = false\n    } else if (!!errors.name) {\n      handleScrollToElement(SCROLL_ID.NAME)\n      validate = false\n    } else if (!!errors.description) {\n      handleScrollToElement(SCROLL_ID.DESCRIPTION)\n      validate = false\n    } else if (!!errors.icon) {\n      handleScrollToElement(SCROLL_ID.ICON)\n      validate = false\n    }\n    return validate\n  }\n\n  const handleClickCreateApp = async () => {\n    const validate = await handleVerifyOnSave()\n    if (validate) {\n      try {\n        setIsFullPageLoading(true)\n        const agentInfo = await handleSubmitSave(getValues())\n        if (agentInfo) {\n          const variableKeys = agentInfo.variables.map((v) => v.key)\n          const { appInfo, variableKeyMapInputNodeDisplayName } =\n            buildAppWithAgentSchema(variableKeys)\n          const appInfoResp = await fetchCreateApp({\n            appName: \"Untitled app\",\n            initScheme: appInfo,\n          })\n          const agentActionInfo = buildActionInfo(\n            agentInfo,\n            variableKeyMapInputNodeDisplayName,\n          )\n          await createAction(appInfoResp.data.appId, agentActionInfo)\n          window.open(\n            `${getILLABuilderURL(window.customDomain)}/${teamIdentifier}/app/${\n              appInfoResp.data.appId\n            }`,\n            \"_blank\",\n          )\n        }\n      } catch {\n        message.error({\n          content: t(\"create_fail\"),\n        })\n      } finally {\n        setIsFullPageLoading(false)\n      }\n    }\n  }\n\n  const handleVerifyOnStart = () => {\n    clearErrors()\n    if (!getValues(\"prompt\")) {\n      setError(\"prompt\", {\n        type: \"required\",\n        message: t(\"editor.ai-agent.validation_blank.prompt\"),\n      })\n      handleScrollToElement(SCROLL_ID.PROMPT)\n      return false\n    } else if (\n      !getValues(\"variables\").every(\n        (param) =>\n          (param.key === \"\" && param.value === \"\") ||\n          (param.key !== \"\" && param.value !== \"\"),\n      )\n    ) {\n      setError(\"variables\", {\n        type: \"validate\",\n        message: t(\"editor.ai-agent.validation_blank.variable_value\"),\n      })\n      handleScrollToElement(SCROLL_ID.VARIABLES)\n      return false\n    } else if (\n      Array.isArray(getValues(\"knowledge\")) &&\n      getValues(\"knowledge\").length > 0 &&\n      getValues(\"knowledge\").some((param) => param.value === \"\")\n    ) {\n      setError(\"variables\", {\n        type: \"knowledge\",\n        message: t(\"dashboard.message.parsing_file_in_prog\"),\n      })\n      handleScrollToElement(SCROLL_ID.KNOWLEDGE)\n      return false\n    }\n    return true\n  }\n\n  const handleClickStart = async () => {\n    if (!handleVerifyOnStart()) {\n      return\n    }\n    if (isPremiumModel(getValues(\"model\")) && !canUseBillingFeature) {\n      upgradeModal({\n        modalType: \"agent\",\n        from: \"agent_run_gpt4\",\n      })\n      return\n    }\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n      ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n      {\n        element: isRunning ? \"restart\" : \"start\",\n        parameter1: agentData2JSONReport(getValues()),\n        parameter5: getValues(\"aiAgentID\") || \"-1\",\n      },\n    )\n    isRunning\n      ? await reconnect(getValues(\"aiAgentID\"), getValues(\"agentType\"))\n      : await connect(getValues(\"aiAgentID\"), getValues(\"agentType\"))\n  }\n\n  return (\n    <>\n      <Helmet>\n        <title>\n          {agentID ? data.agent.name : t(\"new_dashboard.button.blank-agent\")}\n        </title>\n      </Helmet>\n      <ChatContext.Provider value={{ inRoomUsers }}>\n        <div css={aiAgentContainerStyle}>\n          <div css={leftPanelContainerStyle}>\n            <div css={leftPanelCoverContainer}>\n              <div css={leftPanelHeaderStyle}>\n                <div css={leftPanelTitleTextStyle} onClick={handleClickBack}>\n                  <PreviousIcon fs=\"16px\" />\n                  <span css={backTextStyle}>{t(\"editor.ai-agent.title\")}</span>\n                </div>\n                <Link\n                  href=\"https://docs.illacloud.com/ai-agent\"\n                  target=\"__blank\"\n                  colorScheme=\"techPurple\"\n                  hoverable={false}\n                  css={docTextContainerStyle}\n                >\n                  <span css={docTextStyle}>\n                    <DocsIcon size=\"16\" />\n                    <span>{t(\"editor.ai-agent.doc\")}</span>\n                  </span>\n                </Link>\n              </div>\n              <div css={leftPanelContentContainerStyle}>\n                <Controller\n                  name=\"agentType\"\n                  control={control}\n                  shouldUnregister={false}\n                  render={({ field }) => (\n                    <AIAgentBlock\n                      title={t(\"editor.ai-agent.label.mode\")}\n                      tips={t(\"editor.ai-agent.tips.mode\")}\n                      required\n                    >\n                      <RadioGroup\n                        colorScheme={getColor(\"grayBlue\", \"02\")}\n                        w=\"100%\"\n                        value={field.value}\n                        type=\"button\"\n                        forceEqualWidth={true}\n                        options={[\n                          {\n                            value: AI_AGENT_TYPE.CHAT,\n                            label: t(\"editor.ai-agent.option.mode.chat\"),\n                          },\n                          {\n                            value: AI_AGENT_TYPE.TEXT_GENERATION,\n                            label: t(\"editor.ai-agent.option.mode.text\"),\n                          },\n                        ]}\n                        onChange={(value) => {\n                          if (isReceiving || isConnecting) {\n                            message.info({\n                              content: t(\"editor.ai-agent.message.generating\"),\n                            })\n                            return\n                          }\n                          track(\n                            ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                            ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                            {\n                              element: \"mode_radio_button\",\n                              parameter1: value,\n                              parameter5: data.agent.aiAgentID || \"-1\",\n                            },\n                          )\n                          field.onChange(value)\n                        }}\n                      />\n                    </AIAgentBlock>\n                  )}\n                />\n                <Controller\n                  name=\"prompt\"\n                  control={control}\n                  rules={{\n                    required: t(\"editor.ai-agent.validation_blank.prompt\"),\n                  }}\n                  shouldUnregister={false}\n                  render={({ field: promptField }) => (\n                    <AIAgentBlock\n                      title={\"Prompt\"}\n                      required\n                      scrollId={SCROLL_ID.PROMPT}\n                    >\n                      <Controller\n                        name=\"variables\"\n                        control={control}\n                        render={({ field: variables }) => (\n                          <div>\n                            <CodeEditor\n                              {...promptField}\n                              css={codeEditorErrorStyle(!!errors.prompt)}\n                              placeholder={t(\n                                \"editor.ai-agent.placeholder.prompt\",\n                              )}\n                              minHeight=\"200px\"\n                              completionOptions={variables.value}\n                            />\n                            {errors.prompt?.message && (\n                              <ErrorText\n                                errorMessage={errors.prompt?.message}\n                              />\n                            )}\n                          </div>\n                        )}\n                      />\n                    </AIAgentBlock>\n                  )}\n                />\n\n                <Controller\n                  name=\"variables\"\n                  control={control}\n                  rules={{\n                    validate: (value) => {\n                      const isValidate = value.every(\n                        (param) =>\n                          (param.key === \"\" && param.value === \"\") ||\n                          (param.key !== \"\" && param.value !== \"\"),\n                      )\n                      return isValidate\n                        ? isValidate\n                        : t(\n                            \"Please ensure that both the key and value are either empty or not empty.\",\n                          )\n                    },\n                  }}\n                  shouldUnregister={false}\n                  render={({ field }) => (\n                    <AIAgentBlock\n                      title={t(\"editor.ai-agent.label.variable\")}\n                      scrollId={SCROLL_ID.VARIABLES}\n                    >\n                      <RecordEditor\n                        records={field.value}\n                        onAdd={() => {\n                          field.onChange([\n                            ...field.value,\n                            {\n                              key: \"\",\n                              value: \"\",\n                            },\n                          ])\n                        }}\n                        onChangeKey={(index, key) => {\n                          const newVariables = [...field.value]\n                          newVariables[index].key = key\n                          field.onChange(newVariables)\n                        }}\n                        onChangeValue={(index, _, value) => {\n                          const newVariables = [...field.value]\n                          newVariables[index].value = value\n                          field.onChange(newVariables)\n                        }}\n                        onDelete={(index) => {\n                          const newVariables = [...field.value]\n                          newVariables.splice(index, 1)\n                          if (newVariables.length === 0) {\n                            newVariables.push({\n                              key: \"\",\n                              value: \"\",\n                            })\n                          }\n                          field.onChange(newVariables)\n                        }}\n                        label={\"\"}\n                      />\n                      {errors.variables?.message && (\n                        <ErrorText errorMessage={errors.variables?.message} />\n                      )}\n                    </AIAgentBlock>\n                  )}\n                />\n\n                {CAN_EDIT_KNOWLEDGE_FILE &&\n                  isPremiumModel(getValues(\"model\")) && (\n                    <Controller\n                      name=\"knowledge\"\n                      control={control}\n                      rules={{\n                        validate: (value) => {\n                          const isValidate =\n                            !value ||\n                            value.length === 0 ||\n                            value.every((param) => param.value !== \"\")\n                          return isValidate ? isValidate : t(\"\")\n                        },\n                      }}\n                      shouldUnregister={false}\n                      render={({ field }) => (\n                        <AIAgentBlock\n                          title={t(\"knowledge\")}\n                          scrollId={SCROLL_ID.KNOWLEDGE}\n                        >\n                          <KnowledgeUpload\n                            addFile={(\n                              file: KnowledgeFile,\n                              isUpdate?: boolean,\n                            ) => {\n                              const { name, type } = file\n                              const files = field.value || []\n                              const index = files.findIndex(\n                                (item) =>\n                                  item.name === name && item.type === type,\n                              )\n                              if (index !== -1) {\n                                if (isUpdate) {\n                                  let needUpdateFile = files[index]\n                                  files.splice(index, 1, {\n                                    ...needUpdateFile,\n                                    ...file,\n                                  })\n                                } else {\n                                  const fileNamePrefix = `${\n                                    file.name.split(\".\")[0]\n                                  }(${v4().slice(0, 3)})`\n\n                                  files.push({\n                                    ...file,\n                                    name: `${fileNamePrefix}.${file.name.split(\n                                      \".\",\n                                    )?.[1]}`,\n                                  })\n                                }\n                              } else {\n                                files.push(file)\n                              }\n                              field.onChange(files)\n                            }}\n                            removeFile={(name: string) => {\n                              const currentFiles = field.value || []\n                              const files = currentFiles.filter(\n                                (item) => item.name !== name,\n                              )\n                              field.onChange(files)\n                            }}\n                            values={field.value}\n                          />\n                        </AIAgentBlock>\n                      )}\n                    />\n                  )}\n\n                <Controller\n                  name=\"model\"\n                  control={control}\n                  rules={{\n                    required: true,\n                  }}\n                  shouldUnregister={false}\n                  render={({ field }) => (\n                    <AIAgentBlock\n                      title={t(\"editor.ai-agent.label.model\")}\n                      required\n                    >\n                      <Select\n                        {...field}\n                        onClick={() => {\n                          track(\n                            ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                            ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                            {\n                              element: \"model\",\n                              parameter1: field.value,\n                              parameter5: data.agent.aiAgentID || \"-1\",\n                            },\n                          )\n                        }}\n                        onChange={(value) => {\n                          track(\n                            ILLA_MIXPANEL_EVENT_TYPE.CHANGE,\n                            ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                            {\n                              element: \"model\",\n                              parameter1: value,\n                              parameter5: data.agent.aiAgentID || \"-1\",\n                            },\n                          )\n                          if (\n                            isPremiumModel(value as AI_AGENT_MODEL) &&\n                            !canUseBillingFeature\n                          ) {\n                            upgradeModal({\n                              modalType: \"agent\",\n                              from: \"agent_edit_gpt4\",\n                            })\n                            return\n                          }\n                          field.onChange(value)\n                        }}\n                        colorScheme={\"techPurple\"}\n                        options={[\n                          ...freeModelList.map((model) => {\n                            return {\n                              label: (\n                                <div css={labelStyle}>\n                                  <span css={labelLogoStyle}>{model.logo}</span>\n                                  <span css={labelTextStyle}>{model.name}</span>\n                                </div>\n                              ),\n                              value: model.value,\n                            }\n                          }),\n                          ...premiumModelList.map((model) => {\n                            return {\n                              label: (\n                                <div css={labelStyle}>\n                                  <span css={labelLogoStyle}>{model.logo}</span>\n                                  <span css={labelTextStyle}>{model.name}</span>\n                                  {!canUseBillingFeature && (\n                                    <div css={premiumContainerStyle}>\n                                      <UpgradeIcon />\n                                      <div style={{ marginLeft: 4 }}>\n                                        Premium\n                                      </div>\n                                    </div>\n                                  )}\n                                </div>\n                              ),\n                              value: model.value,\n                            }\n                          }),\n                        ]}\n                      />\n                    </AIAgentBlock>\n                  )}\n                />\n                <Divider\n                  mt=\"8px\"\n                  text={t(\"editor.ai-agent.group.information\")}\n                  colorScheme=\"grayBlue\"\n                />\n                <Controller\n                  name=\"name\"\n                  control={control}\n                  rules={{\n                    required: t(\"editor.ai-agent.validation_blank.name\"),\n                  }}\n                  shouldUnregister={false}\n                  render={({ field }) => (\n                    <AIAgentBlock\n                      title={t(\"editor.ai-agent.label.name\")}\n                      required\n                      scrollId={SCROLL_ID.NAME}\n                    >\n                      <Input\n                        {...field}\n                        placeholder={t(\"editor.ai-agent.placeholder.name\")}\n                        colorScheme={\"techPurple\"}\n                        error={!!errors.name}\n                        maxLength={60}\n                        onChange={(value) => {\n                          field.onChange(value)\n                          setInRoomUsers(updateLocalName(value, inRoomUsers))\n                        }}\n                      />\n                      {errors.name?.message && (\n                        <ErrorText errorMessage={errors.name?.message} />\n                      )}\n                    </AIAgentBlock>\n                  )}\n                />\n\n                <Controller\n                  name=\"description\"\n                  control={control}\n                  rules={{\n                    required: t(\"editor.ai-agent.validation_blank.description\"),\n                    maxLength: {\n                      value: 160,\n                      message: t(\"editor.ai-agent.length_invalid.description\"),\n                    },\n                  }}\n                  shouldUnregister={false}\n                  render={({ field }) => (\n                    <AIAgentBlock\n                      title={t(\"editor.ai-agent.label.desc\")}\n                      subtitleTips={t(\"editor.ai-agent.generate-desc.tooltips\")}\n                      required\n                      scrollId={SCROLL_ID.DESCRIPTION}\n                      subtitle={\n                        <div\n                          css={descContainerStyle}\n                          onClick={async () => {\n                            track(\n                              ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                              ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                              {\n                                element: \"desc_generate\",\n                                parameter1: getValues(\"prompt\") ? true : false,\n                                parameter5: data.agent.aiAgentID || \"-1\",\n                              },\n                            )\n                            const currentTime = performance.now()\n                            if (!getValues(\"prompt\")) {\n                              message.error({\n                                content: t(\n                                  \"editor.ai-agent.generate-desc.blank\",\n                                ),\n                              })\n                              return\n                            }\n                            setGenerateDescLoading(true)\n                            try {\n                              const desc = await generateDescription(\n                                getValues(\"prompt\"),\n                              )\n                              track(\n                                ILLA_MIXPANEL_EVENT_TYPE.REQUEST,\n                                ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                                {\n                                  element: \"desc_generate\",\n                                  consume: performance.now() - currentTime,\n                                  parameter2: \"suc\",\n                                },\n                              )\n                              field.onChange(desc.data.payload)\n                            } catch (e) {\n                              track(\n                                ILLA_MIXPANEL_EVENT_TYPE.REQUEST,\n                                ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                                {\n                                  element: \"desc_generate\",\n                                  consume: performance.now() - currentTime,\n                                  parameter2: \"failed\",\n                                },\n                              )\n                              message.error({\n                                content: t(\n                                  \"editor.ai-agent.generate-desc.failed\",\n                                ),\n                              })\n                            } finally {\n                              setGenerateDescLoading(false)\n                            }\n                          }}\n                        >\n                          {generateDescLoading ? (\n                            <AILoading spin={true} size=\"12px\" />\n                          ) : (\n                            <AIIcon />\n                          )}\n                          <div css={descTextStyle}>\n                            {t(\"editor.ai-agent.generate-desc.button\")}\n                          </div>\n                        </div>\n                      }\n                    >\n                      <TextArea\n                        {...field}\n                        minH=\"120px\"\n                        showWordLimit={true}\n                        error={!!errors.description}\n                        maxLength={160}\n                        placeholder={t(\"editor.ai-agent.placeholder.desc\")}\n                        colorScheme={\"techPurple\"}\n                      />\n                      {errors.description?.message && (\n                        <ErrorText errorMessage={errors.description?.message} />\n                      )}\n                    </AIAgentBlock>\n                  )}\n                />\n                <Controller\n                  name=\"icon\"\n                  control={control}\n                  rules={{\n                    required: t(\"editor.ai-agent.validation_blank.icon\"),\n                  }}\n                  shouldUnregister={false}\n                  render={({ field }) => (\n                    <AIAgentBlock\n                      title={t(\"editor.ai-agent.label.icon\")}\n                      required\n                      scrollId={SCROLL_ID.ICON}\n                    >\n                      <MixpanelTrackProvider\n                        basicTrack={track}\n                        pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT}\n                      >\n                        <AvatarUpload\n                          onOk={async (file) => {\n                            let reader = new FileReader()\n                            reader.onload = () => {\n                              field.onChange(reader.result)\n                              setInRoomUsers(\n                                updateLocalIcon(\n                                  reader.result as string,\n                                  inRoomUsers,\n                                ),\n                              )\n                            }\n                            reader.readAsDataURL(file)\n                            return true\n                          }}\n                        >\n                          <div\n                            onClick={() => {\n                              track(\n                                ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                                ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                                {\n                                  element: \"avater\",\n                                },\n                              )\n                            }}\n                          >\n                            {!field.value ? (\n                              <div>\n                                <div css={uploadContainerStyle}>\n                                  <div css={uploadContentContainerStyle}>\n                                    <PlusIcon c={getColor(\"grayBlue\", \"03\")} />\n                                    <div css={uploadTextStyle}>\n                                      {t(\"editor.ai-agent.placeholder.icon\")}\n                                    </div>\n                                  </div>\n                                </div>\n                              </div>\n                            ) : (\n                              <Image\n                                src={field.value}\n                                css={uploadContentContainerStyle}\n                                width=\"100px\"\n                                height=\"100px\"\n                              />\n                            )}\n                          </div>\n                        </AvatarUpload>\n                      </MixpanelTrackProvider>\n                      {errors.icon?.message && (\n                        <ErrorText errorMessage={errors.icon?.message} />\n                      )}\n                    </AIAgentBlock>\n                  )}\n                />\n              </div>\n              {(isConnecting || isSubmitting) && (\n                <div css={leftLoadingCoverStyle} />\n              )}\n            </div>\n            <form onSubmit={handleSubmit(handleSubmitSave)}>\n              <div css={buttonContainerStyle}>\n                <Button\n                  flex=\"1\"\n                  size=\"large\"\n                  type=\"button\"\n                  loading={isConnecting}\n                  colorScheme=\"grayBlue\"\n                  leftIcon={isRunning ? <ResetIcon /> : <PlayFillIcon />}\n                  onClick={handleClickStart}\n                >\n                  {!isRunning\n                    ? t(\"editor.ai-agent.start\")\n                    : t(\"editor.ai-agent.restart\")}\n                </Button>\n                <Button\n                  id=\"save-button\"\n                  flex=\"1\"\n                  ml=\"8px\"\n                  onClick={handleVerifyOnSave}\n                  colorScheme={getColor(\"grayBlue\", \"02\")}\n                  size=\"large\"\n                  loading={isSubmitting}\n                >\n                  {t(\"editor.ai-agent.save\")}\n                </Button>\n              </div>\n            </form>\n          </div>\n          <Controller\n            name=\"agentType\"\n            control={control}\n            shouldUnregister={false}\n            render={({ field }) => (\n              <Controller\n                name=\"aiAgentID\"\n                control={control}\n                render={({ field: idField }) => (\n                  <Controller\n                    render={({ field: contributeField }) => (\n                      <div css={rightPanelContainerStyle}>\n                        <MixpanelTrackProvider\n                          basicTrack={track}\n                          pageName={\n                            ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT\n                          }\n                        >\n                          <PreviewChat\n                            showShareDialog={showShareAgentModalOnlyForShare(\n                              currentTeamInfo,\n                            )}\n                            showContributeDialog={showShareAgentModal(\n                              currentTeamInfo,\n                              currentTeamInfo.myRole,\n                              contributeField.value,\n                            )}\n                            showEditPanel={false}\n                            isRunning={isRunning}\n                            isConnecting={isConnecting}\n                            hasCreated={Boolean(idField.value)}\n                            isMobile={false}\n                            model={getValues(\"model\")}\n                            editState=\"EDIT\"\n                            agentType={field.value}\n                            chatMessages={chatMessages}\n                            generationMessage={generationMessage}\n                            isReceiving={isReceiving}\n                            blockInput={!isRunning || blockInputDirty}\n                            onSendMessage={(\n                              message,\n                              agentType: AI_AGENT_TYPE,\n                            ) => {\n                              track(\n                                ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                                ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                                {\n                                  element: \"send\",\n                                  parameter5: getValues(\"aiAgentID\") || \"-1\",\n                                },\n                              )\n                              sendMessage(\n                                {\n                                  threadID: message.threadID,\n                                  prompt: message.message,\n                                  variables: [],\n                                  actionID: getValues(\"aiAgentID\"),\n                                  modelConfig: getValues(\"modelConfig\"),\n                                  model: getValues(\"model\"),\n                                  agentType: getValues(\"agentType\"),\n                                } as ChatSendRequestPayload,\n                                TextSignal.RUN,\n                                agentType,\n                                \"chat\",\n                                true,\n                                message,\n                              )\n                            }}\n                            onCancelReceiving={() => {\n                              sendMessage(\n                                {} as ChatSendRequestPayload,\n                                TextSignal.STOP_ALL,\n                                field.value,\n                                \"stop_all\",\n                                false,\n                              )\n                              setIsReceiving(false)\n                            }}\n                            onShowShareDialog={() => {\n                              setDefaultShareTag(ShareAgentTab.SHARE_WITH_TEAM)\n                              setShareDialogVisible(true)\n                              track(\n                                ILLA_MIXPANEL_EVENT_TYPE.SHOW,\n                                ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                                {\n                                  element: \"share_modal\",\n                                  parameter5: data.agent.aiAgentID,\n                                },\n                              )\n                            }}\n                            onShowContributeDialog={() => {\n                              if (contributeField.value) {\n                                setDefaultShareTag(ShareAgentTab.TO_MARKETPLACE)\n                                setShareDialogVisible(true)\n                                track(\n                                  ILLA_MIXPANEL_EVENT_TYPE.SHOW,\n                                  ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                                  {\n                                    element: \"share_modal\",\n                                    parameter5: data.agent.aiAgentID,\n                                  },\n                                )\n                              } else {\n                                if (\n                                  !openShareAgentModal(\n                                    currentTeamInfo,\n                                    currentTeamInfo.myRole,\n                                    contributeField.value,\n                                  )\n                                ) {\n                                  upgradeModal({\n                                    modalType: \"upgrade\",\n                                    from: \"agent_edit_contribute\",\n                                  })\n                                  return\n                                }\n                                setContributedDialogVisible(true)\n                              }\n                            }}\n                            onClickCreateApp={handleClickCreateApp}\n                          />\n                        </MixpanelTrackProvider>\n                      </div>\n                    )}\n                    name=\"publishedToMarketplace\"\n                    control={control}\n                  />\n                )}\n              />\n            )}\n          />\n        </div>\n        <Controller\n          control={control}\n          name=\"aiAgentID\"\n          render={({ field: idField }) => (\n            <Controller\n              control={control}\n              name=\"name\"\n              render={({ field: nameField }) => (\n                <Controller\n                  control={control}\n                  name=\"publishedToMarketplace\"\n                  render={({ field }) => (\n                    <MixpanelTrackProvider\n                      basicTrack={track}\n                      pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT}\n                    >\n                      {shareDialogVisible && (\n                        <ShareAgentPC\n                          itemID={idField.value}\n                          onInvitedChange={(userList) => {\n                            const memberListInfo: MemberInfo[] = userList.map(\n                              (user) => {\n                                return {\n                                  ...user,\n                                  userID: \"\",\n                                  nickname: \"\",\n                                  avatar: \"\",\n                                  userStatus: USER_STATUS.PENDING,\n                                  permission: {},\n                                  createdAt: \"\",\n                                  updatedAt: \"\",\n                                }\n                              },\n                            )\n                            dispatch(\n                              teamActions.updateInvitedUserReducer(\n                                memberListInfo,\n                              ),\n                            )\n                          }}\n                          canUseBillingFeature={canUseUpgradeFeature(\n                            currentTeamInfo.myRole,\n                            getPlanUtils(currentTeamInfo),\n                            currentTeamInfo.totalTeamLicense\n                              .teamLicensePurchased,\n                            currentTeamInfo.totalTeamLicense.teamLicenseAllPaid,\n                          )}\n                          title={t(\n                            \"user_management.modal.social_media.default_text.agent\",\n                            {\n                              agentName: nameField.value,\n                            },\n                          )}\n                          redirectURL={`${getILLABuilderURL(\n                            window.customDomain,\n                          )}/${currentTeamInfo.identifier}/ai-agent/${\n                            idField.value\n                          }`}\n                          onClose={() => {\n                            setShareDialogVisible(false)\n                          }}\n                          canInvite={canManageInvite(\n                            currentTeamInfo.myRole,\n                            currentTeamInfo.permission\n                              .allowEditorManageTeamMember,\n                            currentTeamInfo.permission\n                              .allowViewerManageTeamMember,\n                          )}\n                          defaultTab={defaultShareTag}\n                          defaultInviteUserRole={USER_ROLE.VIEWER}\n                          teamID={currentTeamInfo.id}\n                          currentUserRole={currentTeamInfo.myRole}\n                          defaultBalance={\n                            currentTeamInfo.currentTeamLicense.balance\n                          }\n                          defaultAllowInviteLink={\n                            currentTeamInfo.permission.inviteLinkEnabled\n                          }\n                          onInviteLinkStateChange={(enableInviteLink) => {\n                            dispatch(\n                              teamActions.updateTeamMemberPermissionReducer({\n                                teamID: currentTeamInfo.id,\n                                newPermission: {\n                                  ...currentTeamInfo.permission,\n                                  inviteLinkEnabled: enableInviteLink,\n                                },\n                              }),\n                            )\n                          }}\n                          agentID={idField.value}\n                          defaultAgentContributed={field.value}\n                          onAgentContributed={(isAgentContributed) => {\n                            field.onChange(isAgentContributed)\n                            if (isAgentContributed) {\n                              const newUrl = new URL(\n                                getAgentPublicLink(idField.value),\n                              )\n                              newUrl.searchParams.set(\"token\", getAuthToken())\n                              window.open(newUrl, \"_blank\")\n                            }\n                          }}\n                          onCopyInviteLink={(link) => {\n                            track(\n                              ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                              ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                              {\n                                element: \"share_modal_copy_team\",\n                                parameter5: idField.value,\n                              },\n                            )\n                            copyToClipboard(\n                              t(\n                                \"user_management.modal.custom_copy_text_agent_invite\",\n                                {\n                                  userName: currentUserInfo.nickname,\n                                  teamName: currentTeamInfo.name,\n                                  inviteLink: link,\n                                },\n                              ),\n                            )\n                          }}\n                          onCopyAgentMarketLink={(link) => {\n                            track(\n                              ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                              ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                              {\n                                element: \"share_modal_link\",\n                                parameter5: idField.value,\n                              },\n                            )\n                            copyToClipboard(\n                              t(\n                                \"user_management.modal.contribute.default_text.agent\",\n                                {\n                                  agentName: nameField.value,\n                                  agentLink: link,\n                                },\n                              ),\n                            )\n                          }}\n                          userRoleForThisAgent={currentTeamInfo.myRole}\n                          ownerTeamID={currentTeamInfo.id}\n                          onBalanceChange={(balance) => {\n                            dispatch(\n                              teamActions.updateTeamMemberSubscribeReducer({\n                                teamID: currentTeamInfo.id,\n                                subscribeInfo: {\n                                  ...currentTeamInfo.currentTeamLicense,\n                                  balance: balance,\n                                },\n                              }),\n                            )\n                          }}\n                          teamPlan={getPlanUtils(currentTeamInfo)}\n                          onShare={(platform) => {\n                            track(\n                              ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                              ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n                              {\n                                element: \"share_modal_social_media\",\n                                parameter4: platform,\n                                parameter5: idField.value,\n                              },\n                            )\n                          }}\n                        />\n                      )}\n                      {contributedDialogVisible && (\n                        <ContributeAgentPC\n                          onContributed={(isAgentContributed) => {\n                            field.onChange(isAgentContributed)\n                            if (isAgentContributed) {\n                              const newUrl = new URL(\n                                getAgentPublicLink(idField.value),\n                              )\n                              newUrl.searchParams.set(\"token\", getAuthToken())\n                              window.open(newUrl, \"_blank\")\n                            }\n                          }}\n                          teamID={currentTeamInfo.id}\n                          onClose={() => {\n                            setContributedDialogVisible(false)\n                          }}\n                          productID={idField.value}\n                          productType={HASHTAG_REQUEST_TYPE.UNIT_TYPE_AI_AGENT}\n                          productContributed={field.value}\n                        />\n                      )}\n                    </MixpanelTrackProvider>\n                  )}\n                />\n              )}\n            />\n          )}\n        />\n        {isFullPageLoading && <FullPageLoading hasMask />}\n      </ChatContext.Provider>\n    </>\n  )\n}\n\nAIAgent.displayName = \"AIAgent\"\n"
  },
  {
    "path": "apps/builder/src/page/AI/AIAgent/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n} from \"@illa-public/mixpanel-utils\"\nimport { Agent } from \"@illa-public/public-types\"\nimport { FC, useEffect } from \"react\"\nimport {\n  Await,\n  redirect,\n  useBeforeUnload,\n  useLoaderData,\n} from \"react-router-dom\"\nimport { AIAgent } from \"@/page/AI/AIAgent/aiagent\"\nimport {\n  track,\n  trackPageDurationEnd,\n  trackPageDurationStart,\n} from \"@/utils/mixpanelHelper\"\n\nexport const AIAgentDefer: FC = () => {\n  const data = useLoaderData() as {\n    data: Promise<Agent>\n  }\n\n  useEffect(() => {\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.VISIT,\n      ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT,\n    )\n    trackPageDurationStart()\n    return () => {\n      trackPageDurationEnd(ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT)\n    }\n  }, [])\n\n  useBeforeUnload(() => {\n    trackPageDurationEnd(ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_EDIT)\n  })\n\n  return (\n    <Await resolve={data.data} errorElement={<>{redirect(\"404\")}</>}>\n      <AIAgent />\n    </Await>\n  )\n}\n\nAIAgentDefer.displayName = \"AIAgentRun\"\nexport default AIAgentDefer\n"
  },
  {
    "path": "apps/builder/src/page/AI/AIAgent/interface.ts",
    "content": "import { AI_AGENT_MODEL, AI_AGENT_TYPE, Agent } from \"@illa-public/public-types\"\n\nexport const AgentInitial: Agent = {\n  name: \"\",\n  teamIdentifier: \"\",\n  agentType: AI_AGENT_TYPE.CHAT,\n  model: AI_AGENT_MODEL.GPT_3_5,\n  variables: [{ key: \"\", value: \"\" }],\n  knowledge: [],\n  prompt: \"\",\n  modelConfig: {\n    stream: true,\n  },\n  icon: \"\",\n  description: \"\",\n  aiAgentID: \"\",\n  teamID: \"\",\n  teamIcon: \"\",\n  teamName: \"\",\n  publishedToMarketplace: false,\n  createdAt: \"\",\n  createdBy: \"\",\n  updatedBy: \"\",\n  updatedAt: \"\",\n  editedBy: [],\n}\n\nexport enum SCROLL_ID {\n  PROMPT = \"prompt\",\n  VARIABLES = \"variables\",\n  KNOWLEDGE = \"knowledge\",\n  NAME = \"name\",\n  DESCRIPTION = \"description\",\n  ICON = \"icon\",\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/AIAgent/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const aiAgentContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  width: 100%;\n  height: 100%;\n`\n\nexport const backTextStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  margin-left: 8px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 24px;\n`\n\nexport const leftPanelContainerStyle = css`\n  height: 100%;\n  width: 528px;\n  display: flex;\n  flex-direction: column;\n  box-shadow: 4px 0 16px 0 rgba(0, 0, 0, 0.06);\n  flex: none;\n  ${applyMobileStyle(css`\n    display: none;\n  `)}\n`\n\nexport const leftPanelCoverContainer = css`\n  display: flex;\n  flex-direction: column;\n  flex-grow: 1;\n  position: relative;\n  overflow-y: hidden;\n`\n\nexport const leftPanelContentContainerStyle = css`\n  display: flex;\n  width: 100%;\n  height: 100%;\n  overflow-y: auto;\n  flex-direction: column;\n  padding-bottom: 40px;\n`\n\nexport const leftLoadingCoverStyle = css`\n  position: absolute;\n  background: ${getColor(\"white\", \"03\")};\n  height: 100%;\n  width: 100%;\n  z-index: 10;\n`\n\nexport const buttonContainerStyle = css`\n  padding: 24px;\n  border-top: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const leftPanelTitleTextStyle = css`\n  cursor: pointer;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 18px;\n  font-style: normal;\n  font-weight: 600;\n  line-height: 24px;\n`\n\nexport const rightPanelContainerStyle = css`\n  height: 100%;\n  width: 100%;\n  display: flex;\n  flex-grow: 1;\n  overflow-x: hidden;\n  flex-direction: column;\n`\n\nexport const labelStyle = css`\n  display: flex;\n  width: 100%;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const labelLogoStyle = css`\n  font-size: 16px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 16px;\n  height: 16px;\n\n  & svg {\n    height: 100%;\n    width: 100%;\n  }\n`\n\nexport const labelTextStyle = css`\n  margin-left: 8px;\n  flex-grow: 1;\n  flex-shrink: 1;\n  text-overflow: ellipsis;\n  overflow: hidden;\n  white-space: nowrap;\n`\n\nexport const premiumContainerStyle = css`\n  align-items: center;\n  display: inline-flex;\n  margin-left: 8px;\n  box-sizing: border-box;\n  border-radius: 4px;\n  padding: 1px 7px;\n  color: ${getColor(\"techPurple\", \"03\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 22px;\n  text-transform: capitalize;\n  background: ${getColor(\"techPurple\", \"08\")};\n`\n\nexport const uploadContainerStyle = css`\n  cursor: pointer;\n  background: ${getColor(\"grayBlue\", \"09\")};\n  width: 100px;\n  height: 100px;\n  border-radius: 4px;\n  display: flex;\n  padding: 32px 28px 22px 29px;\n  justify-content: center;\n  align-items: center;\n`\n\nexport const uploadContentContainerStyle = css`\n  color: ${getColor(\"grayBlue\", \"04\")};\n  display: inline-flex;\n  flex-direction: column;\n  align-items: center;\n`\n\nexport const uploadTextStyle = css`\n  text-align: center;\n  margin-top: 8px;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 22px;\n`\n\nexport const descContainerStyle = css`\n  cursor: pointer;\n  display: inline-flex;\n  align-items: center;\n`\n\nexport const descTextStyle = css`\n  margin-left: 4px;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 22px;\n  background: linear-gradient(90deg, #853dff 0%, #e13eff 100%);\n  background-clip: text;\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n`\n\nexport const temperatureContainerStyle = css`\n  display: flex;\n  align-items: center;\n`\n\nexport const temperatureStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  text-align: center;\n  font-size: 14px;\n  font-style: normal;\n  margin-left: 16px;\n  width: 34px;\n  font-weight: 400;\n  line-height: 22px;\n  text-transform: capitalize;\n`\n\nexport const docTextContainerStyle = css`\n  text-decoration: none;\n`\nexport const docTextStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 4px;\n`\n\nexport const leftPanelHeaderStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 24px 24px 16px 24px;\n  text-decoration: none;\n`\n\nexport const advancedSettingHeaderStyle = css`\n  display: flex;\n  width: 100%;\n  align-items: center;\n  justify-content: space-between;\n  margin-top: 8px;\n  padding: 8px 24px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 14px;\n  font-weight: 600;\n  line-height: 22px;\n`\n\nexport const advancedSettingStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const promptContainerStyle = css`\n  width: 100%;\n  height: 100%;\n`\nexport const codeEditorErrorStyle = (isError: boolean) => {\n  let style\n  if (isError) {\n    style = css`\n      .cm-editor,\n      .cm-editor:hover,\n      .cm-editor.cm-focused {\n        border-color: ${getColor(\"red\", \"03\")}!important;\n      }\n    `\n  }\n  return style\n}\n\nexport const advancedDivideStyle = css`\n  margin-top: 8px;\n  padding: 0 24px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/AIAgent/utils.ts",
    "content": "import { Agent } from \"@illa-public/public-types\"\n\nexport const agentData2JSONReport = (agent: Agent) => {\n  try {\n    const {\n      agentType,\n      modelConfig: {},\n      model,\n    } = agent\n\n    return JSON.stringify({\n      mode: agentType,\n      model,\n    })\n  } catch (e) {\n    return JSON.stringify({})\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/AIAgentRun/AIAgentRunMobile/index.tsx",
    "content": "import { Avatar } from \"@illa-public/avatar\"\nimport { CodeEditor } from \"@illa-public/code-editor\"\nimport { ShareAgentMobile } from \"@illa-public/invite-modal\"\nimport {\n  MarketAIAgent,\n  getAIAgentMarketplaceInfo,\n  getLLM,\n  isPremiumModel,\n} from \"@illa-public/market-agent\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport {\n  AI_AGENT_TYPE,\n  Agent,\n  MemberInfo,\n  USER_ROLE,\n  USER_STATUS,\n} from \"@illa-public/public-types\"\nimport { RecordEditor } from \"@illa-public/record-editor\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport {\n  getCurrentTeamInfo,\n  getCurrentUser,\n  getPlanUtils,\n  teamActions,\n} from \"@illa-public/user-data\"\nimport {\n  ACTION_MANAGE,\n  ATTRIBUTE_GROUP,\n  canManage,\n  canManageInvite,\n  canUseUpgradeFeature,\n  openShareAgentModal,\n} from \"@illa-public/user-role-utils\"\nimport {\n  formatNumForAgent,\n  getAgentPublicLink,\n  getAuthToken,\n  getILLABuilderURL,\n  getILLACloudURL,\n} from \"@illa-public/utils\"\nimport { motion } from \"framer-motion\"\nimport { FC, useEffect, useState } from \"react\"\nimport { Helmet } from \"react-helmet-async\"\nimport { Controller, useForm, useFormState } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useAsyncValue, useParams, useSearchParams } from \"react-router-dom\"\nimport { v4 } from \"uuid\"\nimport {\n  Button,\n  DependencyIcon,\n  ForkIcon,\n  LoadingIcon,\n  PlayFillIcon,\n  PreviousIcon,\n  RadioGroup,\n  ResetIcon,\n  StarFillIcon,\n  StarOutlineIcon,\n  getColor,\n  useMessage,\n} from \"@illa-design/react\"\nimport { TextSignal } from \"@/api/ws/textSignal\"\nimport AIAgentBlock from \"@/page/AI/components/AIAgentBlock\"\nimport { PreviewChat } from \"@/page/AI/components/PreviewChat\"\nimport { ChatSendRequestPayload } from \"@/page/AI/components/PreviewChat/interface\"\nimport { useAgentConnect } from \"@/page/AI/components/ws/useAgentConnect\"\nimport { CollaboratorsInfo } from \"@/redux/currentApp/collaborators/collaboratorsState\"\nimport { forkAIAgentToTeam, starAIAgent, unstarAIAgent } from \"@/services/agent\"\nimport { copyToClipboard } from \"@/utils/copyToClipboard\"\nimport { track } from \"@/utils/mixpanelHelper\"\nimport { ChatContext } from \"../../components/ChatContext\"\nimport {\n  agentContentContainerStyle,\n  agentControlContainerStyle,\n  agentIconStyle,\n  agentMarketContainerStyle,\n  agentMarketResultStyle,\n  agentNameStyle,\n  agentTeamNameStyle,\n  aiAgentContainerStyle,\n  buttonContainerStyle,\n  configContainerStyle,\n  dividerStyle,\n  headerContainerStyle,\n  headerInfoStyle,\n  labelLogoStyle,\n  labelStyle,\n  lineStyle,\n  menuContainerStyle,\n  previewChatContainer,\n  readOnlyTextStyle,\n  shareContainerStyle,\n  tabContainerStyle,\n  tabStyle,\n  tabsContainerStyle,\n} from \"./style\"\n\nexport const AIAgentRunMobile: FC = () => {\n  const { agent, marketplace } = useAsyncValue() as {\n    agent: Agent\n    marketplace: MarketAIAgent | undefined\n  }\n\n  const [currentMarketplaceInfo, setCurrentMarketplaceInfo] = useState<\n    MarketAIAgent | undefined\n  >(marketplace)\n\n  const { control, handleSubmit, getValues, reset } = useForm<Agent>({\n    mode: \"onSubmit\",\n    defaultValues: agent,\n  })\n\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)!!\n\n  const { isDirty, isValid } = useFormState({\n    control,\n  })\n\n  const message = useMessage()\n  const upgradeModal = useUpgradeModal()\n\n  // page state\n  const [isRunning, setIsRunning] = useState(false)\n  const [isConnecting, setIsConnecting] = useState(false)\n  const [shareDialogVisible, setShareDialogVisible] = useState(false)\n  const [starState, setStarState] = useState(\n    currentMarketplaceInfo?.marketplace?.isStarredByCurrentUser ?? false,\n  )\n  const [forkLoading, setForkLoading] = useState(false)\n  // data state\n  const [inRoomUsers, setInRoomUsers] = useState<CollaboratorsInfo[]>([])\n  const [isReceiving, setIsReceiving] = useState(false)\n  const currentUserInfo = useSelector(getCurrentUser)\n  const [starNum, setStarNum] = useState(\n    currentMarketplaceInfo?.marketplace.numStars ?? 0,\n  )\n\n  const { ownerTeamIdentifier, agentID } = useParams()\n  const [searchParams] = useSearchParams()\n\n  const { t } = useTranslation()\n\n  const [currentSelectTab, setCurrentSelectTab] = useState<\"config\" | \"run\">(\n    \"config\",\n  )\n\n  // premium dialog\n  const canUseBillingFeature = canUseUpgradeFeature(\n    currentTeamInfo?.myRole,\n    getPlanUtils(currentTeamInfo),\n    currentTeamInfo?.totalTeamLicense?.teamLicensePurchased,\n    currentTeamInfo?.totalTeamLicense?.teamLicenseAllPaid,\n  )\n\n  const canShowInviteButton =\n    canUseBillingFeature || getValues(\"publishedToMarketplace\")\n\n  const dispatch = useDispatch()\n\n  const { sendMessage, generationMessage, chatMessages, reconnect, connect } =\n    useAgentConnect({\n      onSendClean: () => {\n        sendMessage(\n          {} as ChatSendRequestPayload,\n          TextSignal.CLEAN,\n          getValues(\"agentType\"),\n          \"clean\",\n          false,\n        )\n      },\n      onStartRunning: () => {},\n      onConnecting: (isConnecting) => {\n        setIsConnecting(isConnecting)\n      },\n      onReceiving: (isReceiving) => {\n        setIsReceiving(isReceiving)\n      },\n      onRunning: (isRunning: boolean) => {\n        setIsRunning(isRunning)\n      },\n      onSendPrompt(): void {\n        sendMessage(\n          {\n            threadID: v4(),\n            prompt: getValues(\"prompt\"),\n            variables: getValues(\"variables\"),\n            modelConfig: getValues(\"modelConfig\"),\n            model: getValues(\"model\"),\n            actionID: getValues(\"aiAgentID\"),\n            agentType: getValues(\"agentType\"),\n          } as ChatSendRequestPayload,\n          TextSignal.RUN,\n          getValues(\"agentType\"),\n          \"chat\",\n          false,\n        )\n      },\n      onUpdateRoomUsers(roomUsers: CollaboratorsInfo[]): void {\n        setInRoomUsers(roomUsers)\n      },\n    })\n\n  const dialog = (\n    <Controller\n      control={control}\n      name=\"publishedToMarketplace\"\n      render={({ field }) => (\n        <MixpanelTrackProvider\n          basicTrack={track}\n          pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN}\n        >\n          {shareDialogVisible && (\n            <ShareAgentMobile\n              canUseBillingFeature={canUseBillingFeature}\n              itemID={agent.aiAgentID}\n              title={t(\n                \"user_management.modal.social_media.default_text.agent\",\n                {\n                  agentName: agent.name,\n                },\n              )}\n              redirectURL={`${getILLABuilderURL(\n                window.customDomain,\n              )}/${ownerTeamIdentifier}/ai-agent/${\n                agent.aiAgentID\n              }/run?myTeamIdentifier=${searchParams.get(\"myTeamIdentifier\")}`}\n              onClose={() => {\n                setShareDialogVisible(false)\n              }}\n              canInvite={canManageInvite(\n                currentTeamInfo.myRole,\n                currentTeamInfo.permission.allowEditorManageTeamMember,\n                currentTeamInfo.permission.allowViewerManageTeamMember,\n              )}\n              defaultInviteUserRole={USER_ROLE.VIEWER}\n              teamID={currentTeamInfo.id}\n              currentUserRole={currentTeamInfo.myRole}\n              defaultBalance={currentTeamInfo.currentTeamLicense.balance}\n              defaultAllowInviteLink={\n                currentTeamInfo.permission.inviteLinkEnabled\n              }\n              onInviteLinkStateChange={(enableInviteLink) => {\n                dispatch(\n                  teamActions.updateTeamMemberPermissionReducer({\n                    teamID: currentTeamInfo.id,\n                    newPermission: {\n                      ...currentTeamInfo.permission,\n                      inviteLinkEnabled: enableInviteLink,\n                    },\n                  }),\n                )\n              }}\n              agentID={agent.aiAgentID}\n              defaultAgentContributed={field.value}\n              onAgentContributed={async (isAgentContributed) => {\n                if (isAgentContributed) {\n                  const resp = await getAIAgentMarketplaceInfo(agent.aiAgentID)\n                  setCurrentMarketplaceInfo(resp.data)\n                  const newUrl = new URL(\n                    getAgentPublicLink(resp.data.aiAgent.aiAgentID),\n                  )\n                  newUrl.searchParams.set(\"token\", getAuthToken())\n                  window.open(newUrl, \"_blank\")\n                } else {\n                  setCurrentMarketplaceInfo(undefined)\n                }\n                field.onChange(isAgentContributed)\n              }}\n              onCopyInviteLink={(link: string) => {\n                track(\n                  ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                  ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                  {\n                    element: \"share_modal_copy_team\",\n                    parameter5: agent.aiAgentID,\n                  },\n                )\n                copyToClipboard(\n                  t(\"user_management.modal.custom_copy_text_agent_invite\", {\n                    userName: currentUserInfo.nickname,\n                    teamName: currentTeamInfo.name,\n                    inviteLink: link,\n                  }),\n                )\n              }}\n              onCopyAgentMarketLink={(link: string) => {\n                track(\n                  ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                  ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                  {\n                    element: \"share_modal_link\",\n                    parameter5: agent.aiAgentID,\n                  },\n                )\n                copyToClipboard(\n                  t(\"user_management.modal.contribute.default_text.agent\", {\n                    agentName: agent.name,\n                    agentLink: link,\n                  }),\n                )\n              }}\n              userRoleForThisAgent={\n                currentTeamInfo.id === agent.teamID\n                  ? currentTeamInfo.myRole\n                  : USER_ROLE.GUEST\n              }\n              ownerTeamID={agent.teamID}\n              onBalanceChange={(balance) => {\n                dispatch(\n                  teamActions.updateTeamMemberSubscribeReducer({\n                    teamID: currentTeamInfo.id,\n                    subscribeInfo: {\n                      ...currentTeamInfo.currentTeamLicense,\n                      balance: balance,\n                    },\n                  }),\n                )\n              }}\n              teamPlan={getPlanUtils(currentTeamInfo)}\n              onShare={(platform) => {\n                track(\n                  ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                  ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                  {\n                    element: \"share_modal_social_media\",\n                    parameter4: platform,\n                    parameter5: agent.aiAgentID,\n                  },\n                )\n              }}\n              onInvitedChange={(userList) => {\n                const memberListInfo: MemberInfo[] = userList.map((user) => {\n                  return {\n                    ...user,\n                    userID: \"\",\n                    nickname: \"\",\n                    avatar: \"\",\n                    userStatus: USER_STATUS.PENDING,\n                    permission: {},\n                    createdAt: \"\",\n                    updatedAt: \"\",\n                  }\n                })\n                dispatch(teamActions.updateInvitedUserReducer(memberListInfo))\n              }}\n            />\n          )}\n        </MixpanelTrackProvider>\n      )}\n    />\n  )\n\n  const configTab = (\n    <div css={configContainerStyle}>\n      <div css={agentControlContainerStyle}>\n        <Controller\n          name=\"agentType\"\n          control={control}\n          shouldUnregister={false}\n          render={({ field }) => (\n            <AIAgentBlock\n              title={t(\"editor.ai-agent.label.mode\")}\n              tips={t(\"editor.ai-agent.tips.mode\")}\n            >\n              <RadioGroup\n                value={field.value}\n                colorScheme={getColor(\"grayBlue\", \"02\")}\n                type=\"button\"\n                w=\"100%\"\n                disp=\"flex\"\n                forceEqualWidth={true}\n                options={[\n                  {\n                    value: AI_AGENT_TYPE.CHAT,\n                    label: t(\"editor.ai-agent.option.mode.chat\"),\n                  },\n                  {\n                    value: AI_AGENT_TYPE.TEXT_GENERATION,\n                    label: t(\"editor.ai-agent.option.mode.text\"),\n                  },\n                ]}\n                onChange={(value) => {\n                  if (isReceiving || isConnecting) {\n                    message.info({\n                      content: t(\"editor.ai-agent.message.generating\"),\n                    })\n                    return\n                  }\n                  track(\n                    ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                    ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                    {\n                      element: \"mode_radio_button\",\n                      parameter1: value,\n                      parameter5: agent.aiAgentID,\n                    },\n                  )\n                  field.onChange(value)\n                }}\n              />\n            </AIAgentBlock>\n          )}\n        />\n        <Controller\n          name=\"prompt\"\n          control={control}\n          shouldUnregister={false}\n          render={({ field: promptField }) => (\n            <Controller\n              name=\"variables\"\n              control={control}\n              render={({ field: variables }) => (\n                <AIAgentBlock title={\"Prompt\"}>\n                  <CodeEditor\n                    {...promptField}\n                    editable={false}\n                    completionOptions={variables.value}\n                  />\n                </AIAgentBlock>\n              )}\n            />\n          )}\n        />\n        <Controller\n          name=\"variables\"\n          control={control}\n          rules={{\n            validate: (value) =>\n              value.every((param) => param.key !== \"\" && param.value !== \"\") ||\n              (value.length === 1 &&\n                value[0].key === \"\" &&\n                value[0].value === \"\"),\n          }}\n          shouldUnregister={false}\n          render={({ field }) =>\n            field.value.length > 0 ? (\n              <AIAgentBlock title={t(\"editor.ai-agent.label.variable\")}>\n                <RecordEditor\n                  fillOnly\n                  records={field.value}\n                  onChangeKey={(index, key) => {\n                    const newVariables = [...field.value]\n                    newVariables[index].key = key\n                    field.onChange(newVariables)\n                  }}\n                  onChangeValue={(index, _, value) => {\n                    const newVariables = [...field.value]\n                    newVariables[index].value = value\n                    field.onChange(newVariables)\n                  }}\n                  onAdd={() => {}}\n                  onDelete={() => {}}\n                  label={\"\"}\n                />\n              </AIAgentBlock>\n            ) : (\n              <></>\n            )\n          }\n        />\n        <Controller\n          name=\"model\"\n          control={control}\n          render={({ field }) => (\n            <AIAgentBlock title={t(\"editor.ai-agent.label.model\")}>\n              <div css={labelStyle}>\n                <span css={labelLogoStyle}>{getLLM(field.value)?.logo}</span>\n                <span css={readOnlyTextStyle}>{getLLM(field.value)?.name}</span>\n              </div>\n            </AIAgentBlock>\n          )}\n        />\n      </div>\n      <form\n        onSubmit={handleSubmit(async (data) => {\n          if (isPremiumModel(data.model) && !canUseBillingFeature) {\n            upgradeModal({\n              modalType: \"agent\",\n              from: \"agent_run_gpt4\",\n            })\n            return\n          }\n          reset(data)\n          setCurrentSelectTab(\"run\")\n          track(\n            ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n            ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n            {\n              element: isRunning ? \"restart\" : \"start\",\n              parameter1: data.agentType === 1 ? \"chat\" : \"text\",\n              parameter5: agent.aiAgentID,\n            },\n          )\n          isRunning\n            ? await reconnect(data.aiAgentID, data.agentType)\n            : await connect(data.aiAgentID, data.agentType)\n        })}\n      >\n        <div css={buttonContainerStyle}>\n          <Button\n            flex=\"1\"\n            disabled={!isValid}\n            size=\"large\"\n            loading={isConnecting}\n            ml=\"8px\"\n            colorScheme={getColor(\"grayBlue\", \"02\")}\n            leftIcon={isRunning ? <ResetIcon /> : <PlayFillIcon />}\n          >\n            {!isRunning\n              ? t(\"editor.ai-agent.start\")\n              : t(\"editor.ai-agent.restart\")}\n          </Button>\n        </div>\n      </form>\n    </div>\n  )\n\n  const previewChatTab = (\n    <Controller\n      name=\"agentType\"\n      control={control}\n      shouldUnregister={false}\n      render={({ field }) => (\n        <div css={previewChatContainer}>\n          <PreviewChat\n            editState=\"RUN\"\n            showEditPanel={false}\n            showShareDialog={false}\n            showContributeDialog={false}\n            isConnecting={isConnecting}\n            isRunning={isRunning}\n            hasCreated={true}\n            isMobile={true}\n            agentType={field.value}\n            model={getValues(\"model\")}\n            chatMessages={chatMessages}\n            generationMessage={generationMessage}\n            isReceiving={isReceiving}\n            blockInput={!isRunning || isDirty}\n            onSendMessage={(message, agentType: AI_AGENT_TYPE) => {\n              track(\n                ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                {\n                  element: \"send\",\n                  parameter5: agent.aiAgentID,\n                },\n              )\n              sendMessage(\n                {\n                  threadID: message.threadID,\n                  prompt: message.message,\n                  actionID: getValues(\"aiAgentID\"),\n                  variables: [],\n                  modelConfig: getValues(\"modelConfig\"),\n                  model: getValues(\"model\"),\n                  agentType: getValues(\"agentType\"),\n                } as ChatSendRequestPayload,\n                TextSignal.RUN,\n                agentType,\n                \"chat\",\n                true,\n                message,\n              )\n            }}\n            onCancelReceiving={() => {\n              sendMessage(\n                {} as ChatSendRequestPayload,\n                TextSignal.STOP_ALL,\n                field.value,\n                \"stop_all\",\n                false,\n              )\n              setIsReceiving(false)\n            }}\n          />\n        </div>\n      )}\n    />\n  )\n\n  useEffect(() => {\n    canShowInviteButton &&\n      track(\n        ILLA_MIXPANEL_EVENT_TYPE.SHOW,\n        ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n        {\n          element: \"invite_entry\",\n        },\n      )\n  }, [canShowInviteButton])\n\n  return (\n    <>\n      <Helmet>\n        <title>{agent.name}</title>\n      </Helmet>\n      <ChatContext.Provider value={{ inRoomUsers }}>\n        <div css={aiAgentContainerStyle}>\n          <div css={headerContainerStyle}>\n            <Controller\n              name=\"publishedToMarketplace\"\n              control={control}\n              render={({ field }) => {\n                return (\n                  <div css={menuContainerStyle}>\n                    <div\n                      css={shareContainerStyle}\n                      onClick={() => {\n                        const cloudUrl = getILLACloudURL(window.customDomain)\n                        if (document.referrer.includes(cloudUrl)) {\n                          return (location.href = `${cloudUrl}/workspace/${ownerTeamIdentifier}/ai-agents`)\n                        }\n                        if (\n                          document.referrer.includes(\n                            import.meta.env.ILLA_MARKET_URL,\n                          ) &&\n                          agentID\n                        ) {\n                          return (location.href = `${\n                            import.meta.env.ILLA_MARKET_URL\n                          }/ai-agent/${agentID}/detail`)\n                        }\n                        return (location.href = cloudUrl)\n                      }}\n                    >\n                      <PreviousIcon fs=\"24px\" />\n                    </div>\n                    <div\n                      style={{\n                        flexGrow: 1,\n                      }}\n                    />\n                    {field.value &&\n                      canManage(\n                        currentTeamInfo.myRole,\n                        ATTRIBUTE_GROUP.AI_AGENT,\n                        getPlanUtils(currentTeamInfo),\n                        ACTION_MANAGE.FORK_AI_AGENT,\n                      ) && (\n                        <div\n                          css={shareContainerStyle}\n                          onClick={async () => {\n                            track(\n                              ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                              ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                              {\n                                element: \"fork\",\n                                parameter5: agent.aiAgentID,\n                              },\n                            )\n                            setForkLoading(true)\n                            try {\n                              await forkAIAgentToTeam(agent.aiAgentID)\n                              message.success({\n                                content: t(\"dashboard.message.mobile-fork-suc\"),\n                              })\n                            } catch (e) {\n                              message.error({\n                                content: t(\"dashboard.message.fork-failed\"),\n                              })\n                            } finally {\n                              setForkLoading(false)\n                            }\n                          }}\n                        >\n                          {forkLoading ? (\n                            <LoadingIcon spin={true} fs=\"24px\" />\n                          ) : (\n                            <ForkIcon fs=\"24px\" />\n                          )}\n                        </div>\n                      )}\n                    {field.value && (\n                      <div\n                        css={shareContainerStyle}\n                        onClick={async () => {\n                          track(\n                            ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                            ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                            {\n                              element: \"star\",\n                              parameter5: agent.aiAgentID,\n                            },\n                          )\n                          const currentState = starState\n                          setStarState(!starState)\n                          try {\n                            if (starState) {\n                              await unstarAIAgent(agent.aiAgentID)\n                              if (starNum > 0) {\n                                setStarNum(starNum - 1)\n                              }\n                            } else {\n                              await starAIAgent(agent.aiAgentID)\n                              setStarNum(starNum + 1)\n                            }\n                          } catch (e) {\n                            setStarState(currentState)\n                            message.error({\n                              content: t(\"dashboard.message.star-failed\"),\n                            })\n                          }\n                        }}\n                      >\n                        {starState ? (\n                          <StarFillIcon c=\"#FFBB38\" fs=\"24px\" />\n                        ) : (\n                          <StarOutlineIcon fs=\"24px\" />\n                        )}\n                      </div>\n                    )}\n                    {(canUseBillingFeature || field.value) && (\n                      <div\n                        css={shareContainerStyle}\n                        onClick={() => {\n                          track(\n                            ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                            ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                            {\n                              element: \"invite_entry\",\n                              parameter5: agent.aiAgentID,\n                            },\n                          )\n                          if (\n                            !openShareAgentModal(\n                              currentTeamInfo,\n                              currentTeamInfo.id === agent.teamID\n                                ? currentTeamInfo.myRole\n                                : USER_ROLE.GUEST,\n                              field.value,\n                            )\n                          ) {\n                            upgradeModal({\n                              modalType: \"upgrade\",\n                              from: \"agent_run_share\",\n                            })\n                            return\n                          }\n                          setShareDialogVisible(true)\n                          track(\n                            ILLA_MIXPANEL_EVENT_TYPE.SHOW,\n                            ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                            {\n                              element: \"share_modal\",\n                              parameter5: agent.aiAgentID,\n                            },\n                          )\n                        }}\n                      >\n                        <DependencyIcon fs=\"24px\" />\n                      </div>\n                    )}\n                  </div>\n                )\n              }}\n            />\n            <div css={headerInfoStyle}>\n              <Controller\n                name=\"icon\"\n                control={control}\n                render={({ field }) => (\n                  <Avatar css={agentIconStyle} avatarUrl={field.value} />\n                )}\n              />\n              <div css={agentContentContainerStyle}>\n                <Controller\n                  name=\"name\"\n                  control={control}\n                  render={({ field }) => (\n                    <div css={agentNameStyle}>{field.value}</div>\n                  )}\n                />\n                <div css={agentMarketContainerStyle}>\n                  <div css={agentTeamNameStyle}>{agent.teamName}</div>\n                  {agent.publishedToMarketplace && (\n                    <div css={agentMarketResultStyle}>\n                      {starNum > 0 && (\n                        <span>\n                          {t(\"marketplace.star\")}\n                          {formatNumForAgent(starNum)}\n                        </span>\n                      )}\n                      {starNum > 0 &&\n                        (currentMarketplaceInfo?.marketplace.numForks ?? 0) >\n                          0 && <span>&nbsp;·&nbsp;</span>}\n\n                      {(currentMarketplaceInfo?.marketplace.numForks ?? 0) >\n                        0 && (\n                        <span>\n                          {t(\"marketplace.fork\")}\n                          {formatNumForAgent(\n                            currentMarketplaceInfo?.marketplace.numForks ?? 0,\n                          )}\n                        </span>\n                      )}\n                    </div>\n                  )}\n                </div>\n              </div>\n            </div>\n            <Controller\n              name=\"agentType\"\n              control={control}\n              render={({ field }) => (\n                <div css={tabsContainerStyle}>\n                  <div\n                    css={tabContainerStyle}\n                    onClick={() => {\n                      setCurrentSelectTab(\"config\")\n                    }}\n                  >\n                    <div css={tabStyle}>{t(\"editor.ai-agent.tab.prompt\")}</div>\n                    {currentSelectTab === \"config\" && (\n                      <motion.div css={lineStyle} layoutId=\"underline\" />\n                    )}\n                  </div>\n                  <div css={dividerStyle} />\n                  <div\n                    css={tabContainerStyle}\n                    onClick={() => {\n                      if (!isRunning || isDirty) {\n                        message.info({\n                          content: t(\"editor.ai-agent.message.click-start\"),\n                        })\n                        return\n                      }\n                      setCurrentSelectTab(\"run\")\n                    }}\n                  >\n                    <div css={tabStyle}>\n                      {field.value === AI_AGENT_TYPE.CHAT\n                        ? t(\"editor.ai-agent.tab.chat\")\n                        : t(\"editor.ai-agent.tab.text\")}\n                    </div>\n                    {currentSelectTab === \"run\" && (\n                      <motion.div css={lineStyle} layoutId=\"underline\" />\n                    )}\n                  </div>\n                </div>\n              )}\n            />\n          </div>\n          {currentSelectTab === \"run\" && previewChatTab}\n          {currentSelectTab === \"config\" && configTab}\n          {dialog}\n        </div>\n      </ChatContext.Provider>\n    </>\n  )\n}\n\nexport default AIAgentRunMobile\n\nAIAgentRunMobile.displayName = \"AIAgentRunMobile\"\n"
  },
  {
    "path": "apps/builder/src/page/AI/AIAgentRun/AIAgentRunMobile/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const aiAgentContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  height: 100%;\n`\n\nexport const buttonContainerStyle = css`\n  padding: 24px;\n  border-top: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const readOnlyTextStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 22px;\n`\n\nexport const labelLogoStyle = css`\n  font-size: 16px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 16px;\n  height: 16px;\n\n  & svg {\n    height: 100%;\n    width: 100%;\n  }\n`\n\nexport const labelStyle = css`\n  display: flex;\n  width: 100%;\n  gap: 4px;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const headerInfoStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  padding-top: 12px;\n  padding-left: 20px;\n  padding-right: 20px;\n`\n\nexport const headerContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.08);\n`\n\nexport const previewChatContainer = css`\n  height: 100%;\n  width: 100%;\n  overflow: hidden;\n`\n\nexport const agentIconStyle = css`\n  width: 40px;\n  margin-right: 12px;\n  height: 40px;\n  border-radius: 8px;\n`\nexport const shareContainerStyle = css`\n  display: inline-flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  margin-left: 6px;\n  width: 40px;\n  height: 40px;\n  flex-shrink: 0;\n`\n\nexport const menuContainerStyle = css`\n  display: flex;\n  padding-right: 16px;\n  padding-top: 12px;\n  align-items: center;\n  padding-bottom: 12px;\n  flex-direction: row;\n`\n\nexport const agentContentContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  overflow-x: hidden;\n  flex-grow: 1;\n  flex-shrink: 1;\n`\n\nexport const agentMarketContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  margin-top: 4px;\n`\n\nexport const agentTeamNameStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 12px;\n  font-style: normal;\n  overflow: hidden;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  flex-shrink: 1;\n  font-weight: 400;\n  line-height: 15px;\n`\n\nexport const agentNameStyle = css`\n  font-size: 14px;\n  text-overflow: ellipsis;\n  overflow-x: hidden;\n  white-space: nowrap;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 17px;\n`\n\nexport const agentMarketResultStyle = css`\n  color: ${getColor(\"grayBlue\", \"03\")};\n  font-size: 12px;\n  margin-left: 8px;\n  white-space: nowrap;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 16px;\n  overflow: hidden;\n  flex-shrink: 0;\n  text-overflow: ellipsis;\n`\n\nexport const agentControlContainerStyle = css`\n  display: flex;\n  overflow-y: auto;\n  flex-direction: column;\n  flex-grow: 1;\n  flex-shrink: 1;\n  padding-bottom: 40px;\n`\n\nexport const configContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  flex-grow: 1;\n  overflow: hidden;\n`\n\nexport const tabsContainerStyle = css`\n  display: flex;\n  justify-content: center;\n  margin-top: 12px;\n  flex-direction: row;\n`\n\nexport const dividerStyle = css`\n  width: 65px;\n  flex-shrink: 1;\n`\n\nexport const tabContainerStyle = css`\n  display: inline-flex;\n  padding-top: 5px;\n  flex-direction: column;\n`\n\nexport const tabStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 22px;\n  text-transform: capitalize;\n`\n\nexport const lineStyle = css`\n  width: 100%;\n  margin-top: 3px;\n  height: 2px;\n  background: ${getColor(\"grayBlue\", \"02\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/AIAgentRun/AIAgentRunPC/index.tsx",
    "content": "import { Avatar } from \"@illa-public/avatar\"\nimport { CodeEditor } from \"@illa-public/code-editor\"\nimport IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { ShareAgentPC } from \"@illa-public/invite-modal\"\nimport {\n  MarketAIAgent,\n  getAIAgentMarketplaceInfo,\n  getLLM,\n  isPremiumModel,\n} from \"@illa-public/market-agent\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport {\n  AI_AGENT_TYPE,\n  Agent,\n  MemberInfo,\n  USER_ROLE,\n  USER_STATUS,\n} from \"@illa-public/public-types\"\nimport { RecordEditor } from \"@illa-public/record-editor\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport {\n  getCurrentTeamInfo,\n  getCurrentUser,\n  getPlanUtils,\n  teamActions,\n} from \"@illa-public/user-data\"\nimport {\n  ACTION_MANAGE,\n  ATTRIBUTE_GROUP,\n  canManage,\n  canManageInvite,\n  canUseUpgradeFeature,\n  openShareAgentModal,\n  showShareAgentModal,\n  showShareAgentModalOnlyForShare,\n} from \"@illa-public/user-role-utils\"\nimport {\n  formatNumForAgent,\n  getAgentPublicLink,\n  getAuthToken,\n  getILLABuilderURL,\n  getILLACloudURL,\n} from \"@illa-public/utils\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { FC, useEffect, useRef, useState } from \"react\"\nimport { Helmet } from \"react-helmet-async\"\nimport { Controller, useForm, useFormState } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  useAsyncValue,\n  useNavigate,\n  useParams,\n  useSearchParams,\n} from \"react-router-dom\"\nimport { v4 } from \"uuid\"\nimport {\n  Button,\n  CloseIcon,\n  DependencyIcon,\n  ForkIcon,\n  PlayFillIcon,\n  PreviousIcon,\n  RadioGroup,\n  ResetIcon,\n  StarFillIcon,\n  StarOutlineIcon,\n  getColor,\n  useMessage,\n} from \"@illa-design/react\"\nimport { createAction } from \"@/api/actions\"\nimport { TextSignal } from \"@/api/ws/textSignal\"\nimport GridFillIcon from \"@/assets/agent/gridFill.svg?react\"\nimport { FullPageLoading } from \"@/components/FullPageLoading\"\nimport { buildActionInfo, buildAppWithAgentSchema } from \"@/config/AppWithAgent\"\nimport AIAgentBlock from \"@/page/AI/components/AIAgentBlock\"\nimport { PreviewChat } from \"@/page/AI/components/PreviewChat\"\nimport { ChatSendRequestPayload } from \"@/page/AI/components/PreviewChat/interface\"\nimport { useAgentConnect } from \"@/page/AI/components/ws/useAgentConnect\"\nimport { CollaboratorsInfo } from \"@/redux/currentApp/collaborators/collaboratorsState\"\nimport { forkAIAgentToTeam, starAIAgent, unstarAIAgent } from \"@/services/agent\"\nimport { fetchCreateApp } from \"@/services/apps\"\nimport { copyToClipboard } from \"@/utils/copyToClipboard\"\nimport { track } from \"@/utils/mixpanelHelper\"\nimport { ChatContext } from \"../../components/ChatContext\"\nimport {\n  agentAvatarStyle,\n  agentControlContainerStyle,\n  agentDescStyle,\n  agentMenuContainerStyle,\n  agentNicknameStyle,\n  agentTeamAvatarStyle,\n  agentTeamInfoContainerStyle,\n  agentTeamNameStyle,\n  agentTitleContainerStyle,\n  agentTopContainerStyle,\n  aiAgentContainerStyle,\n  backMenuStyle,\n  backTextStyle,\n  buttonContainerStyle,\n  closeIconStyle,\n  labelLogoStyle,\n  labelStyle,\n  leftPanelContainerStyle,\n  readOnlyTextStyle,\n  rightPanelContainerStyle,\n} from \"./style\"\n\nexport const AIAgentRunPC: FC = () => {\n  const { agent, marketplace } = useAsyncValue() as {\n    agent: Agent\n    marketplace: MarketAIAgent | undefined\n  }\n\n  const navigate = useNavigate()\n\n  const [currentMarketplaceInfo, setCurrentMarketplaceInfo] = useState<\n    MarketAIAgent | undefined\n  >(marketplace)\n\n  const { control, handleSubmit, getValues, reset } = useForm<Agent>({\n    mode: \"onSubmit\",\n    defaultValues: agent,\n  })\n  const formRef = useRef<HTMLFormElement>(null)\n\n  const { isDirty, isValid } = useFormState({\n    control,\n  })\n\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)!!\n  const currentUserInfo = useSelector(getCurrentUser)\n\n  const message = useMessage()\n\n  // page state\n  const [isRunning, setIsRunning] = useState(false)\n  const [isConnecting, setIsConnecting] = useState(false)\n  const [shareDialogVisible, setShareDialogVisible] = useState(false)\n  const [starLoading, setStarLoading] = useState(false)\n  const [forkLoading, setForkLoading] = useState(false)\n  const [starState, setStarState] = useState(\n    currentMarketplaceInfo?.marketplace?.isStarredByCurrentUser ?? false,\n  )\n\n  // data state\n  const [inRoomUsers, setInRoomUsers] = useState<CollaboratorsInfo[]>([])\n  const [isReceiving, setIsReceiving] = useState(false)\n  const [starNum, setStarNum] = useState(\n    currentMarketplaceInfo?.marketplace.numStars ?? 0,\n  )\n  const upgradeModal = useUpgradeModal()\n\n  const { ownerTeamIdentifier, agentID } = useParams()\n  const [searchParams] = useSearchParams()\n\n  // premium dialog\n  const canUseBillingFeature = canUseUpgradeFeature(\n    currentTeamInfo?.myRole,\n    getPlanUtils(currentTeamInfo),\n    currentTeamInfo?.totalTeamLicense?.teamLicensePurchased,\n    currentTeamInfo?.totalTeamLicense?.teamLicenseAllPaid,\n  )\n\n  // ui state\n  const [isFullPageLoading, setIsFullPageLoading] = useState(false)\n  const canShowInviteButton = showShareAgentModal(\n    currentTeamInfo,\n    agent.teamID === currentTeamInfo.id\n      ? currentTeamInfo.myRole\n      : USER_ROLE.GUEST,\n    getValues(\"publishedToMarketplace\"),\n  )\n\n  const [showEditPanel, setShowEditPanel] = useState(true)\n\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n\n  const handleCloseEditPanel = () => {\n    setShowEditPanel(false)\n  }\n\n  const handleClickBack = () => {\n    const cloud_url = getILLACloudURL(window.customDomain)\n    if (document.referrer.includes(cloud_url)) {\n      return (location.href = `${cloud_url}/workspace/${ownerTeamIdentifier}/ai-agents`)\n    }\n    if (\n      document.referrer.includes(import.meta.env.ILLA_MARKET_URL) &&\n      agentID\n    ) {\n      return (location.href = `${\n        import.meta.env.ILLA_MARKET_URL\n      }/ai-agent/${agentID}/detail`)\n    }\n    return (location.href = cloud_url)\n  }\n\n  const handleSubmitClick = handleSubmit(async (data) => {\n    if (isPremiumModel(data.model) && !canUseBillingFeature) {\n      upgradeModal({\n        modalType: \"agent\",\n        from: \"agent_run_gpt4\",\n      })\n      return\n    }\n    reset(data)\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n      ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n      {\n        element: isRunning ? \"restart\" : \"start\",\n        parameter1: data.agentType === 1 ? \"chat\" : \"text\",\n        parameter5: agent.aiAgentID,\n      },\n    )\n    isRunning\n      ? await reconnect(data.aiAgentID, data.agentType)\n      : await connect(data.aiAgentID, data.agentType)\n  })\n\n  const dialog = (\n    <Controller\n      control={control}\n      name=\"publishedToMarketplace\"\n      render={({ field }) => (\n        <MixpanelTrackProvider\n          basicTrack={track}\n          pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN}\n        >\n          {shareDialogVisible && (\n            <ShareAgentPC\n              itemID={agent.aiAgentID}\n              onInvitedChange={(userList) => {\n                const memberListInfo: MemberInfo[] = userList.map((user) => {\n                  return {\n                    ...user,\n                    userID: \"\",\n                    nickname: \"\",\n                    avatar: \"\",\n                    userStatus: USER_STATUS.PENDING,\n                    permission: {},\n                    createdAt: \"\",\n                    updatedAt: \"\",\n                  }\n                })\n                dispatch(teamActions.updateInvitedUserReducer(memberListInfo))\n              }}\n              canUseBillingFeature={canUseUpgradeFeature(\n                currentTeamInfo.myRole,\n                getPlanUtils(currentTeamInfo),\n                currentTeamInfo.totalTeamLicense.teamLicensePurchased,\n                currentTeamInfo.totalTeamLicense.teamLicenseAllPaid,\n              )}\n              title={t(\n                \"user_management.modal.social_media.default_text.agent\",\n                {\n                  agentName: agent.name,\n                },\n              )}\n              redirectURL={`${getILLABuilderURL(\n                window.customDomain,\n              )}/${ownerTeamIdentifier}/ai-agent/${\n                agent.aiAgentID\n              }/run?myTeamIdentifier=${searchParams.get(\"myTeamIdentifier\")}`}\n              onClose={() => {\n                setShareDialogVisible(false)\n              }}\n              canInvite={canManageInvite(\n                currentTeamInfo.myRole,\n                currentTeamInfo.permission.allowEditorManageTeamMember,\n                currentTeamInfo.permission.allowViewerManageTeamMember,\n              )}\n              defaultInviteUserRole={USER_ROLE.VIEWER}\n              teamID={currentTeamInfo.id}\n              currentUserRole={currentTeamInfo.myRole}\n              defaultBalance={currentTeamInfo.currentTeamLicense.balance}\n              defaultAllowInviteLink={\n                currentTeamInfo.permission.inviteLinkEnabled\n              }\n              onInviteLinkStateChange={(enableInviteLink) => {\n                dispatch(\n                  teamActions.updateTeamMemberPermissionReducer({\n                    teamID: currentTeamInfo.id,\n                    newPermission: {\n                      ...currentTeamInfo.permission,\n                      inviteLinkEnabled: enableInviteLink,\n                    },\n                  }),\n                )\n              }}\n              agentID={agent.aiAgentID}\n              defaultAgentContributed={field.value}\n              onAgentContributed={async (isAgentContributed) => {\n                if (isAgentContributed) {\n                  const resp = await getAIAgentMarketplaceInfo(agent.aiAgentID)\n                  setCurrentMarketplaceInfo(resp.data)\n                  const newUrl = new URL(\n                    getAgentPublicLink(resp.data.aiAgent.aiAgentID),\n                  )\n                  newUrl.searchParams.set(\"token\", getAuthToken())\n                  window.open(newUrl, \"_blank\")\n                } else {\n                  setCurrentMarketplaceInfo(undefined)\n                }\n                field.onChange(isAgentContributed)\n              }}\n              onCopyInviteLink={(link: string) => {\n                track(\n                  ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                  ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                  {\n                    element: \"share_modal_copy_team\",\n                    parameter5: agent.aiAgentID,\n                  },\n                )\n                copyToClipboard(\n                  t(\"user_management.modal.custom_copy_text_agent_invite\", {\n                    userName: currentUserInfo.nickname,\n                    teamName: currentTeamInfo.name,\n                    inviteLink: link,\n                  }),\n                )\n              }}\n              onCopyAgentMarketLink={(link: string) => {\n                track(\n                  ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                  ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                  {\n                    element: \"share_modal_link\",\n                    parameter5: agent.aiAgentID,\n                  },\n                )\n                copyToClipboard(\n                  t(\"user_management.modal.contribute.default_text.agent\", {\n                    agentName: agent.name,\n                    agentLink: link,\n                  }),\n                )\n              }}\n              userRoleForThisAgent={\n                currentTeamInfo.id === agent.teamID\n                  ? currentTeamInfo.myRole\n                  : USER_ROLE.GUEST\n              }\n              ownerTeamID={agent.teamID}\n              onBalanceChange={(balance) => {\n                dispatch(\n                  teamActions.updateTeamMemberSubscribeReducer({\n                    teamID: currentTeamInfo.id,\n                    subscribeInfo: {\n                      ...currentTeamInfo.currentTeamLicense,\n                      balance: balance,\n                    },\n                  }),\n                )\n              }}\n              teamPlan={getPlanUtils(currentTeamInfo)}\n              onShare={(platform) => {\n                track(\n                  ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                  ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                  {\n                    element: \"share_modal_social_media\",\n                    parameter4: platform,\n                    parameter5: agent.aiAgentID,\n                  },\n                )\n              }}\n            />\n          )}\n        </MixpanelTrackProvider>\n      )}\n    />\n  )\n\n  const { sendMessage, generationMessage, chatMessages, reconnect, connect } =\n    useAgentConnect({\n      onSendClean: () => {\n        sendMessage(\n          {} as ChatSendRequestPayload,\n          TextSignal.CLEAN,\n          getValues(\"agentType\"),\n          \"clean\",\n          false,\n        )\n      },\n      onStartRunning: () => {},\n      onConnecting: (isConnecting) => {\n        setIsConnecting(isConnecting)\n      },\n      onReceiving: (isReceiving) => {\n        setIsReceiving(isReceiving)\n      },\n      onRunning: (isRunning: boolean) => {\n        setIsRunning(isRunning)\n      },\n      onSendPrompt(): void {\n        sendMessage(\n          {\n            threadID: v4(),\n            prompt: getValues(\"prompt\"),\n            variables: getValues(\"variables\"),\n            modelConfig: getValues(\"modelConfig\"),\n            model: getValues(\"model\"),\n            actionID: getValues(\"aiAgentID\"),\n            agentType: getValues(\"agentType\"),\n          } as ChatSendRequestPayload,\n          TextSignal.RUN,\n          getValues(\"agentType\"),\n          \"chat\",\n          false,\n        )\n      },\n      onUpdateRoomUsers(roomUsers: CollaboratorsInfo[]): void {\n        setInRoomUsers(roomUsers)\n      },\n    })\n\n  useEffect(() => {\n    canShowInviteButton &&\n      track(\n        ILLA_MIXPANEL_EVENT_TYPE.SHOW,\n        ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n        {\n          element: \"invite_entry\",\n        },\n      )\n  }, [canShowInviteButton])\n  const menu = (\n    <Controller\n      control={control}\n      name=\"publishedToMarketplace\"\n      render={({ field }) => (\n        <div css={agentMenuContainerStyle}>\n          {canShowInviteButton && (\n            <Button\n              colorScheme=\"grayBlue\"\n              leftIcon={<DependencyIcon />}\n              onClick={() => {\n                track(\n                  ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                  ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                  {\n                    element: \"invite_entry\",\n                    parameter5: agent.aiAgentID,\n                  },\n                )\n                if (\n                  !openShareAgentModal(\n                    currentTeamInfo,\n                    currentTeamInfo.id === agent.teamID\n                      ? currentTeamInfo.myRole\n                      : USER_ROLE.GUEST,\n                    field.value,\n                  )\n                ) {\n                  upgradeModal({\n                    modalType: \"upgrade\",\n                    from: \"agent_run_share\",\n                  })\n                  return\n                }\n                setShareDialogVisible(true)\n                track(\n                  ILLA_MIXPANEL_EVENT_TYPE.SHOW,\n                  ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                  {\n                    element: \"share_modal\",\n                    parameter5: agent.aiAgentID,\n                  },\n                )\n              }}\n            >\n              {t(\"share\")}\n            </Button>\n          )}\n          {field.value && (\n            <Button\n              ml=\"8px\"\n              colorScheme=\"grayBlue\"\n              onClick={async () => {\n                setStarLoading(true)\n                track(\n                  ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                  ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                  {\n                    element: \"star\",\n                    parameter5: agent.aiAgentID,\n                  },\n                )\n                try {\n                  if (starState) {\n                    await unstarAIAgent(agent.aiAgentID)\n                    if (starNum > 0) {\n                      setStarNum(starNum - 1)\n                    }\n                  } else {\n                    await starAIAgent(agent.aiAgentID)\n                    setStarNum(starNum + 1)\n                  }\n                  setStarState(!starState)\n                } catch (e) {\n                  message.error({\n                    content: t(\"dashboard.message.star-failed\"),\n                  })\n                } finally {\n                  setStarLoading(false)\n                }\n              }}\n              loading={starLoading}\n              leftIcon={\n                starState ? <StarFillIcon c=\"#FFBB38\" /> : <StarOutlineIcon />\n              }\n            >\n              <span>{t(\"marketplace.star\")}</span>\n              {starNum > 0 && <span> {formatNumForAgent(starNum)}</span>}\n            </Button>\n          )}\n          {canManage(\n            currentTeamInfo.myRole,\n            ATTRIBUTE_GROUP.AI_AGENT,\n            getPlanUtils(currentTeamInfo),\n            ACTION_MANAGE.FORK_AI_AGENT,\n          ) &&\n            field.value && (\n              <Button\n                ml=\"8px\"\n                colorScheme=\"grayBlue\"\n                loading={forkLoading}\n                leftIcon={<ForkIcon />}\n                onClick={async () => {\n                  track(\n                    ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                    ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                    {\n                      element: \"fork\",\n                      parameter5: agent.aiAgentID,\n                    },\n                  )\n                  setForkLoading(true)\n                  try {\n                    const newAgent = await forkAIAgentToTeam(agent.aiAgentID)\n                    navigate(\n                      `/${currentTeamInfo.identifier}/ai-agent/${newAgent.data.aiAgentID}`,\n                    )\n                  } catch (e) {\n                    message.error({\n                      content: t(\"dashboard.message.fork-failed\"),\n                    })\n                  } finally {\n                    setForkLoading(false)\n                  }\n                }}\n              >\n                <span>{t(\"marketplace.fork\")}</span>\n                {(currentMarketplaceInfo?.marketplace.numForks ?? 0) > 0 && (\n                  <span>\n                    {\" \"}\n                    {formatNumForAgent(\n                      currentMarketplaceInfo?.marketplace.numForks ?? 0,\n                    )}\n                  </span>\n                )}\n              </Button>\n            )}\n          {canManage(\n            currentTeamInfo.myRole,\n            ATTRIBUTE_GROUP.APP,\n            getPlanUtils(currentTeamInfo),\n            ACTION_MANAGE.CREATE_APP,\n          ) && (\n            <Button\n              ml=\"8px\"\n              colorScheme=\"grayBlue\"\n              loading={forkLoading}\n              leftIcon={<GridFillIcon />}\n              onClick={async () => {\n                try {\n                  setIsFullPageLoading(true)\n                  const finalAgent =\n                    agent.teamID === currentTeamInfo.id\n                      ? agent\n                      : (await forkAIAgentToTeam(agent.aiAgentID)).data\n\n                  const variableKeys = finalAgent.variables.map((v) => v.key)\n                  const { appInfo, variableKeyMapInputNodeDisplayName } =\n                    buildAppWithAgentSchema(variableKeys)\n                  const appInfoResp = await fetchCreateApp({\n                    appName: \"Untitled app\",\n                    initScheme: appInfo,\n                  })\n                  const agentActionInfo = buildActionInfo(\n                    agent,\n                    variableKeyMapInputNodeDisplayName,\n                  )\n                  await createAction(appInfoResp.data.appId, agentActionInfo)\n                  window.open(\n                    `${getILLABuilderURL(window.customDomain)}/${\n                      currentTeamInfo.identifier\n                    }/app/${appInfoResp.data.appId}`,\n                    \"_blank\",\n                  )\n                } catch {\n                  message.error({\n                    content: t(\"create_fail\"),\n                  })\n                } finally {\n                  setIsFullPageLoading(false)\n                }\n              }}\n            >\n              <span>{t(\"marketplace.agent.create_app\")}</span>\n            </Button>\n          )}\n        </div>\n      )}\n    />\n  )\n\n  return (\n    <>\n      <Helmet>\n        <title>{agent.name}</title>\n      </Helmet>\n      <ChatContext.Provider value={{ inRoomUsers }}>\n        <div css={aiAgentContainerStyle}>\n          <AnimatePresence mode=\"wait\" initial={false}>\n            {showEditPanel && (\n              <motion.div\n                css={leftPanelContainerStyle}\n                initial={{\n                  opacity: 0,\n                  x: \"-100%\",\n                  position: \"absolute\",\n                }}\n                animate={{\n                  opacity: 1,\n                  x: 0,\n                  position: \"relative\",\n                  transition: { duration: 0.3 },\n                }}\n                exit={{\n                  opacity: 0,\n                  x: \"-100%\",\n                  position: \"absolute\",\n                }}\n              >\n                <div css={agentTopContainerStyle}>\n                  <div css={backMenuStyle}>\n                    <div onClick={handleClickBack}>\n                      <PreviousIcon fs=\"16px\" />\n                      <div css={backTextStyle}>{t(\"back\")}</div>\n                    </div>\n                    <IconHotSpot\n                      onClick={handleCloseEditPanel}\n                      css={closeIconStyle}\n                    >\n                      <CloseIcon size=\"12px\" />\n                    </IconHotSpot>\n                  </div>\n                  <div css={agentTitleContainerStyle}>\n                    <Controller\n                      control={control}\n                      name=\"icon\"\n                      render={({ field }) => (\n                        <Avatar\n                          css={agentAvatarStyle}\n                          avatarUrl={field.value}\n                        />\n                      )}\n                    />\n                    <Controller\n                      control={control}\n                      name=\"name\"\n                      render={({ field }) => (\n                        <div css={agentNicknameStyle}>{field.value}</div>\n                      )}\n                    />\n                  </div>\n                  <Controller\n                    control={control}\n                    name=\"description\"\n                    render={({ field }) => (\n                      <div css={agentDescStyle}>{field.value}</div>\n                    )}\n                  />\n                  <div css={agentTeamInfoContainerStyle}>\n                    <Controller\n                      control={control}\n                      name=\"teamIcon\"\n                      render={({ field }) => (\n                        <Avatar\n                          css={agentTeamAvatarStyle}\n                          avatarUrl={field.value}\n                        />\n                      )}\n                    />\n                    <Controller\n                      control={control}\n                      name=\"teamName\"\n                      render={({ field }) => (\n                        <div css={agentTeamNameStyle}>{field.value}</div>\n                      )}\n                    />\n                  </div>\n                  {menu}\n                </div>\n                <div css={agentControlContainerStyle}>\n                  <Controller\n                    name=\"agentType\"\n                    control={control}\n                    shouldUnregister={false}\n                    render={({ field }) => (\n                      <AIAgentBlock\n                        title={t(\"editor.ai-agent.label.mode\")}\n                        tips={t(\"editor.ai-agent.tips.mode\")}\n                      >\n                        <RadioGroup\n                          value={field.value}\n                          colorScheme={getColor(\"grayBlue\", \"02\")}\n                          w=\"100%\"\n                          type=\"button\"\n                          forceEqualWidth={true}\n                          options={[\n                            {\n                              value: AI_AGENT_TYPE.CHAT,\n                              label: t(\"editor.ai-agent.option.mode.chat\"),\n                            },\n                            {\n                              value: AI_AGENT_TYPE.TEXT_GENERATION,\n                              label: t(\"editor.ai-agent.option.mode.text\"),\n                            },\n                          ]}\n                          onChange={(value) => {\n                            if (isReceiving || isConnecting) {\n                              message.info({\n                                content: t(\n                                  \"editor.ai-agent.message.generating\",\n                                ),\n                              })\n                              return\n                            }\n                            track(\n                              ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                              ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                              {\n                                element: \"mode_radio_button\",\n                                parameter1: value,\n                                parameter5: agent.aiAgentID,\n                              },\n                            )\n                            field.onChange(value)\n                          }}\n                        />\n                      </AIAgentBlock>\n                    )}\n                  />\n                  <Controller\n                    name=\"prompt\"\n                    control={control}\n                    shouldUnregister={false}\n                    render={({ field: promptField }) => (\n                      <Controller\n                        name=\"variables\"\n                        control={control}\n                        render={({ field: variables }) => (\n                          <AIAgentBlock title={\"Prompt\"}>\n                            <CodeEditor\n                              {...promptField}\n                              editable={false}\n                              completionOptions={variables.value}\n                            />\n                          </AIAgentBlock>\n                        )}\n                      />\n                    )}\n                  />\n                  <Controller\n                    name=\"variables\"\n                    control={control}\n                    rules={{\n                      validate: (value) =>\n                        value.every(\n                          (param) => param.key !== \"\" && param.value !== \"\",\n                        ) ||\n                        (value.length === 1 &&\n                          value[0].key === \"\" &&\n                          value[0].value === \"\"),\n                    }}\n                    shouldUnregister={false}\n                    render={({ field }) =>\n                      field.value.length > 0 ? (\n                        <AIAgentBlock\n                          title={t(\"editor.ai-agent.label.variable\")}\n                        >\n                          <RecordEditor\n                            fillOnly\n                            records={field.value}\n                            onChangeKey={(index, key) => {\n                              const newVariables = [...field.value]\n                              newVariables[index].key = key\n                              field.onChange(newVariables)\n                            }}\n                            onChangeValue={(index, _, value) => {\n                              const newVariables = [...field.value]\n                              newVariables[index].value = value\n                              field.onChange(newVariables)\n                            }}\n                            onAdd={() => {}}\n                            onDelete={() => {}}\n                            label={\"\"}\n                          />\n                        </AIAgentBlock>\n                      ) : (\n                        <></>\n                      )\n                    }\n                  />\n                  <Controller\n                    name=\"model\"\n                    control={control}\n                    render={({ field }) => (\n                      <AIAgentBlock title={t(\"editor.ai-agent.label.model\")}>\n                        <div css={labelStyle}>\n                          <span css={labelLogoStyle}>\n                            {getLLM(field.value)?.logo}\n                          </span>\n                          <span css={readOnlyTextStyle}>\n                            {getLLM(field.value)?.name}\n                          </span>\n                        </div>\n                      </AIAgentBlock>\n                    )}\n                  />\n                </div>\n                <form ref={formRef} onSubmit={handleSubmitClick}>\n                  <div css={buttonContainerStyle}>\n                    <Button\n                      size=\"large\"\n                      flex=\"1\"\n                      disabled={!isValid}\n                      loading={isConnecting}\n                      ml=\"8px\"\n                      colorScheme={getColor(\"grayBlue\", \"02\")}\n                      leftIcon={isRunning ? <ResetIcon /> : <PlayFillIcon />}\n                    >\n                      {!isRunning\n                        ? t(\"editor.ai-agent.start\")\n                        : t(\"editor.ai-agent.restart\")}\n                    </Button>\n                  </div>\n                </form>\n              </motion.div>\n            )}\n          </AnimatePresence>\n          <Controller\n            name=\"agentType\"\n            control={control}\n            shouldUnregister={false}\n            render={({ field }) => (\n              <Controller\n                control={control}\n                name=\"publishedToMarketplace\"\n                render={({ field: contributedField }) => (\n                  <div css={rightPanelContainerStyle}>\n                    <PreviewChat\n                      showShareDialog={showShareAgentModalOnlyForShare(\n                        currentTeamInfo,\n                      )}\n                      showContributeDialog={showShareAgentModal(\n                        currentTeamInfo,\n                        agent.teamID === currentTeamInfo.id\n                          ? currentTeamInfo.myRole\n                          : USER_ROLE.GUEST,\n                        contributedField.value,\n                      )}\n                      showEditPanel={showEditPanel}\n                      setShowEditPanel={setShowEditPanel}\n                      isRunning={isRunning}\n                      isConnecting={isConnecting}\n                      hasCreated={true}\n                      isMobile={false}\n                      editState=\"RUN\"\n                      agentType={field.value}\n                      model={getValues(\"model\")}\n                      chatMessages={chatMessages}\n                      generationMessage={generationMessage}\n                      isReceiving={isReceiving}\n                      blockInput={!isRunning || isDirty}\n                      onSendMessage={(message, agentType: AI_AGENT_TYPE) => {\n                        track(\n                          ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                          ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n                          {\n                            element: \"send\",\n                            parameter5: agent.aiAgentID,\n                          },\n                        )\n                        sendMessage(\n                          {\n                            threadID: message.threadID,\n                            prompt: message.message,\n                            variables: [],\n                            modelConfig: getValues(\"modelConfig\"),\n                            model: getValues(\"model\"),\n                            agentType: getValues(\"agentType\"),\n                            actionID: getValues(\"aiAgentID\"),\n                          } as ChatSendRequestPayload,\n                          TextSignal.RUN,\n                          agentType,\n                          \"chat\",\n                          true,\n                          message,\n                        )\n                      }}\n                      onCancelReceiving={() => {\n                        sendMessage(\n                          {} as ChatSendRequestPayload,\n                          TextSignal.STOP_ALL,\n                          field.value,\n                          \"stop_all\",\n                          false,\n                        )\n                        setIsReceiving(false)\n                      }}\n                      onClickStartRunning={handleSubmitClick}\n                    />\n                  </div>\n                )}\n              />\n            )}\n          />\n        </div>\n        {dialog}\n        {isFullPageLoading && <FullPageLoading hasMask />}\n      </ChatContext.Provider>\n    </>\n  )\n}\n\nexport default AIAgentRunPC\n\nAIAgentRunPC.displayName = \"AIAgentRunPC\"\n"
  },
  {
    "path": "apps/builder/src/page/AI/AIAgentRun/AIAgentRunPC/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const aiAgentContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  width: 100%;\n  height: 100%;\n`\n\nexport const leftPanelContainerStyle = css`\n  height: 100%;\n  width: 528px;\n  display: flex;\n  flex-direction: column;\n  overflow-y: auto;\n  box-shadow: 4px 0 16px 0 rgba(0, 0, 0, 0.06);\n  flex: none;\n  ${applyMobileStyle(css`\n    display: none;\n  `)}\n`\n\nexport const rightPanelContainerStyle = css`\n  height: 100%;\n  display: flex;\n  overflow-y: auto;\n  flex-grow: 1;\n  flex-direction: column;\n`\n\nexport const agentTopContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  padding: 24px;\n  border-bottom: 1px solid ${getColor(\"grayBlue\", \"08\")};\n`\n\nexport const backMenuStyle = css`\n  display: flex;\n  cursor: pointer;\n  flex-direction: row;\n  justify-content: space-between;\n  margin-bottom: 32px;\n  flex-grow: 1;\n`\n\nexport const backTextStyle = css`\n  display: inline-block;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  margin-left: 8px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 24px;\n`\n\nexport const closeIconStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  display: flex;\n  width: 24px;\n  height: 24px;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  flex-shrink: 0;\n`\n\nexport const agentTitleContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const labelLogoStyle = css`\n  font-size: 16px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 16px;\n  height: 16px;\n\n  & svg {\n    height: 100%;\n    width: 100%;\n  }\n`\n\nexport const labelStyle = css`\n  display: flex;\n  width: 100%;\n  gap: 8px;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const readOnlyTextStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 22px;\n`\n\nexport const agentNicknameStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 18px;\n  font-style: normal;\n  font-weight: 600;\n  overflow-x: hidden;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  flex-grow: 1;\n  flex-shrink: 1;\n  margin-left: 16px;\n  line-height: 24px;\n`\n\nexport const agentAvatarStyle = css`\n  width: 48px;\n  height: 48px;\n  border-radius: 8px;\n`\n\nexport const agentDescStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  white-space: pre-wrap;\n  word-break: break-word;\n  font-weight: 400;\n  margin-top: 24px;\n  line-height: 22px;\n`\n\nexport const agentTeamInfoContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  margin-top: 8px;\n`\n\nexport const agentTeamAvatarStyle = css`\n  width: 24px;\n  height: 24px;\n`\n\nexport const agentMenuContainerStyle = css`\n  display: inline-flex;\n  flex-direction: row;\n  margin-top: 24px;\n`\n\nexport const buttonContainerStyle = css`\n  padding: 24px;\n  border-top: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const agentTeamNameStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  margin-left: 8px;\n  font-size: 12px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 20px;\n`\n\nexport const agentControlContainerStyle = css`\n  display: flex;\n  overflow-y: auto;\n  flex-direction: column;\n  flex-grow: 1;\n  flex-shrink: 1;\n  padding-bottom: 40px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/AIAgentRun/index.tsx",
    "content": "import { LayoutAutoChange } from \"@illa-public/layout-auto-change\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n} from \"@illa-public/mixpanel-utils\"\nimport { FC, useEffect } from \"react\"\nimport {\n  Await,\n  redirect,\n  useBeforeUnload,\n  useLoaderData,\n} from \"react-router-dom\"\nimport AIAgentRunMobile from \"@/page/AI/AIAgentRun/AIAgentRunMobile\"\nimport AIAgentRunPC from \"@/page/AI/AIAgentRun/AIAgentRunPC\"\nimport {\n  track,\n  trackPageDurationEnd,\n  trackPageDurationStart,\n} from \"@/utils/mixpanelHelper\"\n\nexport const AIAgentRun: FC = () => {\n  const data = useLoaderData() as {\n    data: Promise<any>\n  }\n\n  useEffect(() => {\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.VISIT,\n      ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN,\n    )\n    trackPageDurationStart()\n    return () => {\n      trackPageDurationEnd(ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN)\n    }\n  }, [])\n\n  useBeforeUnload(() => {\n    trackPageDurationEnd(ILLA_MIXPANEL_BUILDER_PAGE_NAME.AI_AGENT_RUN)\n  })\n\n  return (\n    <Await resolve={data.data} errorElement={<>{redirect(\"404\")}</>}>\n      <LayoutAutoChange\n        desktopPage={<AIAgentRunPC />}\n        mobilePage={<AIAgentRunMobile />}\n      />\n    </Await>\n  )\n}\n\nAIAgentRun.displayName = \"AIAgentRun\"\nexport default AIAgentRun\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/AIAgentBlock/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Trigger } from \"@illa-design/react\"\nimport RequireIcon from \"@/assets/agent/require.svg?react\"\nimport { AIAgentBlockProps } from \"./interface\"\nimport {\n  agentBlockStyle,\n  applyBlockSubtitleStyle,\n  applyBlockTextStyle,\n  blockRequireStyle,\n  blockTitleContainer,\n} from \"./style\"\n\nexport const AIAgentBlock: FC<AIAgentBlockProps> = (props) => {\n  const { title, tips, children, subtitle, subtitleTips, required, scrollId } =\n    props\n\n  return (\n    <div css={agentBlockStyle} data-scroll-id={scrollId}>\n      <div css={blockTitleContainer}>\n        {title && (\n          <Trigger\n            disabled={tips === undefined}\n            content={tips}\n            trigger=\"hover\"\n            position=\"top-start\"\n          >\n            <div css={applyBlockTextStyle(tips !== undefined)}>{title}</div>\n          </Trigger>\n        )}\n        {required && <RequireIcon css={blockRequireStyle} />}\n        <div style={{ flex: 1 }} />\n        {subtitle && (\n          <Trigger\n            disabled={subtitleTips === undefined}\n            content={subtitleTips}\n            trigger=\"hover\"\n          >\n            <div css={applyBlockSubtitleStyle(subtitleTips !== undefined)}>\n              {subtitle}\n            </div>\n          </Trigger>\n        )}\n      </div>\n      {children}\n    </div>\n  )\n}\n\nexport default AIAgentBlock\nAIAgentBlock.displayName = \"AIAgentBlock\"\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/AIAgentBlock/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface AIAgentBlockProps {\n  title: string\n  tips?: string\n  subtitle?: string | ReactNode\n  children?: ReactNode\n  subtitleTips?: string\n  required?: boolean\n  scrollId?: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/AIAgentBlock/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const agentBlockStyle = css`\n  margin-top: 8px;\n  padding: 8px 24px;\n  width: 100%;\n`\n\nexport function applyBlockTextStyle(\n  renderBottomLine?: boolean,\n): SerializedStyles {\n  return css`\n    color: ${getColor(\"grayBlue\", \"02\")};\n    font-size: 14px;\n    font-weight: 600;\n    line-height: 22px;\n    border-bottom: ${renderBottomLine\n      ? `1px dashed ${getColor(\"grayBlue\", \"06\")}`\n      : \"none\"};\n  `\n}\n\nexport const blockRequireStyle = css`\n  margin-left: 4px;\n`\n\nexport const blockTitleContainer = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  margin-bottom: 8px;\n`\n\nexport function applyBlockSubtitleStyle(\n  renderBottomLine?: boolean,\n): SerializedStyles {\n  return css`\n    display: inline-flex;\n    align-items: center;\n    border-bottom: ${renderBottomLine\n      ? `1px dashed ${getColor(\"grayBlue\", \"06\")}`\n      : \"none\"};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/AIAgentMessage/index.tsx",
    "content": "import { Avatar } from \"@illa-public/avatar\"\nimport { copyToClipboard } from \"@illa-public/utils\"\nimport { FC, useContext } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CopyIcon, useMessage } from \"@illa-design/react\"\nimport { ChatContext } from \"@/page/AI/components/ChatContext\"\nimport MarkdownMessage from \"@/page/AI/components/MarkdownMessage\"\nimport { SenderType } from \"@/page/AI/components/PreviewChat/interface\"\nimport { AIAgentMessageProps } from \"./interface\"\nimport {\n  agentMessageContainer,\n  hoverCopyStyle,\n  messageContainerStyle,\n  senderAvatarStyle,\n  senderContainerStyle,\n  senderNicknameStyle,\n} from \"./style\"\n\nexport const AIAgentMessage: FC<AIAgentMessageProps> = (props) => {\n  const { message, isMobile, canShowLongCopy } = props\n  const chatContext = useContext(ChatContext)\n  const showMessage = useMessage()\n  const { t } = useTranslation()\n\n  const senderNickname =\n    message.sender.senderType === SenderType.ANONYMOUS_AGENT\n      ? chatContext.inRoomUsers.find(\n          (user) => user.roomRole == SenderType.ANONYMOUS_AGENT,\n        )?.nickname ?? \"\"\n      : chatContext.inRoomUsers.find(\n          (user) => user.id == message.sender.senderID,\n        )?.nickname ?? \"\"\n\n  const senderAvatar =\n    message.sender.senderType === SenderType.ANONYMOUS_AGENT\n      ? chatContext.inRoomUsers.find(\n          (user) => user.roomRole == SenderType.ANONYMOUS_AGENT,\n        )?.avatar ?? \"\"\n      : chatContext.inRoomUsers.find(\n          (user) => user.id == message.sender.senderID,\n        )?.avatar ?? \"\"\n\n  return (\n    <div css={agentMessageContainer}>\n      {!isMobile && (\n        <Avatar\n          size={32}\n          css={senderAvatarStyle}\n          avatarUrl={senderAvatar}\n          name={senderNickname}\n          id={message.sender.senderID}\n        />\n      )}\n      <div css={senderContainerStyle}>\n        {canShowLongCopy && message.message && (\n          <span\n            css={hoverCopyStyle}\n            onClick={() => {\n              copyToClipboard(message.message ?? \"\")\n              showMessage.success({\n                content: t(\"copied\"),\n              })\n            }}\n          >\n            <CopyIcon size=\"14px\" />\n          </span>\n        )}\n        <div css={senderNicknameStyle}>{senderNickname}</div>\n        <div css={messageContainerStyle}>\n          <MarkdownMessage disableTrigger={canShowLongCopy}>\n            {message.message}\n          </MarkdownMessage>\n        </div>\n      </div>\n    </div>\n  )\n}\n\nexport default AIAgentMessage\nAIAgentMessage.displayName = \"AIAgentMessage\"\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/AIAgentMessage/interface.ts",
    "content": "import { ChatMessage } from \"@/page/AI/components/PreviewChat/interface\"\n\nexport interface AIAgentMessageProps {\n  message: ChatMessage\n  isMobile: boolean\n  canShowLongCopy: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/AIAgentMessage/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const agentMessageContainer = css`\n  padding: 24px 88px 8px 40px;\n  display: flex;\n  flex-direction: row;\n  width: 100%;\n  ${applyMobileStyle(css`\n    padding: 24px 48px 8px 12px;\n  `)}\n`\n\nexport const senderContainerStyle = css`\n  display: inline-flex;\n  align-items: start;\n  flex-direction: column;\n  max-width: 100%;\n  position: relative;\n`\n\nexport const senderAvatarStyle = css`\n  margin-right: 16px;\n`\n\nexport const senderNicknameStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  overflow-x: hidden;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  font-size: 14px;\n  max-width: 100%;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 22px;\n`\n\nexport const messageContainerStyle = css`\n  border-radius: 8px;\n  background: ${getColor(\"grayBlue\", \"09\")};\n  padding: 12px;\n  margin-top: 4px;\n  max-width: 100%;\n  ${applyMobileStyle(css`\n    margin-right: 0;\n  `)}\n`\n\nexport const hoverCopyStyle = css`\n  display: inline-flex;\n  padding: 4px;\n  align-items: center;\n  border-radius: 4px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  background: ${getColor(\"white\", \"01\")};\n  cursor: pointer;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  position: absolute;\n  bottom: 0;\n  right: -32px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/AILoading/index.tsx",
    "content": "import { createIcon } from \"@illa-design/react\"\n\nconst AILoading = createIcon({\n  title: \"AILoading\",\n  viewBox: \"0 0 12 12\",\n  path: (\n    <>\n      <g clipPath=\"url(#clip0_8958_319)\">\n        <path\n          fillRule=\"evenodd\"\n          clipRule=\"evenodd\"\n          d=\"M5.25 0.75C5.25 0.335786 5.58579 0 6 0C7.18669 0 8.34673 0.351894 9.33342 1.01118C10.3201 1.67047 11.0892 2.60754 11.5433 3.7039C11.9974 4.80026 12.1162 6.00666 11.8847 7.17054C11.6532 8.33443 11.0818 9.40353 10.2426 10.2426C9.40353 11.0818 8.33443 11.6532 7.17054 11.8847C6.00666 12.1162 4.80026 11.9974 3.7039 11.5433C2.60754 11.0892 1.67047 10.3201 1.01118 9.33342C0.351894 8.34673 0 7.18669 0 6C0 5.58579 0.335786 5.25 0.75 5.25C1.16421 5.25 1.5 5.58579 1.5 6C1.5 6.89002 1.76392 7.76004 2.25839 8.50007C2.75285 9.24009 3.45566 9.81686 4.27792 10.1575C5.10019 10.4981 6.00499 10.5872 6.87791 10.4135C7.75082 10.2399 8.55264 9.81132 9.18198 9.18198C9.81132 8.55264 10.2399 7.75082 10.4135 6.87791C10.5872 6.00499 10.4981 5.10019 10.1575 4.27792C9.81686 3.45566 9.24009 2.75285 8.50007 2.25839C7.76005 1.76392 6.89002 1.5 6 1.5C5.58579 1.5 5.25 1.16421 5.25 0.75Z\"\n          fill=\"url(#paint0_angular_8958_319)\"\n        />\n      </g>\n      <defs>\n        <radialGradient\n          id=\"paint0_angular_8958_319\"\n          cx=\"0\"\n          cy=\"0\"\n          r=\"1\"\n          gradientUnits=\"userSpaceOnUse\"\n          gradientTransform=\"translate(6 6) rotate(90) scale(6)\"\n        >\n          <stop offset=\"0.249663\" stopColor=\"#E13EFF\" />\n          <stop offset=\"0.49925\" stopColor=\"#853DFF\" />\n        </radialGradient>\n        <clipPath id=\"clip0_8958_319\">\n          <rect width=\"12\" height=\"12\" fill=\"white\" />\n        </clipPath>\n      </defs>\n    </>\n  ),\n})\n\nAILoading.displayName = \"AILoading\"\nexport default AILoading\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/ChatContext/index.tsx",
    "content": "import { createContext } from \"react\"\nimport { ChatContextProps } from \"@/page/AI/components/ChatContext/interface\"\n\nexport const ChatContext = createContext<ChatContextProps>({\n  inRoomUsers: [],\n})\n\nChatContext.displayName = \"ChatContext\"\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/ChatContext/interface.ts",
    "content": "import { CollaboratorsInfo } from \"@/redux/currentApp/collaborators/collaboratorsState\"\n\nexport interface ChatContextProps {\n  inRoomUsers: CollaboratorsInfo[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/ErrorText/index.tsx",
    "content": "import { FC } from \"react\"\nimport { WarningCircleIcon } from \"@illa-design/react\"\nimport { errorMsgStyle } from \"./style\"\n\ninterface ErrorTextProps {\n  errorMessage: string\n}\n\nexport const ErrorText: FC<ErrorTextProps> = ({ errorMessage }) => {\n  if (!errorMessage) return null\n  return (\n    <div css={errorMsgStyle}>\n      <WarningCircleIcon size=\"16px\" mt=\"4px\" />\n      {errorMessage}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/ErrorText/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const errorMsgStyle = css`\n  font-size: 14px;\n  line-height: 22px;\n  color: ${getColor(\"orange\", \"03\")};\n  display: flex;\n  align-items: flex-start;\n  gap: 8px;\n  margin-top: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/GenerationMessage/index.tsx",
    "content": "import { copyToClipboard } from \"@illa-public/utils\"\nimport { FC, useContext } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CopyIcon, useMessage } from \"@illa-design/react\"\nimport { ChatContext } from \"@/page/AI/components/ChatContext\"\nimport { GenerationMessageProps } from \"@/page/AI/components/GenerationMessage/interface\"\nimport {\n  avatarContainerStyle,\n  avatarStyle,\n  copyContainerStyle,\n  generationContainerStyle,\n  nickNameStyle,\n} from \"@/page/AI/components/GenerationMessage/style\"\nimport MarkdownMessage from \"@/page/AI/components/MarkdownMessage\"\nimport { SenderType } from \"@/page/AI/components/PreviewChat/interface\"\nimport { Avatar } from \"@/page/App/components/Avatar\"\n\nexport const GenerationMessage: FC<GenerationMessageProps> = (props) => {\n  const { message } = props\n\n  const m = useMessage()\n  const { t } = useTranslation()\n\n  const chatContext = useContext(ChatContext)\n  const senderNickname =\n    message.sender.senderType === SenderType.ANONYMOUS_AGENT\n      ? chatContext.inRoomUsers.find(\n          (user) => user.roomRole == SenderType.ANONYMOUS_AGENT,\n        )?.nickname ?? \"\"\n      : chatContext.inRoomUsers.find(\n          (user) => user.id == message.sender.senderID,\n        )?.nickname ?? \"\"\n\n  const senderAvatar =\n    message.sender.senderType === SenderType.ANONYMOUS_AGENT\n      ? chatContext.inRoomUsers.find(\n          (user) => user.roomRole == SenderType.ANONYMOUS_AGENT,\n        )?.avatar ?? \"\"\n      : chatContext.inRoomUsers.find(\n          (user) => user.id == message.sender.senderID,\n        )?.avatar ?? \"\"\n\n  return (\n    <div css={generationContainerStyle}>\n      <div css={avatarContainerStyle}>\n        <Avatar\n          css={avatarStyle}\n          avatar={senderAvatar}\n          nickname={senderNickname}\n        />\n      </div>\n      <div css={nickNameStyle}>{senderNickname}</div>\n      <MarkdownMessage>{message.message}</MarkdownMessage>\n      <div\n        css={copyContainerStyle}\n        onClick={() => {\n          copyToClipboard(message.message)\n          m.success({\n            content: t(\"copied\"),\n          })\n        }}\n      >\n        <CopyIcon fs=\"16px\" />\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/GenerationMessage/interface.ts",
    "content": "import { ChatMessage } from \"@/page/AI/components/PreviewChat/interface\"\n\nexport interface GenerationMessageProps {\n  message: ChatMessage\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/GenerationMessage/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const generationContainerStyle = css`\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  align-items: start;\n  margin: 72px;\n  padding-left: 24px;\n  padding-bottom: 24px;\n  padding-right: 24px;\n  border-radius: 8px;\n  border: 1px solid #f2f3f5;\n  background: ${getColor(\"white\", \"01\")};\n  max-width: 100%;\n  box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.08);\n  ${applyMobileStyle(css`\n    margin: 48px 20px 20px;\n    padding-left: 12px;\n    padding-right: 12px;\n  `)}\n`\n\nexport const avatarContainerStyle = css`\n  width: 100%;\n  left: 0;\n  position: absolute;\n  top: -24px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n\nexport const avatarStyle = css`\n  border-radius: 8px;\n  width: 48px;\n  height: 48px;\n`\n\nexport const nickNameStyle = css`\n  color: getColor(\"grayBlue\", \"100\");\n  margin-bottom: 48px;\n  overflow-x: hidden;\n  align-self: center;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  margin-top: 32px;\n  max-width: 100%;\n  text-align: center;\n  font-size: 16px;\n  font-style: normal;\n  font-weight: 600;\n  line-height: 24px;\n`\n\nexport const copyContainerStyle = css`\n  cursor: pointer;\n  width: 32px;\n  height: 32px;\n  margin-top: 6px;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  border-radius: 8px;\n  align-self: end;\n  &:hover {\n    background: ${getColor(\"grayBlue\", \"09\")};\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/KnowledgeUpload/contants.ts",
    "content": "import {\n  EXCEL_FILE_TYPE_RULES,\n  PDF_FILE_TYPE_RULES,\n  WORD_FILE_TYPE_RULES,\n} from \"@illa-public/utils\"\n\nexport const JSON_RULES = [\"application/json\"]\nexport const ACCEPT = [\n  WORD_FILE_TYPE_RULES[2],\n  ...EXCEL_FILE_TYPE_RULES,\n  ...PDF_FILE_TYPE_RULES,\n  \".mdx\",\n  \".md\",\n  \".txt\",\n  \".json\",\n  // \"image/*\", // TODO: not support currently\n]\n\nexport const MAX_MESSAGE_FILES_LENGTH = 10\nexport const MAX_FILE_SIZE = 20971520 // 20MB\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/KnowledgeUpload/index.tsx",
    "content": "import { getFileIconByContentType } from \"@illa-public/icon\"\nimport { GCS_OBJECT_TYPE, KnowledgeFile } from \"@illa-public/public-types\"\nimport { ChangeEvent, FC, useRef } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  Button,\n  DeleteIcon,\n  Loading,\n  SuccessIcon,\n  UploadIcon,\n  getColor,\n  useMessage,\n  useModal,\n} from \"@illa-design/react\"\nimport { handleParseFile } from \"@/utils/file\"\nimport { ACCEPT, MAX_FILE_SIZE, MAX_MESSAGE_FILES_LENGTH } from \"./contants\"\nimport {\n  fileItemStyle,\n  fileListContainerStyle,\n  fileNameStyle,\n  fileTypeIconStyle,\n  iconHotSpotStyle,\n  nameContainerStyle,\n  opeationStyle,\n} from \"./style\"\n\ninterface KnowledgeUploadProps {\n  addFile: (file: KnowledgeFile, isUpdate?: boolean) => void\n  removeFile: (name: string) => void\n  values: KnowledgeFile[]\n}\n\nconst KnowledgeUpload: FC<KnowledgeUploadProps> = ({\n  values,\n  removeFile,\n  addFile,\n}) => {\n  const inputRef = useRef<HTMLInputElement>(null)\n  const { t } = useTranslation()\n  const modal = useModal()\n  const message = useMessage()\n  const handleOnChange = async (e: ChangeEvent<HTMLInputElement>) => {\n    const files = e.target.files\n    const file = files && files[0]\n    if (!file) return\n    try {\n      if (file.size > MAX_FILE_SIZE) {\n        message.warning({\n          content: t(\"dashboard.message.please_use_a_file_wi\"),\n        })\n        return\n      }\n      const fileItem = {\n        name: file.name,\n        type: file.type,\n      }\n      addFile(fileItem)\n      const value = await handleParseFile(file)\n      if (value === \"\") {\n        message.warning({\n          content: t(\"dashboard.message.no_usable_text_conte\"),\n        })\n        removeFile(file.name)\n      } else {\n        const fileItem = {\n          name: file.name,\n          type: file.type,\n          value,\n        }\n        addFile(fileItem, true)\n      }\n    } catch (e) {\n      message.error({\n        content: t(\"dashboard.message.no_usable_text_conte\"),\n      })\n    }\n    inputRef.current && (inputRef.current.value = \"\")\n  }\n\n  const handleDelete = (name: string) => {\n    modal.show({\n      z: 1020,\n      title: t(\"drive.modal.delete_going_on_task.title\"),\n      content: t(\"drive.modal.delete_going_on_task.description\"),\n      okText: t(\"drive.modal.delete_going_on_task.delete\"),\n      cancelText: t(\"drive.modal.delete_going_on_task.cancel\"),\n      okButtonProps: {\n        colorScheme: \"red\",\n      },\n      onOk: () => removeFile(name),\n    })\n  }\n\n  const handleUploadFile = () => {\n    if (Array.isArray(values) && values.length >= MAX_MESSAGE_FILES_LENGTH) {\n      message.warning({\n        content: t(\"dashboard.message.support_for_up_to_10\"),\n      })\n      return\n    }\n    inputRef.current?.click()\n  }\n  return (\n    <>\n      <div>\n        <Button\n          colorScheme=\"grayBlue\"\n          fullWidth\n          variant=\"dashed\"\n          leftIcon={<UploadIcon />}\n          onClick={handleUploadFile}\n        >\n          Upload\n        </Button>\n        <input\n          style={{ display: \"none\" }}\n          type=\"file\"\n          accept={ACCEPT.join(\",\")}\n          ref={inputRef}\n          onChange={handleOnChange}\n        />\n      </div>\n      {Array.isArray(values) && values.length > 0 && (\n        <div css={fileListContainerStyle}>\n          {values.map((fileInfo) => (\n            <div key={fileInfo.name} css={fileItemStyle}>\n              <div css={nameContainerStyle}>\n                {getFileIconByContentType(\n                  GCS_OBJECT_TYPE.FILE,\n                  fileInfo.type,\n                  fileTypeIconStyle,\n                )}\n                <span css={fileNameStyle}>{fileInfo.name}</span>\n              </div>\n              <div css={opeationStyle}>\n                {fileInfo.value ? (\n                  <SuccessIcon color={getColor(\"green\", \"03\")} />\n                ) : (\n                  <Loading colorScheme=\"grayBlue\" />\n                )}\n                <span\n                  css={iconHotSpotStyle}\n                  onClick={() => handleDelete(fileInfo.name)}\n                >\n                  <DeleteIcon />\n                </span>\n              </div>\n            </div>\n          ))}\n        </div>\n      )}\n    </>\n  )\n}\n\nexport default KnowledgeUpload\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/KnowledgeUpload/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const fileListContainerStyle = css`\n  display: flex;\n  padding: 8px 0px;\n  flex-direction: column;\n  justify-content: center;\n  align-items: flex-start;\n  gap: 16px;\n  align-self: stretch;\n  width: 100%;\n`\n\nexport const fileItemStyle = css`\n  display: flex;\n  padding: 7px 12px;\n  justify-content: space-between;\n  align-items: center;\n  align-self: stretch;\n  border-radius: 2px;\n  background: ${getColor(\"grayBlue\", \"09\")};\n`\n\nexport const nameContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 12px;\n`\n\nexport const fileTypeIconStyle = css`\n  width: 16px;\n  height: 20px;\n`\n\nexport const fileNameStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  display: inline-block;\n  max-width: 364px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  font-size: 14px;\n  font-weight: 400;\n  line-height: 22px;\n`\n\nexport const opeationStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 16px;\n`\n\nexport const iconHotSpotStyle = css`\n  width: 16px;\n  height: 16px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/MarkdownMessage/Code/index.tsx",
    "content": "import { copyToClipboard } from \"@illa-public/utils\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CodeProps } from \"react-markdown/lib/ast-to-react\"\nimport { Prism as SyntaxHighlighter } from \"react-syntax-highlighter\"\nimport { oneLight } from \"react-syntax-highlighter/dist/esm/styles/prism\"\nimport { CopyIcon, Text, useMessage } from \"@illa-design/react\"\nimport { getTextValue } from \"../utils\"\nimport {\n  codeBlockContainerStyle,\n  codeBlockHeaderStyle,\n  copyStyle,\n  inlineCodeStyle,\n} from \"./style\"\n\nconst Code: FC<CodeProps> = (props) => {\n  const { t } = useTranslation()\n  const message = useMessage()\n\n  return (\n    <>\n      {!!props.inline ? (\n        <Text css={inlineCodeStyle} bg=\"#FAFAFA\" colorScheme=\"grayBlue\">\n          {getTextValue(props.children)}\n        </Text>\n      ) : (\n        <div css={codeBlockContainerStyle}>\n          <div css={codeBlockHeaderStyle}>\n            <span>\n              {/language-(\\w+)/.exec(props.className || \"\")?.[1] ?? \"markdown\"}\n            </span>\n            <div\n              css={copyStyle}\n              onClick={() => {\n                copyToClipboard(props.children?.[0])\n                message.success({\n                  content: t(\"copied\"),\n                })\n              }}\n            >\n              <CopyIcon size=\"16px\" />\n              <span>{t(\"editor.ai-agent.copy_code\")}</span>\n            </div>\n          </div>\n          <SyntaxHighlighter\n            {...props}\n            CodeTag=\"div\"\n            PreTag=\"div\"\n            customStyle={{\n              background: \"transparent\",\n            }}\n            language={\n              /language-(\\w+)/.exec(props.className || \"\")?.[1] ?? \"markdown\"\n            }\n            style={oneLight}\n          >\n            {getTextValue(props.children)}\n          </SyntaxHighlighter>\n        </div>\n      )}\n    </>\n  )\n}\n\nexport default Code\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/MarkdownMessage/Code/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const inlineCodeStyle = css`\n  display: inline-block;\n  margin: 0 4px;\n  font-size: 12px;\n  border-radius: 4px;\n  padding: 3px 4px;\n  font-weight: 450;\n  line-height: 18px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n`\n\nexport const codeBlockContainerStyle = css`\n  background-color: #fafafa;\n  display: flex;\n  flex-direction: column;\n  align-self: stretch;\n  border-radius: 8px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n`\n\nexport const codeBlockHeaderStyle = css`\n  display: flex;\n  padding: 4px 16px;\n  justify-content: space-between;\n  align-items: center;\n  align-self: stretch;\n  border-bottom: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  color: #444;\n  font-size: 12px;\n  font-weight: 400;\n`\n\nexport const copyStyle = css`\n  display: flex;\n  padding: 2px 8px;\n  justify-content: center;\n  align-items: center;\n  gap: 4px;\n  border-radius: 4px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 12px;\n  font-weight: 400;\n  line-height: 20px;\n  text-transform: capitalize;\n  cursor: pointer;\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/MarkdownMessage/index.tsx",
    "content": "import { copyToClipboard } from \"@illa-public/utils\"\nimport {\n  Paper,\n  Table,\n  TableBody,\n  TableCell,\n  TableContainer,\n  TableFooter,\n  TableHead,\n  TableRow,\n} from \"@mui/material\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport ReactMarkdown from \"react-markdown\"\nimport remarkBreaks from \"remark-breaks\"\nimport remarkGfm from \"remark-gfm\"\nimport {\n  CopyIcon,\n  Heading,\n  Link,\n  Paragraph,\n  Trigger,\n  Typography,\n  useMessage,\n} from \"@illa-design/react\"\nimport { MarkdownMessageProps } from \"@/page/AI/components/MarkdownMessage/interface\"\nimport {\n  cellStyle,\n  hoverCopyStyle,\n  markdownMessageStyle,\n  tableStyle,\n} from \"@/page/AI/components/MarkdownMessage/style\"\nimport Code from \"./Code\"\nimport { handleParseText } from \"./utils\"\n\nexport const MarkdownMessage: FC<MarkdownMessageProps> = (props) => {\n  const { children, isOwnMessage, disableTrigger } = props\n  const { t } = useTranslation()\n  const message = useMessage()\n\n  return (\n    <Trigger\n      bdRadius=\"4px\"\n      disabled={disableTrigger}\n      content={\n        <span\n          css={hoverCopyStyle(isOwnMessage)}\n          onClick={() => {\n            copyToClipboard(children ?? \"\")\n            message.success({\n              content: t(\"copied\"),\n            })\n          }}\n        >\n          <CopyIcon />\n        </span>\n      }\n      colorScheme=\"transparent\"\n      position={isOwnMessage ? \"left-end\" : \"right-end\"}\n      showArrow={false}\n      autoFitPosition={false}\n      withoutPadding\n      trigger=\"hover\"\n      withoutShadow\n    >\n      <div>\n        <Typography>\n          <ReactMarkdown\n            css={markdownMessageStyle}\n            remarkPlugins={[remarkGfm, remarkBreaks]}\n            components={{\n              h1: ({ children }) => <Heading level=\"h1\">{children}</Heading>,\n              h2: ({ children }) => <Heading level=\"h2\">{children}</Heading>,\n              h3: ({ children }) => <Heading level=\"h3\">{children}</Heading>,\n              h4: ({ children }) => <Heading level=\"h4\">{children}</Heading>,\n              h5: ({ children }) => <Heading level=\"h5\">{children}</Heading>,\n              h6: ({ children }) => <Heading level=\"h6\">{children}</Heading>,\n              a: ({ href, children }) => (\n                <Link href={href} target=\"_blank\" colorScheme=\"blue\">\n                  {children}\n                </Link>\n              ),\n              p: ({ children }) => <Paragraph>{children}</Paragraph>,\n              tr: ({ children }) => <TableRow>{children}</TableRow>,\n              th: ({ children }) => (\n                <TableCell align=\"center\">{children}</TableCell>\n              ),\n              td: ({ children }) => (\n                <TableCell align=\"left\" css={cellStyle}>\n                  {children}\n                </TableCell>\n              ),\n              thead: ({ children }) => <TableHead>{children}</TableHead>,\n              tbody: ({ children }) => <TableBody>{children}</TableBody>,\n              tfoot: ({ children }) => <TableFooter>{children}</TableFooter>,\n              table: ({ children }) => (\n                <TableContainer component={Paper} css={tableStyle}>\n                  <Table sx={{ minWidth: 650 }}>{children}</Table>\n                </TableContainer>\n              ),\n              code: (props) => <Code {...props} />,\n            }}\n          >\n            {handleParseText(children ?? \"\", isOwnMessage)}\n          </ReactMarkdown>\n        </Typography>\n      </div>\n    </Trigger>\n  )\n}\n\nMarkdownMessage.displayName = \"MarkdownMessage\"\nexport default MarkdownMessage\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/MarkdownMessage/interface.ts",
    "content": "export interface MarkdownMessageProps {\n  disableTrigger?: boolean\n  isOwnMessage?: boolean\n  children?: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/MarkdownMessage/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const markdownMessageStyle = css`\n  max-width: 100%;\n  overflow-x: hidden;\n  word-break: break-word;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 22px;\n`\n\nexport const hoverCopyStyle = (isOwnMessage?: boolean) => css`\n  display: inline-flex;\n  padding: 4px;\n  align-items: center;\n  gap: 8px;\n  border-radius: 4px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  background: ${getColor(\"white\", \"01\")};\n  cursor: pointer;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  transform: translate(${isOwnMessage ? \"-16px\" : \"16px\"}, 12px);\n`\n\nexport const cellStyle = css`\n  min-width: 100px;\n`\n\nexport const tableStyle = css`\n  margin: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/MarkdownMessage/utils.ts",
    "content": "import { isString } from \"@illa-design/react\"\n\nconst markCodeBlocks = (markdownText: string) => {\n  const codeBlockRegex = /```[\\s\\S]*?```/g\n  const placeholders: string[] = []\n  const placeholderPrefix = \"__CODEBLOCK__\"\n  // handler \"---\"\n  let tempText = markdownText.replaceAll(/(^---\\r?\\n?)/gm, \"\\n---\\n\")\n  tempText = tempText.replace(codeBlockRegex, (match) => {\n    const placeholder = `${placeholderPrefix}${placeholders.length}`\n    placeholders.push(match)\n    return placeholder\n  })\n  return { textWithoutCodeBlocks: tempText, placeholders }\n}\n\nconst convertTablesWithoutCodeBlocks = (\n  tempText: string,\n  isOwnMessage?: boolean,\n) => {\n  let res = tempText\n\n  if (isOwnMessage) {\n    const startRex = /(^\\n?\\|)|((\\n\\n)(.*)\\|)/g\n    const endRex = /(\\|\\n?$)|(\\|\\n\\n)/g\n    if (startRex.test(tempText) && endRex.test(tempText)) {\n      res = tempText.replace(startRex, (match) => {\n        return `\\n\\`\\`\\`markdown\\n${match.trim()}`\n      })\n      res = res.replace(endRex, (match) => {\n        return `${match.trim()}\\n\\`\\`\\`\\n`\n      })\n    }\n  } else {\n    const startRex = /(^\\n?\\|)|((\\n\\n)(.*)\\|)/\n    const endRex = /(\\|\\n?$)|(\\|\\n\\n)/\n    if (startRex.test(tempText) && endRex.test(tempText)) {\n      res = tempText.replace(startRex, (match) => {\n        return `\\n\\`\\`\\`markdown\\n${match.trim()}`\n      })\n      res = res.replace(endRex, (match) => {\n        return `${match.trim()}\\n\\`\\`\\`\\n`\n      })\n    } else if (startRex.test(tempText)) {\n      res = tempText.replace(startRex, (match) => {\n        return `\\n\\`\\`\\`markdown\\n${match.trim()}`\n      })\n    }\n  }\n  return res\n}\n\nconst restoreCodeBlocks = (\n  textWithPlaceholders: string,\n  placeholders: string[],\n) => {\n  placeholders.forEach((placeholderContent, index) => {\n    const placeholder = `__CODEBLOCK__${index}`\n    textWithPlaceholders = textWithPlaceholders.replace(\n      placeholder,\n      () => placeholderContent,\n    )\n  })\n\n  return textWithPlaceholders\n}\n\nexport const convertMarkdownTables = (\n  markdownText: string,\n  isOwnMessage?: boolean,\n) => {\n  const { textWithoutCodeBlocks, placeholders } = markCodeBlocks(markdownText)\n  let convertedText = convertTablesWithoutCodeBlocks(\n    textWithoutCodeBlocks,\n    isOwnMessage,\n  )\n  convertedText = restoreCodeBlocks(convertedText, placeholders)\n  return convertedText\n}\n\nexport const getTextValue = (value: unknown): string => {\n  if (Array.isArray(value)) {\n    return value.join(\"\\n\")\n  } else if (isString(value)) {\n    return value\n  } else {\n    return \"\"\n  }\n}\n\nexport const handleMarkdownLine = (text: string) => {\n  return text.replace(/((^\\n?---)(\\n|$))/gm, \"\\n---\\n\")\n}\n\nexport const handleMarkdownCode = (\n  text: string,\n  isOwnMessage?: boolean,\n): string => {\n  let res = text\n  if (isOwnMessage) {\n    const startRex =\n      /(^\\n?```markdown)|(^\\n?```md)|(\\n*```markdown)|(\\n*```md)/gim\n    const endRex = /(```\\n?$)|(```\\n\\n)/gm\n    if (startRex.test(res) && endRex.test(res)) {\n      res = text.replace(startRex, () => {\n        return `\\n\\n`\n      })\n      res = res.replace(endRex, () => {\n        return `\\n\\n`\n      })\n    }\n  } else {\n    const startRex =\n      /(^\\n?```markdown)|(^\\n?```md)|((\\n\\n)(.*)```markdown) | ((\\n\\n)(.*)```md)/im\n    const endRex = /(```\\n?$)|(```\\n\\n)/m\n    if (startRex.test(res) && endRex.test(res)) {\n      res = res.replace(startRex, () => {\n        return `\\n\\n`\n      })\n      res = res.replace(endRex, () => {\n        return `\\n\\n`\n      })\n    } else if (startRex.test(res)) {\n      res = res.replace(startRex, () => {\n        return `\\n\\n`\n      })\n    }\n  }\n  return res\n}\nexport const handleParseText = (text: string, isOwnMessage?: boolean) => {\n  let res = text\n  res = handleMarkdownLine(text)\n  res = handleMarkdownCode(res, isOwnMessage)\n  return res\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/PreviewChat/UploadButton/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { forwardRef } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { AttachmentIcon, Loading, Trigger, getColor } from \"@illa-design/react\"\nimport { ACCEPT } from \"../../KnowledgeUpload/contants\"\nimport { sendFileContainerStyle, sendFileIconStyle } from \"./style\"\n\ninterface UploadButton {\n  handleClick: () => void\n  parseKnowledgeLoading: boolean\n  handleFileChange: (e: React.ChangeEvent<HTMLInputElement>) => void\n}\n\nconst UploadButton = forwardRef<HTMLInputElement, UploadButton>(\n  ({ handleClick, handleFileChange, parseKnowledgeLoading }, ref) => {\n    const { t } = useTranslation()\n    return (\n      <Trigger\n        content={t(\"dashboard.message.support_for_uploadin\")}\n        position=\"top\"\n        maxW=\"300px\"\n      >\n        <div css={sendFileContainerStyle}>\n          <IconHotSpot onClick={handleClick} css={sendFileIconStyle}>\n            {parseKnowledgeLoading ? (\n              <Loading colorScheme=\"grayBlue\" />\n            ) : (\n              <AttachmentIcon size=\"16px\" color={getColor(\"grayBlue\", \"02\")} />\n            )}\n          </IconHotSpot>\n          <input\n            style={{ display: \"none\" }}\n            type=\"file\"\n            accept={ACCEPT.join(\",\")}\n            ref={ref}\n            multiple\n            onChange={handleFileChange}\n          />\n        </div>\n      </Trigger>\n    )\n  },\n)\n\nUploadButton.displayName = \"UploadButton\"\nexport default UploadButton\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/PreviewChat/UploadButton/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const sendFileContainerStyle = css`\n  display: flex;\n`\n\nexport const sendFileIconStyle = css`\n  display: flex;\n  padding: 12px;\n  width: 40px;\n  height: 40px;\n  flex: none;\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/PreviewChat/UploadKnowledgeFiles/index.tsx",
    "content": "import { getFileIconByContentType } from \"@illa-public/icon\"\nimport { GCS_OBJECT_TYPE, KnowledgeFile } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { Tag, getColor } from \"@illa-design/react\"\nimport { fileItemContainerStyle, fileTypeIconStyle } from \"./style\"\n\ninterface UploadKnowledgeFilesPops {\n  knowledgeFiles: KnowledgeFile[]\n  handleDeleteFile: (name: string) => void\n}\n\nconst UploadKnowledgeFiles: FC<UploadKnowledgeFilesPops> = ({\n  handleDeleteFile,\n  knowledgeFiles,\n}) => {\n  return (\n    <div css={fileItemContainerStyle}>\n      {knowledgeFiles.map((item) => (\n        <Tag\n          key={item.name}\n          closable\n          onClose={() => handleDeleteFile(item.name)}\n          maxW=\"300px\"\n          bg={getColor(\"grayBlue\", \"09\")}\n          icon={getFileIconByContentType(\n            GCS_OBJECT_TYPE.FILE,\n            item.type,\n            fileTypeIconStyle,\n          )}\n        >\n          {item.name}\n        </Tag>\n      ))}\n    </div>\n  )\n}\n\nexport default UploadKnowledgeFiles\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/PreviewChat/UploadKnowledgeFiles/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const fileItemContainerStyle = css`\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 8px;\n  flex-wrap: wrap;\n  max-height: 150px;\n  overflow-y: auto;\n`\n\nexport const fileTypeIconStyle = css`\n  height: 16px;\n`\n\nexport const fileNameStyle = css``\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/PreviewChat/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { isPremiumModel } from \"@illa-public/market-agent\"\nimport {\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackContext,\n} from \"@illa-public/mixpanel-utils\"\nimport { AI_AGENT_TYPE, KnowledgeFile } from \"@illa-public/public-types\"\nimport { getCurrentUser } from \"@illa-public/user-data\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport {\n  ChangeEvent,\n  FC,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { v4 } from \"uuid\"\nimport {\n  Button,\n  ContributeIcon,\n  DependencyIcon,\n  PlayFillIcon,\n  ResetIcon,\n  useMessage,\n} from \"@illa-design/react\"\nimport { ILLA_WEBSOCKET_STATUS } from \"@/api/ws/interface\"\nimport AgentBlockInput from \"@/assets/agent/agent-block-input.svg?react\"\nimport GridFillIcon from \"@/assets/agent/gridFill.svg?react\"\nimport MenuIcon from \"@/assets/agent/menuIcon.svg?react\"\nimport StopIcon from \"@/assets/agent/stop.svg?react\"\nimport AIAgentMessage from \"@/page/AI/components/AIAgentMessage\"\nimport { GenerationMessage } from \"@/page/AI/components/GenerationMessage\"\nimport {\n  ChatMessage,\n  PreviewChatProps,\n  SenderType,\n} from \"@/page/AI/components/PreviewChat/interface\"\nimport {\n  blockInputContainerStyle,\n  blockInputTextStyle,\n  chatContainerStyle,\n  generatingContainerStyle,\n  generatingContentContainerStyle,\n  generatingDividerStyle,\n  generatingTextStyle,\n  inputStyle,\n  inputTextContainerStyle,\n  menuIconStyle,\n  mobileInputContainerStyle,\n  mobileInputElementStyle,\n  mobileInputStyle,\n  operationStyle,\n  previewChatContainerStyle,\n  previewTitleContainerStyle,\n  previewTitleTextStyle,\n  sendButtonStyle,\n  stopIconStyle,\n} from \"@/page/AI/components/PreviewChat/style\"\nimport UserMessage from \"@/page/AI/components/UserMessage\"\nimport { getAgentWSStatus } from \"@/redux/config/configSelector\"\nimport { handleParseFile } from \"@/utils/file\"\nimport {\n  MAX_FILE_SIZE,\n  MAX_MESSAGE_FILES_LENGTH,\n} from \"../KnowledgeUpload/contants\"\nimport UploadButton from \"./UploadButton\"\nimport UploadKnowledgeFiles from \"./UploadKnowledgeFiles\"\n\nexport const PreviewChat: FC<PreviewChatProps> = (props) => {\n  const {\n    showShareDialog,\n    showContributeDialog,\n    hasCreated,\n    isMobile,\n    isRunning,\n    agentType,\n    chatMessages,\n    generationMessage,\n    onSendMessage,\n    isReceiving,\n    blockInput,\n    editState,\n    model,\n    showEditPanel,\n    isConnecting,\n    setShowEditPanel,\n    onCancelReceiving,\n    onShowShareDialog,\n    onShowContributeDialog,\n    onClickCreateApp,\n    onClickStartRunning,\n  } = props\n\n  const currentUserInfo = useSelector(getCurrentUser)\n  const message = useMessage()\n\n  const wsStatus = useSelector(getAgentWSStatus)\n\n  const chatRef = useRef<HTMLDivElement>(null)\n\n  const [textAreaVal, setTextAreaVal] = useState(\"\")\n  const [knowledgeFiles, setKnowledgeFiles] = useState<KnowledgeFile[]>([])\n  const [parseKnowledgeLoading, setParseKnowledgeLoading] = useState(false)\n\n  const inputRef = useRef<HTMLInputElement>(null)\n  const canShowKnowledgeFiles = isPremiumModel(model)\n\n  const { t } = useTranslation()\n\n  const { track } = useContext(MixpanelTrackContext)\n\n  const messagesList = useMemo(() => {\n    return chatMessages.map((message, i) => {\n      if (\n        message.sender.senderType === SenderType.USER &&\n        message.sender.senderID === currentUserInfo.userID\n      ) {\n        return (\n          <UserMessage\n            key={message.threadID}\n            message={message}\n            isMobile={isMobile}\n          />\n        )\n      }\n      return (\n        <AIAgentMessage\n          key={message.threadID}\n          message={message}\n          isMobile={isMobile}\n          canShowLongCopy={i === chatMessages.length - 1 && !isReceiving}\n        />\n      )\n    })\n  }, [chatMessages, currentUserInfo.userID, isMobile, isReceiving])\n\n  const handleDeleteFile = (fileName: string) => {\n    const files = knowledgeFiles.filter((file) => file.name !== fileName)\n    setKnowledgeFiles(files)\n  }\n\n  const handleUploadFile = () => {\n    if (knowledgeFiles.length >= MAX_MESSAGE_FILES_LENGTH) {\n      message.warning({\n        content: t(\"dashboard.message.support_for_up_to_10\"),\n      })\n      return\n    }\n    inputRef.current?.click()\n  }\n\n  const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {\n    let inputFiles = Array.from(e.target.files || [])\n    inputRef.current && (inputRef.current.value = \"\")\n    if (!inputFiles.length) return\n    if (inputFiles.length + knowledgeFiles.length > MAX_MESSAGE_FILES_LENGTH) {\n      message.warning({\n        content: t(\"dashboard.message.support_for_up_to_10\"),\n      })\n      return\n    }\n    setParseKnowledgeLoading(true)\n    const currentFiles = [...knowledgeFiles]\n    try {\n      for (let file of inputFiles) {\n        if (!file) break\n        if (file.size > MAX_FILE_SIZE) {\n          message.warning({\n            content: t(\"dashboard.message.please_use_a_file_wi\"),\n          })\n          return\n        }\n        const index = currentFiles.findIndex(\n          (item) => item.name === file.name && item.type === file.type,\n        )\n        const fileName =\n          index !== -1\n            ? `${file.name.split(\".\")[0]}(${v4().slice(0, 3)})`\n            : file.name\n\n        currentFiles.push({\n          name: fileName,\n          type: file.type,\n        })\n        setKnowledgeFiles(currentFiles)\n        const value = await handleParseFile(file, true)\n        if (value === \"\") {\n          message.warning({\n            content: t(\"dashboard.message.no_usable_text_conte\"),\n          })\n          handleDeleteFile(fileName)\n          return\n        }\n        const afterParseFilesIndex = currentFiles.findIndex(\n          (item) => item.name === file.name && item.type === file.type,\n        )\n        if (afterParseFilesIndex !== -1) {\n          const needUpdateFile = currentFiles[afterParseFilesIndex]\n          if (!needUpdateFile.value) {\n            currentFiles.splice(afterParseFilesIndex, 1, {\n              ...needUpdateFile,\n              ...file,\n              value,\n            })\n          }\n        } else {\n          currentFiles.push({\n            name: fileName,\n            type: file.type,\n            value,\n          })\n        }\n        setKnowledgeFiles(currentFiles)\n      }\n    } catch (e) {\n      message.error({\n        content: t(\"dashboard.message.bad_file\"),\n      })\n    } finally {\n      setParseKnowledgeLoading(false)\n    }\n  }\n\n  useEffect(() => {\n    chatRef.current?.scrollTo({\n      top: chatRef.current.scrollHeight,\n    })\n  }, [chatMessages, generationMessage])\n\n  const sendAndClearMessage = useCallback(() => {\n    if (\n      (textAreaVal !== \"\" || knowledgeFiles.length > 0) &&\n      !parseKnowledgeLoading\n    ) {\n      onSendMessage(\n        {\n          threadID: v4(),\n          message: textAreaVal,\n          sender: {\n            senderID: currentUserInfo.userID,\n            senderType: SenderType.USER,\n          },\n          knowledgeFiles: knowledgeFiles,\n        } as ChatMessage,\n        agentType,\n      )\n      setTextAreaVal(\"\")\n      setKnowledgeFiles([])\n    }\n  }, [\n    agentType,\n    currentUserInfo.userID,\n    knowledgeFiles,\n    onSendMessage,\n    parseKnowledgeLoading,\n    textAreaVal,\n  ])\n\n  const generationBlock = useMemo(() => {\n    return (\n      generationMessage && <GenerationMessage message={generationMessage} />\n    )\n  }, [generationMessage])\n\n  useEffect(() => {\n    editState === \"EDIT\" &&\n      showShareDialog &&\n      track?.(\n        ILLA_MIXPANEL_EVENT_TYPE.SHOW,\n        {\n          element: \"invite_entry\",\n        },\n        \"both\",\n      )\n  }, [editState, showShareDialog, track])\n\n  return (\n    <div css={previewChatContainerStyle}>\n      {!isMobile && (\n        <div css={previewTitleContainerStyle}>\n          {editState === \"RUN\" && !showEditPanel && (\n            <IconHotSpot\n              onClick={() => setShowEditPanel?.(!showEditPanel)}\n              css={menuIconStyle}\n            >\n              <MenuIcon />\n            </IconHotSpot>\n          )}\n          <div css={previewTitleTextStyle}>\n            {agentType === AI_AGENT_TYPE.CHAT\n              ? t(\"editor.ai-agent.title-preview.chat\")\n              : t(\"editor.ai-agent.title-preview.text-generation\")}\n          </div>\n          {editState === \"EDIT\" && showShareDialog && (\n            <Button\n              disabled={!hasCreated}\n              ml=\"8px\"\n              colorScheme=\"grayBlue\"\n              leftIcon={<DependencyIcon />}\n              onClick={() => {\n                track?.(\n                  ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                  {\n                    element: \"invite_entry\",\n                  },\n                  \"both\",\n                )\n                onShowShareDialog?.()\n              }}\n            >\n              {t(\"share\")}\n            </Button>\n          )}\n          {editState === \"EDIT\" && showContributeDialog && (\n            <Button\n              disabled={!hasCreated}\n              ml=\"8px\"\n              colorScheme=\"grayBlue\"\n              leftIcon={<ContributeIcon />}\n              onClick={() => {\n                onShowContributeDialog?.()\n              }}\n            >\n              {t(\"editor.ai-agent.contribute\")}\n            </Button>\n          )}\n          {editState === \"EDIT\" && (\n            <Button\n              ml=\"8px\"\n              colorScheme=\"grayBlue\"\n              leftIcon={<GridFillIcon />}\n              onClick={() => {\n                onClickCreateApp?.()\n              }}\n            >\n              {t(\"marketplace.agent.create_app\")}\n            </Button>\n          )}\n          {editState === \"RUN\" && !showEditPanel && (\n            <Button\n              colorScheme=\"grayBlue\"\n              loading={isConnecting}\n              leftIcon={isRunning ? <ResetIcon /> : <PlayFillIcon />}\n              onClick={onClickStartRunning}\n            >\n              {!isRunning\n                ? t(\"editor.ai-agent.start\")\n                : t(\"editor.ai-agent.restart\")}\n            </Button>\n          )}\n        </div>\n      )}\n      <div ref={chatRef} css={chatContainerStyle}>\n        {agentType === AI_AGENT_TYPE.CHAT ? messagesList : generationBlock}\n      </div>\n      <div css={inputTextContainerStyle}>\n        <AnimatePresence>\n          {isReceiving &&\n            wsStatus !== ILLA_WEBSOCKET_STATUS.CLOSED &&\n            wsStatus !== ILLA_WEBSOCKET_STATUS.FAILED && (\n              <motion.div\n                css={generatingContainerStyle}\n                initial={{\n                  y: 0,\n                  opacity: 0,\n                }}\n                animate={{\n                  y: -16,\n                  opacity: 1,\n                }}\n                exit={{\n                  y: 0,\n                  opacity: 0,\n                }}\n                transition={{ duration: 0.2 }}\n              >\n                <div css={generatingContentContainerStyle}>\n                  <div css={generatingTextStyle}>\n                    {t(\"editor.ai-agent.button.generating\")}\n                  </div>\n                  <div css={generatingDividerStyle} />\n                  <StopIcon\n                    css={stopIconStyle}\n                    onClick={() => {\n                      onCancelReceiving()\n                    }}\n                  />\n                </div>\n              </motion.div>\n            )}\n          {isRunning &&\n            (wsStatus === ILLA_WEBSOCKET_STATUS.CLOSED ||\n              wsStatus === ILLA_WEBSOCKET_STATUS.FAILED) && (\n              <motion.div\n                css={generatingContainerStyle}\n                initial={{\n                  y: 0,\n                  opacity: 0,\n                }}\n                animate={{\n                  y: -16,\n                  opacity: 1,\n                }}\n                exit={{\n                  y: 0,\n                  opacity: 0,\n                }}\n                transition={{ duration: 0.2 }}\n              >\n                <div css={generatingContentContainerStyle}>\n                  <div css={generatingTextStyle}>\n                    {t(\"editor.ai-agent.message.reconnect\")}\n                  </div>\n                </div>\n              </motion.div>\n            )}\n        </AnimatePresence>\n        {blockInput ? (\n          <div css={blockInputContainerStyle}>\n            <AgentBlockInput />\n            <div css={blockInputTextStyle}>\n              {editState === \"RUN\"\n                ? t(\"editor.ai-agent.tips.not-start-run\")\n                : t(\"editor.ai-agent.tips.not-start\")}\n            </div>\n          </div>\n        ) : isMobile ? (\n          <div css={mobileInputContainerStyle}>\n            <div css={mobileInputStyle}>\n              <input\n                css={mobileInputElementStyle}\n                value={textAreaVal}\n                placeholder={t(\"editor.ai-agent.placeholder.send\")}\n                onKeyDown={(event) => {\n                  if (event.keyCode === 13 && !event.shiftKey) {\n                    event.preventDefault()\n                    if (isReceiving || blockInput) {\n                      return\n                    }\n                    sendAndClearMessage()\n                  }\n                }}\n                onChange={(v) => {\n                  setTextAreaVal(v.target.value)\n                }}\n              />\n              {canShowKnowledgeFiles && (\n                <UploadButton\n                  handleClick={handleUploadFile}\n                  parseKnowledgeLoading={parseKnowledgeLoading}\n                  handleFileChange={handleFileChange}\n                  ref={inputRef}\n                />\n              )}\n              <Button\n                disabled={isReceiving || blockInput}\n                ml=\"8px\"\n                colorScheme=\"techPurple\"\n                onClick={() => {\n                  sendAndClearMessage()\n                }}\n              >\n                {t(\"editor.ai-agent.button.send\")}\n              </Button>\n            </div>\n            {canShowKnowledgeFiles && (\n              <UploadKnowledgeFiles\n                knowledgeFiles={knowledgeFiles}\n                handleDeleteFile={handleDeleteFile}\n              />\n            )}\n          </div>\n        ) : (\n          <>\n            <textarea\n              value={textAreaVal}\n              css={inputStyle}\n              placeholder={t(\"editor.ai-agent.placeholder.send\")}\n              onKeyDown={(event) => {\n                if (event.keyCode === 13 && !event.shiftKey) {\n                  event.preventDefault()\n                  if (isReceiving || blockInput) {\n                    return\n                  }\n                  sendAndClearMessage()\n                }\n              }}\n              onChange={(event) => {\n                setTextAreaVal(event.target.value)\n              }}\n            />\n            <div css={operationStyle(canShowKnowledgeFiles)}>\n              {canShowKnowledgeFiles && (\n                <UploadKnowledgeFiles\n                  knowledgeFiles={knowledgeFiles}\n                  handleDeleteFile={handleDeleteFile}\n                />\n              )}\n              <div css={sendButtonStyle}>\n                {canShowKnowledgeFiles && (\n                  <UploadButton\n                    handleClick={handleUploadFile}\n                    parseKnowledgeLoading={parseKnowledgeLoading}\n                    handleFileChange={handleFileChange}\n                    ref={inputRef}\n                  />\n                )}\n                <Button\n                  disabled={isReceiving || blockInput}\n                  colorScheme=\"techPurple\"\n                  onClick={() => {\n                    sendAndClearMessage()\n                  }}\n                >\n                  {t(\"editor.ai-agent.button.send\")}\n                </Button>\n              </div>\n            </div>\n          </>\n        )}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/PreviewChat/interface.ts",
    "content": "import {\n  AI_AGENT_MODEL,\n  AI_AGENT_TYPE,\n  AgentAdvanceConfig,\n  KnowledgeFile,\n} from \"@illa-public/public-types\"\nimport { Params } from \"@illa-public/record-editor\"\n\nexport type EDIT_STATE = \"EDIT\" | \"RUN\"\n\nexport enum SenderType {\n  USER = 1,\n  AGENT = 2,\n  ANONYMOUS_AGENT = 3,\n}\n\nexport interface ChatWsAppendResponse {\n  sender: ChatSender\n  threadID: string\n  message: string\n  actionID: string\n}\n\nexport interface ChatWsEndResponse {\n  actionID: string\n}\n\nexport interface ChatSender {\n  senderID: string\n  senderType: SenderType\n}\n\nexport interface ChatMessage {\n  threadID: string\n  message: string\n  sender: ChatSender\n  knowledgeFiles?: KnowledgeFile[]\n}\n\nexport interface ChatSendRequestPayload {\n  threadID: string\n  prompt: string\n  actionID: string // the ID of who answered the question\n  variables: Params[]\n  model: AI_AGENT_MODEL\n  agentType: AI_AGENT_TYPE\n  modelConfig: AgentAdvanceConfig\n}\n\nexport interface PreviewChatProps {\n  model: AI_AGENT_MODEL\n  hasCreated: boolean\n  editState: EDIT_STATE\n  agentType: AI_AGENT_TYPE\n  chatMessages: ChatMessage[]\n  generationMessage?: ChatMessage\n  onSendMessage: (message: ChatMessage, agentType: AI_AGENT_TYPE) => void\n  onCancelReceiving: () => void\n  blockInput: boolean\n  isReceiving: boolean\n  isRunning: boolean\n  isConnecting: boolean\n  isMobile: boolean\n  showShareDialog: boolean\n  showContributeDialog: boolean\n  showEditPanel: boolean\n  setShowEditPanel?: (show: boolean) => void\n  onShowShareDialog?: () => void\n  onShowContributeDialog?: () => void\n  onClickCreateApp?: () => void\n  onClickStartRunning?: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/PreviewChat/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const blockInputContainerStyle = css`\n  height: 104px;\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  overflow: hidden;\n  background-color: ${getColor(\"white\", \"05\")};\n  backdrop-filter: blur(5px);\n`\n\nexport const blockInputTextStyle = css`\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 400;\n  margin-top: 4px;\n  line-height: 22px;\n`\n\nexport const previewChatContainerStyle = css`\n  position: relative;\n  height: 100%;\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n`\n\nexport const previewTitleContainerStyle = css`\n  display: flex;\n  width: 100%;\n  flex-direction: row;\n  padding: 24px;\n  align-items: center;\n  border-bottom: 1px solid ${getColor(\"grayBlue\", \"08\")};\n`\n\nexport const menuIconStyle = css`\n  cursor: pointer;\n  margin-right: 16px;\n  flex: none;\n`\n\nexport const previewTitleTextStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 18px;\n  flex: 1;\n  font-weight: 500;\n  line-height: 24px;\n`\n\nexport const inputTextContainerStyle = css`\n  padding: 24px;\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  box-sizing: border-box;\n  border-top: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  flex: none;\n  ${applyMobileStyle(css`\n    padding: 12px 20px;\n  `)}\n`\n\nexport const chatContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  overflow-y: auto;\n  height: 100%;\n  padding-bottom: 110px;\n  width: 100%;\n`\n\nexport const mobileInputElementStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  flex-grow: 1;\n  font-style: normal;\n  border: none;\n  font-weight: 400;\n  line-height: 22px; /* 157.143% */\n  padding: 8px 8px 8px 0;\n\n  ::placeholder {\n    color: ${getColor(\"grayBlue\", \"04\")};\n  }\n`\n\nexport const inputStyle = css`\n  padding: 6px 16px;\n  font-size: 14px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  outline: none;\n  line-height: 22px;\n  border: none;\n  flex-shrink: 1;\n  width: 100%;\n  flex-grow: 1;\n  font-family: unset;\n  background: none;\n  resize: none;\n\n  ::placeholder {\n    color: ${getColor(\"grayBlue\", \"04\")};\n  }\n\n  &:focus-within {\n    outline: none;\n    border: none;\n    background: none;\n  }\n\n  &:active {\n    outline: none;\n    border: none;\n    background: none;\n  }\n\n  &:disabled {\n    cursor: not-allowed;\n    color: ${getColor(\"grayBlue\", \"05\")};\n  }\n\n  &::-webkit-outer-spin-button,\n  &::-webkit-inner-spin-button {\n    -webkit-appearance: none;\n  }\n\n  &[type=\"number\"] {\n    -moz-appearance: textfield;\n  }\n`\n\nexport const generatingContainerStyle = css`\n  display: flex;\n  justify-content: center;\n  width: 100%;\n  pointer-events: none;\n  left: 0;\n  top: -32px;\n  position: absolute;\n`\n\nexport const generatingContentContainerStyle = css`\n  display: inline-flex;\n  pointer-events: auto;\n  flex-direction: row;\n  align-items: center;\n  background: ${getColor(\"white\", \"01\")};\n  box-sizing: border-box;\n  border-radius: 16px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  padding: 4px 15px;\n`\nexport const generatingTextStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 22px;\n`\n\nexport const generatingDividerStyle = css`\n  width: 1px;\n  height: 12px;\n  margin-left: 10px;\n  margin-right: 10px;\n  background: ${getColor(\"grayBlue\", \"08\")};\n`\n\nexport const stopIconStyle = css`\n  cursor: pointer;\n`\n\nexport const mobileInputContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n`\nexport const mobileInputStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const operationStyle = (showKnowledge: boolean) => css`\n  display: flex;\n  justify-content: ${showKnowledge ? \"space-between\" : \"flex-end\"};\n  align-items: flex-end;\n  align-self: stretch;\n`\n\nexport const sendButtonStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  margin-top: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/UserMessage/ShowFiles/index.tsx",
    "content": "import { getFileIconByContentType } from \"@illa-public/icon\"\nimport { GCS_OBJECT_TYPE, KnowledgeFile } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport {\n  containerStyle,\n  fileItemStyle,\n  fileNameStyle,\n  fileTypeIconStyle,\n  iconContainerStyle,\n} from \"./style\"\n\ninterface ShowFilesProps {\n  knowledgeFiles: KnowledgeFile[]\n}\nconst ShowFiles: FC<ShowFilesProps> = ({ knowledgeFiles }) => {\n  return (\n    <div css={containerStyle}>\n      {knowledgeFiles.map((item) => (\n        <div key={item.name} css={fileItemStyle}>\n          <span css={iconContainerStyle}>\n            {getFileIconByContentType(\n              GCS_OBJECT_TYPE.FILE,\n              item.type,\n              fileTypeIconStyle,\n            )}\n          </span>\n          <span css={fileNameStyle}>{item.name}</span>\n        </div>\n      ))}\n    </div>\n  )\n}\n\nexport default ShowFiles\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/UserMessage/ShowFiles/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const containerStyle = css`\n  gap: 8px;\n  width: 100%;\n  display: flex;\n  justify-content: flex-end;\n  align-items: flex-start;\n  flex-wrap: wrap;\n  margin-bottom: 8px;\n  ${applyMobileStyle(css`\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    align-items: flex-start;\n  `)}\n`\n\nexport const fileItemStyle = css`\n  display: flex;\n  width: 284px;\n  padding: 8px;\n  align-items: center;\n  gap: 4px;\n  align-self: stretch;\n  border-radius: 12px;\n  background: ${getColor(\"grayBlue\", \"09\")};\n  ${applyMobileStyle(css`\n    width: 100%;\n  `)}\n`\n\nexport const iconContainerStyle = css`\n  display: flex;\n  width: 32px;\n  height: 32px;\n  padding: 1px 4px;\n  justify-content: center;\n  align-items: center;\n`\n\nexport const fileTypeIconStyle = css`\n  width: 24px;\n  height: 30px;\n`\n\nexport const fileNameStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n  display: inline-block;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/UserMessage/index.tsx",
    "content": "import { Avatar } from \"@illa-public/avatar\"\nimport { getCurrentUser } from \"@illa-public/user-data\"\nimport { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport MarkdownMessage from \"@/page/AI/components/MarkdownMessage\"\nimport { UserMessageProps } from \"@/page/AI/components/UserMessage/interface\"\nimport {\n  agentMessageContainer,\n  messageContainerStyle,\n  senderAvatarStyle,\n  senderContainerStyle,\n  senderNicknameStyle,\n} from \"@/page/AI/components/UserMessage/style\"\nimport ShowFilesMobile from \"./ShowFiles\"\n\nexport const UserMessage: FC<UserMessageProps> = (props) => {\n  const { message, isMobile } = props\n  const currentUserInfo = useSelector(getCurrentUser)\n\n  return (\n    <div css={agentMessageContainer}>\n      <div css={senderContainerStyle}>\n        <span css={senderNicknameStyle}>{currentUserInfo.nickname}</span>\n        {Array.isArray(message.knowledgeFiles) &&\n          message.knowledgeFiles.length > 0 && (\n            <ShowFilesMobile knowledgeFiles={message.knowledgeFiles} />\n          )}\n        {message.message && (\n          <div css={messageContainerStyle}>\n            <MarkdownMessage isOwnMessage>{message.message}</MarkdownMessage>\n          </div>\n        )}\n      </div>\n      {!isMobile && (\n        <Avatar\n          size={32}\n          css={senderAvatarStyle}\n          avatarUrl={currentUserInfo.avatar}\n          name={currentUserInfo.nickname}\n          id={currentUserInfo.userID}\n        />\n      )}\n    </div>\n  )\n}\n\nexport default UserMessage\nUserMessage.displayName = \"UserMessage\"\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/UserMessage/interface.ts",
    "content": "import { ChatMessage } from \"@/page/AI/components/PreviewChat/interface\"\n\nexport interface UserMessageProps {\n  message: ChatMessage\n  isMobile: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/UserMessage/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const agentMessageContainer = css`\n  padding: 24px 40px 8px 88px;\n  display: flex;\n  justify-content: end;\n  width: 100%;\n  flex-direction: row;\n  ${applyMobileStyle(css`\n    padding: 24px 12px 8px 48px;\n  `)}\n`\n\nexport const senderContainerStyle = css`\n  display: inline-flex;\n  overflow-x: hidden;\n  flex-direction: column;\n  align-items: end;\n  gap: 4px;\n  max-width: 100%;\n  width: 100%;\n`\n\nexport const senderNicknameStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  max-width: 100%;\n  overflow-x: hidden;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 22px;\n`\n\nexport const senderAvatarStyle = css`\n  margin-left: 16px;\n`\n\nexport const messageContainerStyle = css`\n  border-radius: 8px;\n  background: ${getColor(\"techPurple\", \"08\")};\n  padding: 12px;\n  max-width: 100%;\n  ${applyMobileStyle(css`\n    margin-left: 0;\n  `)}\n`\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/ws/useAgentConnect.ts",
    "content": "import { isPremiumModel } from \"@illa-public/market-agent\"\nimport { AI_AGENT_TYPE } from \"@illa-public/public-types\"\nimport {\n  CollarModalType,\n  handleCollaPurchaseError,\n  useCollarModal,\n} from \"@illa-public/upgrade-modal\"\nimport { getCurrentTeamInfo, getCurrentUser } from \"@illa-public/user-data\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { useMessage } from \"@illa-design/react\"\nimport { Connection, getTextMessagePayload } from \"@/api/ws\"\nimport { WSMessageListener } from \"@/api/ws/illaWS\"\nimport { Callback } from \"@/api/ws/interface\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\nimport {\n  ChatMessage,\n  ChatSendRequestPayload,\n  ChatWsAppendResponse,\n} from \"@/page/AI/components/PreviewChat/interface\"\nimport {\n  UseAgentProps,\n  UseAgentReturn,\n} from \"@/page/AI/components/ws/useAgentProps\"\nimport { CollaboratorsInfo } from \"@/redux/currentApp/collaborators/collaboratorsState\"\nimport {\n  getAIAgentAnonymousAddress,\n  getAIAgentWsAddress,\n} from \"@/services/agent\"\nimport { formatMessageString } from \"./utils\"\n\nexport type AgentMessageType = \"chat\" | \"stop_all\" | \"clean\"\n\nexport function useAgentConnect(useAgentProps: UseAgentProps) {\n  const {\n    onConnecting,\n    onReceiving,\n    onSendClean,\n    onUpdateRoomUsers,\n    onRunning,\n    onSendPrompt,\n    onStartRunning,\n  } = useAgentProps\n\n  const [chatMessages, setChatMessages] = useState<ChatMessage[]>([])\n  const [generationMessage, setGenerationMessage] = useState<\n    ChatMessage | undefined\n  >(undefined)\n\n  const chatMessagesRef = useRef<ChatMessage[]>([])\n  const generationMessageRef = useRef<ChatMessage | undefined>(undefined)\n\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n  const currentUserInfo = useSelector(getCurrentUser)\n\n  const message = useMessage()\n  const collaModal = useCollarModal()\n  const { t } = useTranslation()\n\n  const sendMessage = useCallback(\n    (\n      payload: ChatSendRequestPayload,\n      signal: TextSignal,\n      aiAgentType: AI_AGENT_TYPE,\n      type: AgentMessageType,\n      updateMessage?: boolean,\n      messageContent?: ChatMessage,\n    ) => {\n      onReceiving(true)\n      const encodePayload: ChatSendRequestPayload = payload\n      Object.keys(encodePayload).forEach((key) => {\n        if (key === \"prompt\") {\n          const text = encodePayload[key]\n          if (isPremiumModel(payload.model)) {\n            encodePayload[key] = encodeURIComponent(\n              formatMessageString(text, messageContent?.knowledgeFiles),\n            )\n          } else {\n            encodePayload[key] = encodeURIComponent(encodePayload[key])\n          }\n        }\n        if (key === \"variables\") {\n          encodePayload[key] = encodePayload[key].map((v) => {\n            return {\n              ...v,\n              value: encodeURIComponent(v.value),\n            }\n          })\n        }\n      })\n\n      Connection.getTextRoom(\"ai-agent\", \"\")?.send(\n        getTextMessagePayload(\n          signal,\n          TextTarget.ACTION,\n          true,\n          {\n            type: type,\n            payload: {},\n          },\n          currentTeamInfo?.id ?? \"\",\n          currentUserInfo.userID,\n          [encodePayload],\n        ),\n      )\n      if (updateMessage && messageContent) {\n        switch (aiAgentType) {\n          case AI_AGENT_TYPE.CHAT:\n            chatMessagesRef.current = [\n              ...chatMessagesRef.current,\n              messageContent,\n            ]\n            setChatMessages([...chatMessages, messageContent])\n            break\n          case AI_AGENT_TYPE.TEXT_GENERATION:\n            break\n        }\n      }\n    },\n    [chatMessages, currentTeamInfo?.id, currentUserInfo.userID, onReceiving],\n  )\n\n  const onUpdateChatMessage = useCallback((message: ChatMessage) => {\n    const newMessageList = [...chatMessagesRef.current]\n    const index = newMessageList.findIndex((m) => {\n      return m.threadID === message.threadID\n    })\n    if (index === -1) {\n      newMessageList.push({\n        sender: message.sender,\n        message: message.message,\n        threadID: message.threadID,\n      } as ChatMessage)\n    } else {\n      newMessageList[index].message =\n        newMessageList[index].message + message.message\n    }\n    chatMessagesRef.current = newMessageList\n    setChatMessages(newMessageList)\n  }, [])\n\n  const onUpdateGenerationMessage = useCallback((message: ChatMessage) => {\n    if (\n      generationMessageRef.current &&\n      generationMessageRef.current.threadID === message.threadID\n    ) {\n      const newMessage = {\n        ...generationMessageRef.current,\n      }\n      newMessage.message = newMessage.message + message.message\n      generationMessageRef.current = newMessage\n      setGenerationMessage(newMessage)\n    } else {\n      const m = {\n        sender: message.sender,\n        message: message.message,\n        threadID: message.threadID,\n      } as ChatMessage\n      generationMessageRef.current = m\n      setGenerationMessage(m)\n    }\n  }, [])\n\n  const cleanMessage = useCallback(() => {\n    chatMessagesRef.current = []\n    setChatMessages([])\n    generationMessageRef.current = undefined\n    setGenerationMessage(undefined)\n  }, [])\n\n  const connect = useCallback(\n    async (aiAgentID: string, agentType: AI_AGENT_TYPE) => {\n      onConnecting(true)\n      let address = \"\"\n      try {\n        if (aiAgentID === \"\" || aiAgentID === undefined) {\n          const response = await getAIAgentAnonymousAddress()\n          address = response.data.aiAgentConnectionAddress\n        } else {\n          const response = await getAIAgentWsAddress(aiAgentID)\n          address = response.data.aiAgentConnectionAddress\n        }\n\n        const messageListener = {\n          onMessage: (event) => {\n            const m = event.data\n            if (typeof m !== \"string\") {\n              return\n            }\n            const dataList = m.split(\"\\n\")\n            dataList.forEach((data: string) => {\n              let callback: Callback<unknown> = JSON.parse(data)\n              if (callback.errorCode === 0) {\n                switch (callback.broadcast?.type) {\n                  case \"enter/remote\":\n                    const { inRoomUsers } = callback.broadcast.payload as {\n                      inRoomUsers: CollaboratorsInfo[]\n                    }\n                    onUpdateRoomUsers(inRoomUsers)\n                    cleanMessage()\n                    onSendClean()\n                    break\n                  case \"chat/remote\":\n                    let chatCallback = callback.broadcast\n                      .payload as ChatWsAppendResponse\n                    if (agentType === AI_AGENT_TYPE.CHAT) {\n                      onUpdateChatMessage(chatCallback)\n                    } else {\n                      onUpdateGenerationMessage(chatCallback)\n                    }\n                    break\n                  case \"stop_all/remote\":\n                    break\n                  case \"clean/remote\":\n                    onSendPrompt()\n                    break\n                }\n              } else {\n                switch (callback.errorCode) {\n                  case 1:\n                    onReceiving(false)\n                    onRunning(false)\n                    message.error({\n                      content: t(\"editor.ai-agent.message.start-failed\"),\n                    })\n                    break\n                  case 15:\n                    onReceiving(false)\n                    break\n                  case 16:\n                    message.error({\n                      content: t(\"editor.ai-agent.message.token\"),\n                    })\n                    break\n                  case 17:\n                  case 18:\n                    collaModal({\n                      modalType: CollarModalType.TOKEN,\n                      from: \"agent_run\",\n                    })\n                    break\n                  case 3:\n                    break\n                }\n              }\n            })\n          },\n          onClosed: () => {\n            onReceiving(true)\n          },\n        } as WSMessageListener\n        Connection.enterAgentRoom(address, messageListener)\n        onConnecting(false)\n        onRunning(true)\n        onReceiving(true)\n        onStartRunning()\n      } catch (e) {\n        onConnecting(false)\n        const res = handleCollaPurchaseError(\n          e,\n          CollarModalType.TOKEN,\n          \"agent_run\",\n        )\n        if (res) return\n        message.error({\n          content: t(\"editor.ai-agent.message.start-failed\"),\n        })\n        return\n      }\n    },\n    [\n      cleanMessage,\n      message,\n      onConnecting,\n      onReceiving,\n      onRunning,\n      onSendClean,\n      onSendPrompt,\n      onStartRunning,\n      onUpdateChatMessage,\n      onUpdateGenerationMessage,\n      onUpdateRoomUsers,\n      collaModal,\n      t,\n    ],\n  )\n\n  useEffect(() => {\n    return () => {\n      Connection.leaveRoom(\"ai-agent\", \"\")\n    }\n  }, [])\n\n  const reconnect = useCallback(\n    async (aiAgentID: string, aiAgentType: AI_AGENT_TYPE) => {\n      Connection.leaveRoom(\"ai-agent\", \"\")\n      onRunning(false)\n      chatMessagesRef.current = []\n      setChatMessages([])\n      generationMessageRef.current = undefined\n      setGenerationMessage(undefined)\n      await connect(aiAgentID, aiAgentType)\n    },\n    [connect, onRunning],\n  )\n\n  return {\n    connect,\n    reconnect,\n    chatMessages,\n    generationMessage,\n    sendMessage,\n  } as UseAgentReturn\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/ws/useAgentProps.ts",
    "content": "import { AI_AGENT_TYPE } from \"@illa-public/public-types\"\nimport { TextSignal } from \"@/api/ws/textSignal\"\nimport {\n  ChatMessage,\n  ChatSendRequestPayload,\n} from \"@/page/AI/components/PreviewChat/interface\"\nimport { AgentMessageType } from \"@/page/AI/components/ws/useAgentConnect\"\nimport { CollaboratorsInfo } from \"@/redux/currentApp/collaborators/collaboratorsState\"\n\nexport interface UseAgentProps {\n  onConnecting: (isConnecting: boolean) => void\n  onRunning: (isRunning: boolean) => void\n  onReceiving: (isReceiving: boolean) => void\n  onUpdateRoomUsers: (roomUsers: CollaboratorsInfo[]) => void\n  onSendPrompt: () => void\n  onStartRunning: () => void\n  onSendClean: () => void\n}\n\nexport interface UseAgentReturn {\n  connect: (aiAgentID: string, agentType: AI_AGENT_TYPE) => Promise<void>\n  reconnect: (aiAgentID: string, agentType: AI_AGENT_TYPE) => Promise<void>\n  sendMessage: (\n    payload: ChatSendRequestPayload,\n    signal: TextSignal,\n    aiAgentType: AI_AGENT_TYPE,\n    type: AgentMessageType,\n    updateMessage?: boolean,\n    messageContent?: ChatMessage,\n  ) => void\n  generationMessage: ChatMessage | undefined\n  chatMessages: ChatMessage[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/AI/components/ws/utils.ts",
    "content": "import { KnowledgeFile } from \"@illa-public/public-types\"\n\nexport const formatMessageString = (\n  text: string,\n  knowledgeFiles?: KnowledgeFile[],\n) => {\n  let res = text\n  if (!knowledgeFiles || knowledgeFiles.length === 0) return res\n  const fileString = knowledgeFiles\n    .map((file) => {\n      return `File name: [${file.name}]\\nFile content: [\\n${file.value}\\n]\n    `\n    })\n    .join(\"\\n\\n\")\n\n  return `${res}\\n${fileString}`\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/ActionEditor/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport { FC, useRef } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Divider } from \"@illa-design/react\"\nimport ActionGuidePanel from \"@/page/App/components/Actions/ActionGuidePanel\"\nimport { ActionList } from \"@/page/App/components/Actions/ActionList\"\nimport { ActionPanel } from \"@/page/App/components/Actions/ActionPanel\"\nimport { DragBar } from \"@/page/App/components/Actions/DragBar\"\nimport { getActionMixedList } from \"@/redux/currentApp/action/actionSelector\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { resourceContextHelper } from \"@/utils/mixpanelHelper\"\nimport { applyActionEditorStyle, contentContainerStyle } from \"./styles\"\n\nconst ActionEditorDefaultHeight = 320\n\nexport const ActionEditor: FC = () => {\n  const panelRef = useRef<HTMLDivElement | null>(null)\n  const actionLists = useSelector(getActionMixedList)\n\n  return (\n    <div\n      css={applyActionEditorStyle(ActionEditorDefaultHeight)}\n      onClick={() => {\n        FocusManager.switchFocus(\"action\")\n      }}\n      ref={panelRef}\n      data-onboarding-action=\"actionEditor\"\n    >\n      <DragBar resizeRef={panelRef} minHeight={ActionEditorDefaultHeight} />\n      <Divider direction=\"horizontal\" />\n      <div css={contentContainerStyle}>\n        <MixpanelTrackProvider\n          basicTrack={resourceContextHelper(\"editor_new\")}\n          pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR}\n        >\n          <ActionList />\n        </MixpanelTrackProvider>\n        {actionLists.length > 0 ? (\n          <MixpanelTrackProvider\n            pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR}\n            basicTrack={resourceContextHelper(\"editor_resource_new\")}\n          >\n            <ActionPanel />\n          </MixpanelTrackProvider>\n        ) : (\n          <ActionGuidePanel />\n        )}\n      </div>\n    </div>\n  )\n}\n\nActionEditor.displayName = \"ActionEditor\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/ActionEditor/styles.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport function applyActionEditorStyle(h: number) {\n  return css`\n    position: relative;\n    width: 100%;\n    height: ${h}px;\n  `\n}\n\nexport const contentContainerStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: row;\n  overflow: hidden;\n  height: 100%;\n`\n\nexport const optionLabelStyle = css`\n  height: 38px;\n  display: flex;\n  font-size: 14px;\n  font-weight: 500;\n  padding: 8px 24px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  align-items: center;\n`\n\nexport const configItem = css`\n  display: flex;\n  height: 48px;\n  align-items: center;\n  flex-direction: row;\n  padding-left: 24px;\n`\n\nexport const configItemTip = css`\n  font-size: 14px;\n  font-weight: 400;\n  margin-left: 192px;\n  padding-bottom: 8px;\n  line-height: 22px;\n  padding-left: 24px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n\nexport const connectType = css`\n  display: flex;\n  height: 38px;\n  align-items: center;\n  padding-left: 24px;\n`\n\nexport const labelContainer = css`\n  display: flex;\n  justify-content: end;\n  min-width: 176px;\n`\n\nexport const connectTypeStyle = css`\n  font-size: 14px;\n  height: 22px;\n  display: flex;\n  align-items: center;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  margin-left: 16px;\n`\n\nexport function applyConfigItemLabelText(\n  color: string,\n  margin?: boolean,\n): SerializedStyles {\n  let marginLeft = css``\n  if (margin) {\n    marginLeft = css`\n      margin-left: 4px;\n    `\n  }\n  return css`\n    font-size: 14px;\n    color: ${color};\n    font-weight: 500;\n    ${marginLeft};\n  `\n}\n\nexport const errorMsgStyle: SerializedStyles = css`\n  position: relative;\n  font-size: 14px;\n  padding-left: 24px;\n  line-height: 22px;\n  color: ${getColor(\"orange\", \"03\")};\n`\n\nexport const errorIconStyle: SerializedStyles = css`\n  position: absolute;\n  font-size: 16px;\n  line-height: 0;\n  top: 3px;\n  left: 0;\n`\n\nexport const privateKeyItem = css`\n  display: flex;\n  width: 100%;\n  padding-top: 8px;\n  padding-left: 24px;\n  align-items: flex-start;\n`\n\nexport const getOAuthStatusContentStyle = (isSuccess: boolean) => {\n  return css`\n    width: 100%;\n    padding: 9px 16px;\n    display: flex;\n    gap: 8px;\n    height: 40px;\n    background: ${isSuccess\n      ? getColor(\"green\", \"08\")\n      : getColor(\"orange\", \"08\")};\n    border-radius: 4px;\n    align-items: center;\n  `\n}\n\nexport const oAuthStatusContainerStyle = css`\n  width: 100%;\n  padding: 8px 24px;\n`\n\nexport const oAuthErrorIconStyle: SerializedStyles = css`\n  font-size: 16px;\n  color: ${getColor(\"orange\", \"03\")};\n`\n\nexport const agentActionStyle = (size: string) => css`\n  width: ${size};\n  height: ${size};\n  flex-shrink: 0;\n  border-radius: 4px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/Components/BuildAppOnEmpty/BuildByDatabase/index.tsx",
    "content": "import {\n  BuildActionInfo,\n  CreateFromResourceModal,\n  REPORT_PARAMETER,\n  RESOURCE_TYPE,\n  fetchBatchCreateAction,\n} from \"@illa-public/create-app\"\nimport { getIconFromWidgetType } from \"@illa-public/icon\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackContext,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport { ComponentTreeNode, Resource } from \"@illa-public/public-types\"\nimport { AnimatePresence } from \"framer-motion\"\nimport { FC, useCallback, useContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Button, getColor } from \"@illa-design/react\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { getAppId } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getAllResources } from \"@/redux/resource/resourceSelector\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { resourceContextHelper } from \"@/utils/mixpanelHelper\"\nimport { getCurrentTeamID } from \"@/utils/team\"\nimport { containerStyle, paddingStyle, textContentStyle } from \"./style\"\n\nconst BuildByDatabase: FC = () => {\n  const formIcon = getIconFromWidgetType(\"FORM_WIDGET\", \"24px\")\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n  const teamID = useSelector(getCurrentTeamID)!\n  const appID = useSelector(getAppId)!\n  const resourceList = useSelector(getAllResources) || []\n  const [showCreateFromResourceModal, setShowCreateFromResourceModal] =\n    useState(false)\n\n  const { track } = useContext(MixpanelTrackContext)\n\n  const createFromResourceCallback = async (\n    appInfo: ComponentTreeNode,\n    actionsInfo: BuildActionInfo[],\n  ) => {\n    return new Promise(async (resolve, reject) => {\n      try {\n        dispatch(\n          componentsActions.deleteComponentNodeReducer({\n            displayNames: [\"page1\"],\n          }),\n        )\n        dispatch(componentsActions.addComponentReducer(appInfo.childrenNode))\n        const actions = await fetchBatchCreateAction(teamID, appID, actionsInfo)\n        DisplayNameGenerator.updateDisplayNameList(appInfo, actions)\n        dispatch(actionActions.batchAddActionItemReducer(actions))\n        resolve(undefined)\n      } catch (error) {\n        reject(error)\n      }\n    })\n  }\n\n  const handleUpdateResource = useCallback(\n    (resource: Resource) => {\n      dispatch(resourceActions.addResourceItemReducer(resource))\n    },\n    [dispatch],\n  )\n\n  const handleClickFromResource = () => {\n    track?.(\n      ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n      {\n        element: \"create_app_modal_db\",\n        parameter1: REPORT_PARAMETER.BLANK_APP,\n      },\n      \"both\",\n    )\n    setShowCreateFromResourceModal(true)\n  }\n\n  return (\n    <>\n      <div css={paddingStyle}>\n        <div css={containerStyle}>\n          <div css={textContentStyle}>\n            {formIcon}\n            <span>{t(\"new_dashboard.create_new.generate_crud_app_fr\")}</span>\n          </div>\n          <Button\n            fullWidth\n            onClick={handleClickFromResource}\n            colorScheme={getColor(\"grayBlue\", \"02\")}\n          >\n            {t(\"new_dashboard.create_from_resource.input_type_option.create\")}\n          </Button>\n        </div>\n      </div>\n      <MixpanelTrackProvider\n        basicTrack={resourceContextHelper(REPORT_PARAMETER.BLANK_APP_CREATE)}\n        pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR}\n      >\n        <AnimatePresence>\n          {showCreateFromResourceModal && (\n            <CreateFromResourceModal\n              updateResourceList={handleUpdateResource}\n              resourceList={resourceList.filter((item) =>\n                Object.values(RESOURCE_TYPE).includes(\n                  item?.resourceType as RESOURCE_TYPE,\n                ),\n              )}\n              createCallBack={createFromResourceCallback}\n              closeModal={() => setShowCreateFromResourceModal(false)}\n            />\n          )}\n        </AnimatePresence>\n      </MixpanelTrackProvider>\n    </>\n  )\n}\nexport default BuildByDatabase\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/Components/BuildAppOnEmpty/BuildByDatabase/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { DATABASE_CARD_WIDTH } from \"../constants\"\nimport { templateCardKeyframes } from \"../style\"\n\nexport const paddingStyle = css`\n  padding-bottom: 4px;\n`\n\nexport const containerStyle = css`\n  width: ${DATABASE_CARD_WIDTH}px;\n  flex: none;\n  height: 156px;\n  display: flex;\n  padding: 16px;\n  transform: translateY(100%);\n  flex-direction: column;\n  justify-content: center;\n  align-items: flex-start;\n  gap: 8px;\n  border-radius: 8px;\n  border: 1px solid ${getColor(\"grayBlue\", \"09\")};\n  background: ${getColor(\"white\", \"01\")};\n  box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.09);\n  animation: show 0.3s ease-in-out 0.3s;\n  animation-fill-mode: forwards;\n  ${templateCardKeyframes};\n`\n\nexport const textContentStyle = css`\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: flex-start;\n  gap: 8px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 18px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/Components/BuildAppOnEmpty/BuildByTemplate/index.tsx",
    "content": "import {\n  AppTemplateCard,\n  CreateFromTemplateModal,\n  REPORT_PARAMETER,\n  fetchBatchCreateAction,\n} from \"@illa-public/create-app\"\nimport { ProductMarketApp } from \"@illa-public/market-app\"\nimport {\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackContext,\n} from \"@illa-public/mixpanel-utils\"\nimport { AnimatePresence } from \"framer-motion\"\nimport { FC, useContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { NextIcon } from \"@illa-design/react\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { getAppId } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { fetchPubicAppInitData } from \"@/services/apps\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { getCurrentTeamID } from \"@/utils/team\"\nimport {\n  containerStyle,\n  moreContainerStyle,\n  moreContentStyle,\n  templateCardContainerStyle,\n} from \"./style\"\n\ninterface BuildByTemplateProps {\n  templateList: ProductMarketApp[]\n  showCardCount: number\n  showAnimation: boolean\n  handleShowPreview: (src?: string) => void\n}\n\nconst BuildByTemplate: FC<BuildByTemplateProps> = ({\n  templateList,\n  showCardCount,\n  showAnimation,\n  handleShowPreview,\n}) => {\n  const [showCreateFromTemplateModal, setShowCreateFromTemplateModal] =\n    useState(false)\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n  const { track } = useContext(MixpanelTrackContext)\n  const teamID = useSelector(getCurrentTeamID)!\n  const appID = useSelector(getAppId)!\n\n  const handleForkApp = async (appId: string, teamIdentifier?: string) => {\n    return new Promise(async (resolve, reject) => {\n      try {\n        const { data } = await fetchPubicAppInitData(\n          appId,\n          \"-2\",\n          teamIdentifier,\n        )\n        dispatch(\n          componentsActions.deleteComponentNodeReducer({\n            displayNames: [\"page1\"],\n          }),\n        )\n        dispatch(\n          componentsActions.addComponentReducer(data.components.childrenNode),\n        )\n        DisplayNameGenerator.updateDisplayNameList(\n          data.components,\n          data.actions,\n        )\n        dispatch(\n          componentsActions.setComponentPropsReducer({\n            displayName: \"root\",\n            updateSlice: data.components.props!,\n          }),\n        )\n        const actions = await fetchBatchCreateAction(\n          teamID,\n          appID,\n          data.actions,\n        )\n        dispatch(actionActions.batchAddActionItemReducer(actions))\n        resolve(undefined)\n      } catch (error) {\n        reject(error)\n      }\n    })\n  }\n\n  const handleShowMore = () => {\n    track?.(\n      ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n      {\n        element: \"create_app_modal_more\",\n        parameter1: REPORT_PARAMETER.MORE_TEMPLATE,\n      },\n      \"both\",\n    )\n    track?.(\n      ILLA_MIXPANEL_EVENT_TYPE.SHOW,\n      {\n        element: \"create_app_modal\",\n        parameter1: REPORT_PARAMETER.MORE_TEMPLATE,\n      },\n      \"both\",\n    )\n    setShowCreateFromTemplateModal(true)\n  }\n\n  return (\n    <>\n      <div css={containerStyle}>\n        {templateList.slice(0, showCardCount).map((info, i) => {\n          const { app, marketplace } = info || {}\n          return (\n            <div\n              key={app?.appId || i}\n              css={templateCardContainerStyle(i, showAnimation)}\n              onMouseEnter={() => handleShowPreview(marketplace?.config?.cover)}\n              onMouseLeave={() => handleShowPreview()}\n            >\n              <AppTemplateCard\n                bd=\"none\"\n                w=\"200px\"\n                teamIdentifier={marketplace?.contributorTeam?.teamIdentifier}\n                handleForkApp={async (\n                  appId: string,\n                  teamIdentifier?: string,\n                ) => {\n                  track?.(\n                    ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                    {\n                      element: \"create_app_modal_use_template\",\n                      parameter1: REPORT_PARAMETER.BLANK_APP,\n                    },\n                    \"both\",\n                  )\n                  handleForkApp(appId, teamIdentifier)\n                }}\n                appID={app?.appId}\n                cover={marketplace?.config?.cover}\n                appName={app?.appName}\n              />\n            </div>\n          )\n        })}\n        <div css={moreContainerStyle(showCardCount)} onClick={handleShowMore}>\n          <div css={moreContentStyle}>\n            <span>{t(\"new_dashboard.create_new.more\")}</span>\n            <NextIcon size=\"16px\" />\n          </div>\n        </div>\n      </div>\n      <AnimatePresence>\n        {showCreateFromTemplateModal && (\n          <CreateFromTemplateModal\n            hiddenCreateBlank\n            handleForkApp={async (appId: string, teamIdentifier?: string) => {\n              track?.(\n                ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                {\n                  element: \"create_app_modal_use_template\",\n                  parameter1: REPORT_PARAMETER.CREATE_APP_MODAL,\n                },\n                \"both\",\n              )\n              handleForkApp(appId, teamIdentifier)\n            }}\n            closeModal={() => setShowCreateFromTemplateModal(false)}\n          />\n        )}\n      </AnimatePresence>\n    </>\n  )\n}\nexport default BuildByTemplate\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/Components/BuildAppOnEmpty/BuildByTemplate/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { MORE_CARD_WIDTH } from \"../constants\"\nimport { templateCardKeyframes } from \"../style\"\n\nexport const containerStyle = css`\n  display: flex;\n  align-items: flex-start;\n  height: 100%;\n  box-sizing: content-box;\n  padding-bottom: 4px;\n  overflow-y: hidden;\n  overflow-x: auto;\n  gap: 16px;\n`\n\nexport const templateCardContainerStyle = (\n  index: number,\n  showAnimation: boolean,\n) => {\n  const animation = showAnimation\n    ? css`\n        transform: translateY(100%);\n        animation: show 0.3s ease-in-out ${0.3 + 0.02 * (index + 1)}s;\n        animation-fill-mode: forwards;\n        ${templateCardKeyframes};\n      `\n    : css``\n  return css`\n    min-height: 156px;\n    box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.09);\n    border-radius: 8px;\n    overflow: hidden;\n    border: 1px solid ${getColor(\"grayBlue\", \"09\")};\n    ${animation};\n  `\n}\n\nexport const templateCardStyle = css`\n  border: none;\n`\n\nexport const moreContainerStyle = (index: number) => css`\n  display: flex;\n  cursor: pointer;\n  width: ${MORE_CARD_WIDTH}px;\n  flex: none;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  gap: 12px;\n  height: 100%;\n  border-radius: 8px;\n  border: 1px solid ${getColor(\"grayBlue\", \"09\")};\n  box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.09);\n  transform: translateY(100%);\n  animation: show 0.3s ease-in-out ${0.3 + 0.02 * (index + 1)}s;\n  animation-fill-mode: forwards;\n  ${templateCardKeyframes};\n`\n\nexport const moreContentStyle = css`\n  display: flex;\n  padding: 0px 8px;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  gap: 4px;\n  color: ${getColor(\"techPurple\", \"03\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 22px;\n  text-transform: capitalize;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/Components/BuildAppOnEmpty/PreviewAppImage/index.tsx",
    "content": "import { FC } from \"react\"\nimport { containerStyle } from \"./style\"\n\ninterface PreviewAppImageProps {\n  showPreviewSrc: string\n}\n\nconst PreviewAppImage: FC<PreviewAppImageProps> = ({ showPreviewSrc }) => {\n  return (\n    <div css={containerStyle}>\n      <img src={showPreviewSrc} width=\"100%\" />\n    </div>\n  )\n}\n\nexport default PreviewAppImage\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/Components/BuildAppOnEmpty/PreviewAppImage/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  height: 100%;\n  overflow-y: hidden;\n  position: absolute;\n  opacity: 0.5;\n  bottom: 0;\n  top: 0;\n  left: 0;\n  right: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/Components/BuildAppOnEmpty/constants.ts",
    "content": "export const DATABASE_CARD_WIDTH = 224\nexport const CARD_LIST_GAP = 16\nexport const DATABASE_CONTAINER_GAP = 24\nexport const CARD_LIST_SEPARATOR_WIDTH = 1\nexport const MORE_CARD_WIDTH = 89\nexport const CONTAINER_PADDING = 16\nexport const SHOWN_BUILD_APP = \"shownBuildApp\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/Components/BuildAppOnEmpty/index.tsx",
    "content": "import { CARD_NORMAL_WIDTH, fetchTemplateList } from \"@illa-public/create-app\"\nimport IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { ProductMarketApp } from \"@illa-public/market-app\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport { FC, useCallback, useEffect, useMemo, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport useMeasure from \"react-use-measure\"\nimport { CloseIcon, getColor, isObject } from \"@illa-design/react\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport { getAppId } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport {\n  getCurrentAppPageNames,\n  getWidgetCount,\n  searchDSLByDisplayName,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { getIsDragging } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { track } from \"@/utils/mixpanelHelper\"\nimport { ILLABuilderStorage } from \"@/utils/storage\"\nimport BuildByDatabase from \"./BuildByDatabase\"\nimport BuildByTemplate from \"./BuildByTemplate\"\nimport PreviewAppImage from \"./PreviewAppImage\"\nimport {\n  CARD_LIST_GAP,\n  CARD_LIST_SEPARATOR_WIDTH,\n  CONTAINER_PADDING,\n  DATABASE_CARD_WIDTH,\n  DATABASE_CONTAINER_GAP,\n  MORE_CARD_WIDTH,\n  SHOWN_BUILD_APP,\n} from \"./constants\"\nimport {\n  containerHeaderStyle,\n  containerStyle,\n  lineStyle,\n  templateContainerStyle,\n} from \"./style\"\n\nconst BuildAppOnEmpty: FC = () => {\n  const pages = useSelector(getCurrentAppPageNames)\n  const actionList = useSelector(getActionList)\n  const appID = useSelector(getAppId)\n  const widgetCount = useSelector(getWidgetCount)\n  const shownApp = ILLABuilderStorage.getLocalStorage(SHOWN_BUILD_APP)\n  const [containerRef, containerRect] = useMeasure()\n  const [show, setShow] = useState(isObject(shownApp) ? !shownApp[appID] : true)\n  const isDraggingInGlobal = useSelector(getIsDragging)\n\n  const isEmptyApp = useMemo(() => {\n    if (pages.length > 1 || actionList.length > 0 || widgetCount > 0)\n      return false\n    for (let displayName of pages) {\n      const pageNode = searchDSLByDisplayName(displayName)!\n      const bodySectionDisplayName = pageNode.childrenNode[0]\n      const bodySectionNode = searchDSLByDisplayName(bodySectionDisplayName)!\n      if (bodySectionNode.childrenNode.length > 1) return false\n    }\n    return true\n  }, [actionList.length, pages, widgetCount])\n\n  const handleCloseBuildApp = useCallback(() => {\n    setShow(false)\n    const localShownBuildApp =\n      ILLABuilderStorage.getLocalStorage(SHOWN_BUILD_APP) || {}\n    ILLABuilderStorage.setLocalStorage(SHOWN_BUILD_APP, {\n      ...localShownBuildApp,\n      [appID]: true,\n    })\n  }, [appID])\n\n  const [templateList, setTemplateList] = useState<ProductMarketApp[]>([])\n  const [showAnimation, setShowAnimation] = useState(true)\n  const [showPreviewSrc, setShowPreviewSrc] = useState<string>()\n\n  const { showCardCount, headerWidth } = useMemo(() => {\n    const otherWidth =\n      DATABASE_CARD_WIDTH +\n      CARD_LIST_SEPARATOR_WIDTH +\n      MORE_CARD_WIDTH +\n      DATABASE_CONTAINER_GAP * 2\n\n    const count = Math.floor(\n      (containerRect.width - CONTAINER_PADDING * 2 - otherWidth) /\n        (CARD_NORMAL_WIDTH + CARD_LIST_GAP),\n    )\n\n    const showCardCount = count < 1 ? 1 : count\n    return {\n      showCardCount,\n      headerWidth:\n        otherWidth + showCardCount * (CARD_NORMAL_WIDTH + CARD_LIST_GAP),\n    }\n  }, [containerRect.width])\n\n  const finalTemplateList =\n    templateList.length > 0 ? templateList : new Array(showCardCount).fill({})\n\n  const handleAnimateEnd = () => {\n    setShowAnimation(false)\n  }\n\n  const handleShowPreview = (src?: string) => {\n    setShowPreviewSrc(src)\n  }\n\n  useEffect(() => {\n    const controller = new AbortController()\n    fetchTemplateList({}, controller.signal).then((res) => {\n      setTemplateList(res.data.products)\n    })\n    return () => {\n      controller.abort()\n    }\n  }, [])\n\n  useEffect(() => {\n    if (!isEmptyApp) {\n      handleCloseBuildApp()\n    }\n  }, [handleCloseBuildApp, isEmptyApp])\n\n  if (!show || !isEmptyApp) {\n    return null\n  }\n\n  return (\n    <>\n      <MixpanelTrackProvider\n        basicTrack={track}\n        pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR}\n      >\n        <div css={containerStyle(isDraggingInGlobal)} ref={containerRef}>\n          <div css={containerHeaderStyle(headerWidth)}>\n            <IconHotSpot onClick={handleCloseBuildApp}>\n              <CloseIcon size=\"12px\" color={getColor(\"grayBlue\", \"02\")} />\n            </IconHotSpot>\n          </div>\n          <div css={templateContainerStyle} onAnimationEnd={handleAnimateEnd}>\n            <BuildByDatabase />\n            <span css={lineStyle} />\n            <BuildByTemplate\n              templateList={finalTemplateList}\n              showCardCount={showCardCount}\n              showAnimation={showAnimation}\n              handleShowPreview={handleShowPreview}\n            />\n          </div>\n        </div>\n      </MixpanelTrackProvider>\n      {!!showPreviewSrc && <PreviewAppImage showPreviewSrc={showPreviewSrc} />}\n    </>\n  )\n}\n\nexport default BuildAppOnEmpty\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/Components/BuildAppOnEmpty/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { CARD_LIST_SEPARATOR_WIDTH } from \"./constants\"\n\nexport const templateCardKeyframes = css`\n  @-webkit-keyframes show {\n    from {\n      transform: translateY(100%);\n    }\n    to {\n      transform: translateY(0);\n    }\n  }\n  @keyframes show {\n    from {\n      transform: translateY(100%);\n    }\n    to {\n      transform: translateY(0);\n    }\n  }\n`\n\nexport const containerStyle = (isDraggingInGlobal: boolean) => css`\n  width: 100%;\n  display: flex;\n  background-color: ${getColor(\"white\", \"01\")};\n  padding: 16px 16px 0 16px;\n  flex-direction: column;\n  align-items: center;\n  gap: 16px;\n  position: absolute;\n  z-index: 99;\n  bottom: 0;\n  overflow-y: hidden;\n  pointer-events: ${isDraggingInGlobal ? \"none\" : \"auto\"};\n  opacity: ${isDraggingInGlobal ? 0.5 : 1};\n`\n\nexport const containerHeaderStyle = (width: number) => css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  width: ${width}px;\n  display: flex;\n  cursor: pointer;\n  justify-content: flex-end;\n`\n\nexport const templateContainerStyle = css`\n  width: 100%;\n  display: flex;\n  height: 156px;\n  /* overflow-y: hidden; */\n  padding-bottom: 12px;\n  box-sizing: content-box;\n  align-items: center;\n  justify-content: center;\n  gap: 24px;\n  transform: translateY(100%);\n  animation: show 0.3s ease-in-out 0.3s;\n  animation-fill-mode: forwards;\n  ${templateCardKeyframes};\n`\n\nexport const lineStyle = css`\n  width: ${CARD_LIST_SEPARATOR_WIDTH}px;\n  height: 64px;\n  background-color: ${getColor(\"grayBlue\", \"08\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/index.tsx",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport { forwardRef, useSyncExternalStore } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { isObject } from \"@illa-design/react\"\nimport { DotPanel } from \"@/page/App/components/DotPanel\"\nimport {\n  getIsILLAEditMode,\n  getIsILLAPreviewMode,\n} from \"@/redux/config/configSelector\"\nimport { getAppId } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { ILLABuilderStorage } from \"@/utils/storage\"\nimport { UploadDetailButton } from \"../UploadDetail\"\nimport { updateFileDetailStore } from \"../UploadDetail/store\"\nimport BuildAppOnEmpty from \"./Components/BuildAppOnEmpty\"\nimport { SHOWN_BUILD_APP } from \"./Components/BuildAppOnEmpty/constants\"\nimport { CanvasPanelProps } from \"./interface\"\nimport { applyScaleContainerStyle } from \"./style\"\n\nexport const CanvasPanel = forwardRef<HTMLDivElement, CanvasPanelProps>(\n  (props, ref) => {\n    const { ...otherProps } = props\n\n    const isEditMode = useSelector(getIsILLAEditMode)\n    const appID = useSelector(getAppId)\n    const isEditPreviewMode = useSelector(getIsILLAPreviewMode)\n    const executionResult = useSelector(getExecutionResult)\n    const uploadFiles = useSyncExternalStore(\n      updateFileDetailStore.subscribe,\n      updateFileDetailStore.getSnapshot,\n    )\n    const localShownBuildAppOnEmpty =\n      ILLABuilderStorage.getLocalStorage(SHOWN_BUILD_APP)\n\n    const showBuildAppOnEmpty =\n      isEditMode &&\n      isCloudVersion &&\n      (!isObject(localShownBuildAppOnEmpty) ||\n        !localShownBuildAppOnEmpty[appID])\n\n    if (!executionResult || !executionResult.root) {\n      return null\n    }\n\n    return (\n      <div\n        {...otherProps}\n        ref={ref}\n        css={applyScaleContainerStyle(isEditPreviewMode, isEditMode)}\n      >\n        <DotPanel />\n        {uploadFiles.length > 0 && <UploadDetailButton />}\n        {showBuildAppOnEmpty && <BuildAppOnEmpty />}\n      </div>\n    )\n  },\n)\n\nCanvasPanel.displayName = \"CanvasPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/interface.ts",
    "content": "import { HTMLAttributes } from \"react\"\n\nexport interface CanvasPanelProps extends HTMLAttributes<HTMLDivElement> {\n  scale?: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/CanvasPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const applyScaleContainerStyle = (\n  isEditorPreview: boolean,\n  isEditorMode: boolean,\n) => {\n  return css`\n    box-sizing: border-box;\n    min-width: 148px;\n    height: 100%;\n    min-height: 280px;\n    background: ${isEditorPreview ? \"#f7f8fa\" : \"#fff\"};\n    overflow: auto;\n    flex: 1;\n    position: relative;\n    ${isEditorMode &&\n    `* {\n      user-select: none;\n    }`}\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/ComponentManager/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, Suspense, useEffect, useRef, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { SimpleTabs, getRenderBody } from \"@/components/Tabs\"\nimport { COMPONENT_MANAGER_TABS } from \"@/components/Tabs/constant\"\nimport { getSelectedComponentDisplayNames } from \"@/redux/config/configSelector\"\nimport { getCurrentPageDisplayName } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport WidgetLoading from \"@/widgetLibrary/PublicSector/WidgetLoading\"\nimport { containerStyle } from \"./style\"\n\nexport const ComponentsManager: FC = () => {\n  const [activeKey, setActiveKey] = useState(\"Insert\")\n\n  const selectedDisplayNames = useSelector(getSelectedComponentDisplayNames)\n  const currentPageDisplayName = useSelector(getCurrentPageDisplayName)\n  const prevPageDisplayName = useRef<string>(currentPageDisplayName)\n  const isClickChange = useRef<boolean>(false)\n\n  useEffect(() => {\n    if (!isClickChange.current) {\n      if (selectedDisplayNames.length > 0) {\n        setActiveKey(\"Inspect\")\n      } else {\n        if (activeKey === \"Page\") {\n          setActiveKey(\"Page\")\n        }\n        if (activeKey === \"Inspect\") {\n          setActiveKey(\"Insert\")\n        }\n      }\n    }\n    if (prevPageDisplayName.current !== currentPageDisplayName) {\n      prevPageDisplayName.current = currentPageDisplayName\n    }\n    isClickChange.current = false\n  }, [activeKey, currentPageDisplayName, selectedDisplayNames])\n\n  const handleClickChangeTab = (activeKey: string) => {\n    switch (activeKey) {\n      case \"Page\":\n        FocusManager.switchFocus(\"page_config\")\n        break\n      case \"Inspect\":\n        FocusManager.switchFocus(\"components_config\")\n        break\n      case \"Insert\":\n        FocusManager.switchFocus(\"widget_picker\")\n        break\n    }\n    setActiveKey(activeKey)\n    isClickChange.current = true\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"right_tab\",\n      parameter2: activeKey,\n    })\n  }\n\n  return (\n    <div css={containerStyle} data-onboarding-comp=\"componentsManager\">\n      <SimpleTabs\n        items={COMPONENT_MANAGER_TABS}\n        activeKey={activeKey}\n        handleClickChangeTab={handleClickChangeTab}\n      />\n      <Suspense fallback={<WidgetLoading />}>\n        {getRenderBody(activeKey, COMPONENT_MANAGER_TABS)}\n      </Suspense>\n    </div>\n  )\n}\n\nexport default ComponentsManager\n\nComponentsManager.displayName = \"ComponentsManager\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/ComponentManager/style.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { RIGHT_PANEL_WIDTH } from \"@/style\"\n\nexport const componentPanelCss = css`\n  display: inline-flex;\n  justify-content: center;\n`\n\nexport const menuHeaderWrapperStyle = css`\n  display: flex;\n  width: 100%;\n  padding: 13px 12px;\n  gap: 10px;\n`\n\nexport const applyTabItemStyle = (isActive: boolean) => css`\n  padding: 1px 4px;\n  height: 24px;\n  border-radius: 4px;\n  font-size: 14px;\n  cursor: pointer;\n  font-weight: ${isActive ? 500 : 400};\n  color: ${isActive ? getColor(\"grayBlue\", \"02\") : getColor(\"grayBlue\", \"03\")};\n  :hover {\n    background-color: ${getColor(\"grayBlue\", \"09\")};\n  }\n`\n\nexport const containerStyle = css`\n  box-sizing: border-box;\n  width: ${RIGHT_PANEL_WIDTH}px;\n  flex: none;\n  display: flex;\n  flex-direction: column;\n  height: 100%;\n  border-left: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  background: ${getColor(\"white\", \"01\")};\n  position: relative;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/ActionSpaceTree/index.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { PanelBar } from \"@/components/PanelBar\"\nimport { getSelectedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport { getActionExecutionResultWithOutIgnoreKey } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { BaseDataItem } from \"../BaseDataItem\"\n\nexport const ActionSpaceTree: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n\n  const actionExecution = useSelector(getActionExecutionResultWithOutIgnoreKey)\n  const actionList = useSelector(getActionList)\n  const selectedAction = useSelector(getSelectedAction)\n\n  const handleActionSelect = useCallback(\n    (selectedKey: string) => {\n      const action = actionList.find((item) => item.displayName === selectedKey)\n      action && dispatch(configActions.changeSelectedAction(action))\n    },\n    [actionList, dispatch],\n  )\n\n  return (\n    <PanelBar\n      title={`${t(\"editor.data_work_space.actions_title\")}(${\n        Object.keys(actionExecution).length\n      })`}\n      onIllaFocus={() => {\n        FocusManager.switchFocus(\"data_action\")\n      }}\n      destroyChildrenWhenClose\n    >\n      {Object.keys(actionExecution).map((actionDisplayName) => (\n        <BaseDataItem\n          key={actionDisplayName}\n          title={actionDisplayName}\n          level={0}\n          value={actionExecution[actionDisplayName] as Record<string, unknown>}\n          haveMoreAction\n          selectedDisplayNames={[selectedAction?.displayName ?? \"\"]}\n          onClick={handleActionSelect}\n          dataType=\"action\"\n          type={\n            (actionExecution[actionDisplayName] as Record<string, unknown>)\n              .actionType as string\n          }\n        />\n      ))}\n    </PanelBar>\n  )\n}\n\nActionSpaceTree.displayName = \"ActionSpaceTree\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/BaseDataItem/index.tsx",
    "content": "import { getIconFromWidgetType } from \"@illa-public/icon\"\nimport IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { getDocLink } from \"@illa-public/public-configs\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { FC, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CaretRightIcon } from \"@illa-design/react\"\nimport StateIcon from \"@/assets/dataWorkspace/state.svg?react\"\nimport { MovableModal } from \"@/components/Modal/movableModal\"\nimport { panelBarItemContainerAnimationVariants } from \"@/components/PanelBar/style\"\nimport { ViewItemShape } from \"@/page/App/components/InspectPanel/PanelSetters/TabsSetter/TabListSetter/interface\"\nimport { getExpandedWidgets } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { MoreAction } from \"../MoreAction\"\nimport { WorkSpaceTreeNode } from \"../WorkSpaceTreeItem/WorkSpaceTreeNode\"\nimport { BaseDataItemProps } from \"./interface\"\nimport {\n  applyExpandIconStyle,\n  expendContainerStyle,\n  iconContainerStyle,\n  itemContainerStyle,\n  itemContentStyle,\n  modalBodyContainerStyle,\n  outerContainerStyle,\n  rectangleStyle,\n  titleAndIconContainerStyle,\n  titleStyle,\n} from \"./style\"\n\nconst formatModalTitle = (index: number) => {\n  switch (index) {\n    case 0: {\n      return \"header\"\n    }\n    case 1: {\n      return \"body\"\n    }\n    case 2: {\n      return \"footer\"\n    }\n    default: {\n      return \"container\"\n    }\n  }\n}\n\nexport const BaseDataItem: FC<BaseDataItemProps> = (props) => {\n  const {\n    title,\n    fakeTitle,\n    type,\n    level,\n    canExpand,\n    haveMoreAction,\n    value,\n    onClick,\n    dataType,\n    selectedDisplayNames,\n  } = props\n  const [isOpenCodeModal, setIsOpenCodeModal] = useState(false)\n  const expandedStatus = useSelector(getExpandedWidgets)\n  const isExpanded = (canExpand ?? false) && (expandedStatus?.[title] ?? false)\n\n  const isSelected = selectedDisplayNames?.includes(title) ?? false\n  const dispatch = useDispatch()\n  const handleClickOnContainer = () => {\n    onClick?.(title, type ?? \"\")\n  }\n\n  const handleClickOnExpandIcon = (e: React.MouseEvent) => {\n    e.stopPropagation()\n    if (!isExpanded) {\n      dispatch(configActions.addExpandedWidgetReducer([title]))\n    } else {\n      dispatch(configActions.removeExpandWidgetReducer([title]))\n    }\n  }\n\n  return (\n    <>\n      <div\n        css={outerContainerStyle(isSelected, !!canExpand)}\n        onClick={handleClickOnContainer}\n        id={`${title}-baseDataItemContainer`}\n      >\n        <div css={itemContainerStyle(level)}>\n          <div css={expendContainerStyle}>\n            <span\n              css={applyExpandIconStyle(isExpanded, !!canExpand, isSelected)}\n              onClick={handleClickOnExpandIcon}\n              id=\"expand-icon\"\n            >\n              <CaretRightIcon />\n            </span>\n            {!!type && level >= 1 && <div css={rectangleStyle} />}\n            <div css={titleAndIconContainerStyle}>\n              {!!type && getIconFromWidgetType(type, \"16px\")}\n              <span css={titleStyle}>{fakeTitle ?? title}</span>\n            </div>\n          </div>\n          <div css={iconContainerStyle} id=\"action-bar\">\n            {((dataType === \"widget\" &&\n              (value.$widgetType as string).endsWith(\"_WIDGET\")) ||\n              dataType !== \"widget\") && (\n              <IconHotSpot onClick={() => setIsOpenCodeModal(true)}>\n                <StateIcon />\n              </IconHotSpot>\n            )}\n            {haveMoreAction && (\n              <MoreAction displayName={title} actionType={dataType} />\n            )}\n          </div>\n        </div>\n      </div>\n\n      {dataType === \"widget\" && Array.isArray(value.$childrenNode) && (\n        <AnimatePresence>\n          {isExpanded && (\n            <motion.div\n              css={itemContentStyle}\n              variants={panelBarItemContainerAnimationVariants}\n              animate={isExpanded ? \"enter\" : \"exit\"}\n              transition={{ duration: 0.2 }}\n              exit=\"exit\"\n            >\n              {value.$childrenNode.map((item, index) => {\n                if (value.$widgetType === \"CONTAINER_WIDGET\") {\n                  if (!(value.viewList as ViewItemShape[])[index]) return null\n                  return (\n                    <BaseDataItem\n                      key={item.displayName}\n                      title={item.displayName}\n                      fakeTitle={\n                        (value.viewList as ViewItemShape[])[index].label\n                      }\n                      value={item}\n                      level={level + 1}\n                      dataType=\"widget\"\n                      type={item.$widgetType as string}\n                      canExpand={item.$childrenNode.length > 0}\n                      haveMoreAction={item.$widgetType.endsWith(\"_WIDGET\")}\n                      selectedDisplayNames={selectedDisplayNames}\n                      onClick={onClick}\n                    />\n                  )\n                }\n                if (\n                  value.$widgetType === \"MODAL_WIDGET\" ||\n                  value.$widgetType === \"FORM_WIDGET\"\n                ) {\n                  return (\n                    <BaseDataItem\n                      key={item.displayName}\n                      title={item.displayName}\n                      fakeTitle={formatModalTitle(index)}\n                      value={item}\n                      level={level + 1}\n                      dataType=\"widget\"\n                      type={item.$widgetType as string}\n                      canExpand={item.$childrenNode.length > 0}\n                      haveMoreAction={item.$widgetType.endsWith(\"_WIDGET\")}\n                      selectedDisplayNames={selectedDisplayNames}\n                      onClick={onClick}\n                    />\n                  )\n                }\n                if (\n                  value.$widgetType === \"LIST_WIDGET\" ||\n                  value.$widgetType === \"GRID_LIST_WIDGET\"\n                )\n                  return (\n                    <BaseDataItem\n                      key={item.displayName}\n                      title={item.displayName}\n                      fakeTitle=\"list template\"\n                      value={item}\n                      level={level + 1}\n                      dataType=\"widget\"\n                      type={item.$widgetType as string}\n                      canExpand={item.$childrenNode.length > 0}\n                      haveMoreAction={item.$widgetType.endsWith(\"_WIDGET\")}\n                      selectedDisplayNames={selectedDisplayNames}\n                      onClick={onClick}\n                    />\n                  )\n\n                return (\n                  <BaseDataItem\n                    key={item.displayName}\n                    title={item.displayName}\n                    value={item}\n                    level={level + 1}\n                    dataType=\"widget\"\n                    type={item.$widgetType as string}\n                    canExpand={item.$childrenNode.length > 0}\n                    haveMoreAction={item.$widgetType.endsWith(\"_WIDGET\")}\n                    selectedDisplayNames={selectedDisplayNames}\n                    onClick={onClick}\n                  />\n                )\n              })}\n            </motion.div>\n          )}\n        </AnimatePresence>\n      )}\n      {isOpenCodeModal && (\n        <MovableModal\n          title={title}\n          bodyContent={\n            <div css={modalBodyContainerStyle}>\n              {Object.keys(value)\n                .filter((key) => !key.startsWith(\"$\"))\n                .map((key) => {\n                  return (\n                    <WorkSpaceTreeNode\n                      key={key}\n                      name={key}\n                      value={value[key]}\n                      itemKey={key}\n                      level={0}\n                      parentKey={title}\n                    />\n                  )\n                })}\n            </div>\n          }\n          onClose={() => {\n            setIsOpenCodeModal(false)\n          }}\n          docLink={getDocLink(dataType, type)}\n          defaultPosition={{\n            x:\n              document\n                .querySelector(`#${title}-baseDataItemContainer`)\n                ?.getBoundingClientRect().right ?? 0,\n            y:\n              document\n                .querySelector(`#${title}-baseDataItemContainer`)\n                ?.getBoundingClientRect().top ?? 0,\n            width: 320,\n            height: 214,\n          }}\n        />\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/BaseDataItem/interface.ts",
    "content": "export interface BaseDataItemProps {\n  level: number\n  fakeTitle?: string\n  title: string\n  type?: string\n  canExpand?: boolean\n  haveMoreAction?: boolean\n  value: Record<string, unknown>\n  selectedDisplayNames?: string[]\n  onClick?: (displayName: string, type: string) => void\n  dataType: \"globalData\" | \"action\" | \"widget\"\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/BaseDataItem/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const outerContainerStyle = (\n  isSelected: boolean,\n  canExpand: boolean,\n) => css`\n  width: 100%;\n  background-color: ${isSelected\n    ? getColor(\"techPurple\", \"08\")\n    : getColor(\"white\", \"01\")};\n  cursor: pointer;\n  font-family: \"Fira Code\", monospace;\n  :hover {\n    background-color: ${getColor(\"techPurple\", \"08\")};\n    #action-bar {\n      visibility: visible;\n    }\n    #expand-icon {\n      visibility: ${canExpand ? \"visible\" : \"hidden\"};\n    }\n  }\n  #action-bar {\n    visibility: ${isSelected ? \"visible\" : \"hidden\"};\n  }\n`\n\nexport const itemContainerStyle = (level: number = 0) => css`\n  padding-left: ${level * 16 + (level - 1 >= 0 ? level - 1 : 0) * 4}px;\n  padding-right: 16px;\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n`\n\nexport const expendContainerStyle = css`\n  display: flex;\n  align-items: center;\n`\n\nexport const rectangleStyle = css`\n  width: 4px;\n  height: 100%;\n  flex: none;\n`\n\nexport const titleAndIconContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 4px;\n`\n\nexport const titleStyle = css`\n  font-size: 12px;\n  font-weight: 500;\n  line-height: 24px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const applyExpandIconStyle = (\n  isExpanded: boolean,\n  canExpand: boolean,\n  isSelected: boolean,\n) => css`\n  font-size: 8px;\n  line-height: 0;\n  cursor: pointer;\n  transform-origin: center;\n  transform: rotate(${isExpanded ? 90 : 0}deg);\n  transition: transform 200ms;\n  width: 16px;\n  height: 16px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  flex: none;\n  visibility: ${canExpand ? (isSelected ? \"visible\" : \"hidden\") : \"hidden\"};\n`\n\nexport const iconContainerStyle = css`\n  display: flex;\n  align-items: center;\n  visibility: hidden;\n`\n\nexport const modalBodyContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n`\n\nexport const itemContentStyle = css`\n  font-family: \"Fira Code\", monospace;\n  height: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/ComponentSpaceTree/index.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { PanelBar } from \"@/components/PanelBar\"\nimport { WorkSpaceTreeGroup } from \"@/page/App/Module/DataWorkspace/components/WorkSpaceTreeGroup\"\nimport { getSelectedComponentDisplayNames } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport {\n  getCurrentPageBodyWidgetTree,\n  getCurrentPageFooterWidgetTree,\n  getCurrentPageHeaderWidgetTree,\n  getCurrentPageLeftWidgetTree,\n  getCurrentPageModalWidgetTree,\n  getCurrentPageRightWidgetTree,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport {\n  autoChangeContainersIndexWhenClick,\n  autoChangeWhenClickOnCanvas,\n} from \"@/utils/componentNode/search\"\nimport { ClickPosition, FocusManager } from \"@/utils/focusManager\"\nimport { BaseDataItem } from \"../BaseDataItem\"\n\nexport const ComponentSpaceTree: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n\n  const footerSectionTree = useSelector(getCurrentPageFooterWidgetTree)\n  const leftSectionTree = useSelector(getCurrentPageLeftWidgetTree)\n  const rightSectionTree = useSelector(getCurrentPageRightWidgetTree)\n  const headerSectionTree = useSelector(getCurrentPageHeaderWidgetTree)\n  const bodySectionTree = useSelector(getCurrentPageBodyWidgetTree)\n  const modalSectionTree = useSelector(getCurrentPageModalWidgetTree)\n  const selectedComponent = useSelector(getSelectedComponentDisplayNames)\n\n  const handleClick = useCallback(\n    (displayName: string, type: string) => {\n      const clickPosition: ClickPosition = {\n        displayName,\n        type: \"component\",\n        clickPosition: [],\n      }\n      if (type === \"CANVAS\") {\n        displayName = autoChangeWhenClickOnCanvas(displayName)\n        clickPosition.type = \"inner_container\"\n        clickPosition.clickPosition = [0, 0]\n      }\n      FocusManager.switchFocus(\"data_component\", clickPosition)\n      if (type === \"MODAL_WIDGET\") {\n        dispatch(\n          executionActions.updateModalDisplayReducer({\n            displayName,\n            display: true,\n          }),\n        )\n      }\n      if (displayName) {\n        dispatch(configActions.updateSelectedComponent([displayName]))\n        autoChangeContainersIndexWhenClick(displayName)\n        setTimeout(() => {\n          const dom = document.querySelector(\n            `[data-displayname=\"${displayName}\"]`,\n          )\n          dom?.scrollIntoView({ behavior: \"smooth\", block: \"center\" })\n        }, 160)\n      }\n    },\n    [dispatch],\n  )\n\n  return (\n    <PanelBar\n      title={t(\"editor.data_work_space.components_title\")}\n      destroyChildrenWhenClose\n    >\n      {modalSectionTree.length > 0 && (\n        <>\n          <WorkSpaceTreeGroup\n            title={t(\"editor.data_work_space.component_layer.floating\")}\n          >\n            {modalSectionTree.map((tree) => (\n              <BaseDataItem\n                key={tree.displayName}\n                title={tree.displayName}\n                value={tree}\n                level={0}\n                dataType=\"widget\"\n                type={tree.$widgetType as string}\n                canExpand\n                haveMoreAction\n                onClick={handleClick}\n                selectedDisplayNames={selectedComponent}\n              />\n            ))}\n          </WorkSpaceTreeGroup>\n        </>\n      )}\n      <WorkSpaceTreeGroup title={t(\"editor.page.label_name.body\")}>\n        {bodySectionTree.map((tree) => (\n          <BaseDataItem\n            key={tree.displayName}\n            title={tree.displayName}\n            value={tree}\n            level={0}\n            dataType=\"widget\"\n            type={tree.$widgetType as string}\n            canExpand={tree.$childrenNode.length > 0}\n            haveMoreAction\n            onClick={handleClick}\n            selectedDisplayNames={selectedComponent}\n          />\n        ))}\n      </WorkSpaceTreeGroup>\n\n      {headerSectionTree.length > 0 && (\n        <>\n          <WorkSpaceTreeGroup title={t(\"editor.page.label_name.header\")}>\n            {headerSectionTree.map((tree) => (\n              <BaseDataItem\n                key={tree.displayName}\n                title={tree.displayName}\n                value={tree}\n                level={0}\n                dataType=\"widget\"\n                type={tree.$widgetType as string}\n                canExpand={tree.$childrenNode.length > 0}\n                onClick={handleClick}\n                selectedDisplayNames={selectedComponent}\n              />\n            ))}\n          </WorkSpaceTreeGroup>\n        </>\n      )}\n\n      {leftSectionTree.length > 0 && (\n        <>\n          <WorkSpaceTreeGroup title={t(\"editor.page.label_name.left_panel\")}>\n            {leftSectionTree.map((tree) => (\n              <BaseDataItem\n                key={tree.displayName}\n                title={tree.displayName}\n                value={tree}\n                level={0}\n                dataType=\"widget\"\n                type={tree.$widgetType as string}\n                canExpand={tree.$childrenNode.length > 0}\n                haveMoreAction\n                onClick={handleClick}\n                selectedDisplayNames={selectedComponent}\n              />\n            ))}\n          </WorkSpaceTreeGroup>\n        </>\n      )}\n\n      {rightSectionTree.length > 0 && (\n        <>\n          <WorkSpaceTreeGroup title={t(\"editor.page.label_name.right_panel\")}>\n            {rightSectionTree.map((tree) => (\n              <BaseDataItem\n                key={tree.displayName}\n                title={tree.displayName}\n                value={tree}\n                level={0}\n                dataType=\"widget\"\n                type={tree.$widgetType as string}\n                canExpand={tree.$childrenNode.length > 0}\n                haveMoreAction\n                onClick={handleClick}\n                selectedDisplayNames={selectedComponent}\n              />\n            ))}\n          </WorkSpaceTreeGroup>\n        </>\n      )}\n\n      {footerSectionTree.length > 0 && (\n        <>\n          <WorkSpaceTreeGroup title={t(\"editor.page.label_name.footer\")}>\n            {footerSectionTree.map((tree) => (\n              <BaseDataItem\n                key={tree.displayName}\n                title={tree.displayName}\n                value={tree}\n                level={0}\n                dataType=\"widget\"\n                type={tree.$widgetType as string}\n                canExpand={tree.$childrenNode.length > 0}\n                haveMoreAction\n                onClick={handleClick}\n                selectedDisplayNames={selectedComponent}\n              />\n            ))}\n          </WorkSpaceTreeGroup>\n        </>\n      )}\n    </PanelBar>\n  )\n}\n\nComponentSpaceTree.displayName = \"ComponentSpaceTree\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/GlobalsSpaceTree/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { PanelBar } from \"@/components/PanelBar\"\nimport { getGlobalInfoExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { BaseDataItem } from \"../BaseDataItem\"\n\nexport const GlobalsSpaceTree: FC = () => {\n  const { t } = useTranslation()\n\n  const globalInfoList = useSelector(getGlobalInfoExecutionResult)\n\n  return (\n    <PanelBar\n      title={`${t(\"editor.data_work_space.globals_title\")}(${\n        Object.keys(globalInfoList).length\n      })`}\n      onIllaFocus={() => {\n        FocusManager.switchFocus(\"data_global_state\")\n      }}\n      destroyChildrenWhenClose\n    >\n      {Object.keys(globalInfoList).map((key) => (\n        <BaseDataItem\n          key={key}\n          title={key}\n          level={0}\n          value={globalInfoList[key] as Record<string, unknown>}\n          dataType=\"globalData\"\n        />\n      ))}\n    </PanelBar>\n  )\n}\n\nGlobalsSpaceTree.displayName = \"GlobalsSpaceTree\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/GlobalsSpaceTree/interface.ts",
    "content": "export interface CreateGlobalModalProps {\n  onClose: () => void\n  variableName?: string\n  actionType: \"ADD\" | \"UPDATE\"\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/GlobalsSpaceTree/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const modalBodyWrapperStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n`\n\nexport const singleLineWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 8px 0;\n  gap: 16px;\n`\nexport const codeEditorWrapperStyle = css`\n  width: 184px;\n`\n\nexport const footerWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  padding: 8px 0%;\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/LibrariesTree/constants.ts",
    "content": "export const LIBRARIES = [\n  {\n    title: \"lodash@4.17.21\",\n    alias: \"_\",\n    docLink: \"https://lodash.com/docs/4.17.15\",\n  },\n  {\n    title: \"uuid@8.3.2\",\n    alias: \"uuid\",\n    docLink: \"https://www.npmjs.com/package/uuid\",\n  },\n  {\n    title: \"dayjs@1.11.7\",\n    alias: \"dayjs\",\n    docLink: \"https://day.js.org/docs/en/parse/parse\",\n  },\n  {\n    title: \"numbro@2.4.0\",\n    alias: \"numbro\",\n    docLink: \"https://numbrojs.com/\",\n  },\n  {\n    title: \"papaparse@5.4.1\",\n    alias: \"papa\",\n    docLink: \"https://www.papaparse.com/docs\",\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/LibrariesTree/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { PanelBar } from \"@/components/PanelBar\"\nimport { LIBRARIES } from \"./constants\"\nimport { LibrariesItem } from \"./item\"\nimport { libraryContainerStyle } from \"./style\"\n\nexport const LibrarySpaceTree: FC = () => {\n  const { t } = useTranslation()\n  return (\n    <>\n      <PanelBar\n        title={`${t(\"editor.data_work_space.library\")}`}\n        destroyChildrenWhenClose\n      >\n        <div css={libraryContainerStyle}>\n          {LIBRARIES.map((library) => (\n            <LibrariesItem\n              key={library.title}\n              title={library.title}\n              docLink={library.docLink}\n              alias={library.alias}\n            />\n          ))}\n        </div>\n      </PanelBar>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/LibrariesTree/interface.ts",
    "content": "export interface LibrariesItemProps {\n  title: string\n  alias?: string\n  docLink: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/LibrariesTree/item.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC } from \"react\"\nimport { Link } from \"react-router-dom\"\nimport { DocsIcon } from \"@illa-design/react\"\nimport { LibrariesItemProps } from \"./interface\"\nimport {\n  actionGroupContainerStyle,\n  aliasContainerStyle,\n  itemContainerStyle,\n  titleContainerStyle,\n  titleStyle,\n} from \"./style\"\n\nexport const LibrariesItem: FC<LibrariesItemProps> = (props) => {\n  const { title, alias, docLink } = props\n  return (\n    <div css={itemContainerStyle}>\n      <div css={titleContainerStyle}>\n        <span css={titleStyle}>{title}</span>\n        <div css={actionGroupContainerStyle}>\n          <Link to={docLink} target=\"_blank\">\n            <IconHotSpot>\n              <DocsIcon />\n            </IconHotSpot>\n          </Link>\n        </div>\n      </div>\n      <p css={aliasContainerStyle}>{alias ?? title}</p>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/LibrariesTree/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const itemContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  padding: 0 16px;\n`\n\nexport const titleContainerStyle = css`\n  display: flex;\n  width: 100%;\n  justify-content: space-between;\n  align-items: center;\n`\n\nexport const titleStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 12px;\n  font-weight: 500;\n  line-height: 24px;\n`\n\nexport const actionGroupContainerStyle = css`\n  display: flex;\n  align-items: center;\n`\n\nexport const aliasContainerStyle = css`\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 12px;\n  font-weight: 450;\n  line-height: 16px;\n  padding: 0;\n  margin: 0;\n`\n\nexport const libraryContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n  font-family: \"Fira Code\", monospace;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/MoreAction/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC, useContext } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  DropList,\n  DropListItem,\n  Dropdown,\n  MoreIcon,\n  getColor,\n} from \"@illa-design/react\"\nimport { onCopyActionItem } from \"@/page/App/components/Actions/api\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport store from \"@/store\"\nimport { CopyManager } from \"@/utils/copyManager\"\nimport { ShortCutContext } from \"@/utils/shortcut/shortcutProvider\"\nimport { MoreActionProps } from \"./interface\"\n\nexport const MoreAction: FC<MoreActionProps> = (props) => {\n  const { displayName, actionType } = props\n  const { t } = useTranslation()\n  const shortcut = useContext(ShortCutContext)\n\n  const handleClickDelete = () => {\n    shortcut.showDeleteDialog([displayName], actionType)\n  }\n\n  const handleClickCopy = () => {\n    switch (actionType) {\n      case \"action\": {\n        const actionList = getActionList(store.getState())\n        const targetAction = actionList.find(\n          (action) => action.displayName === displayName,\n        )\n        if (targetAction) {\n          onCopyActionItem(targetAction)\n        }\n        break\n      }\n      case \"widget\": {\n        CopyManager.copyComponentNodeByDisplayName([displayName])\n        CopyManager.paste(\"duplicate\")\n        break\n      }\n    }\n  }\n\n  return (\n    <Dropdown\n      dropList={\n        <DropList w=\"200px\">\n          <DropListItem\n            value=\"duplicate\"\n            title={t(\"editor.action.action_list.contextMenu.duplicate\")}\n            onClick={handleClickCopy}\n          />\n          <DropListItem\n            value=\"delete\"\n            title={t(\"editor.action.action_list.contextMenu.delete\")}\n            deleted\n            onClick={handleClickDelete}\n          />\n        </DropList>\n      }\n    >\n      <IconHotSpot inactiveColor={getColor(\"grayBlue\", \"02\")}>\n        <MoreIcon />\n      </IconHotSpot>\n    </Dropdown>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/MoreAction/interface.ts",
    "content": "export interface MoreActionProps {\n  displayName: string\n  actionType: \"action\" | \"widget\" | \"globalData\"\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/PageSpaceTree/components/ActionMenu/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, useCallback, useContext, useEffect } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { DropList, DropListItem } from \"@illa-design/react\"\nimport { getCurrentPageSortedKeys } from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ShortCutContext } from \"@/utils/shortcut/shortcutProvider\"\nimport { ActionMenuProps } from \"./interface\"\n\nexport const ActionMenu: FC<ActionMenuProps> = (props) => {\n  const { pageDisplayName, isParentPage, parentPageName, openRenameModal } =\n    props\n  const { t } = useTranslation()\n\n  const pageDisplayNames = useSelector(getCurrentPageSortedKeys)\n\n  const dispatch = useDispatch()\n\n  const shortcut = useContext(ShortCutContext)\n\n  useEffect(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n      element: \"manage_page\",\n    })\n  }, [])\n\n  const handleClickSetHomePage = useCallback(() => {\n    if (!pageDisplayName) return\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"set_home_page\",\n    })\n    if (isParentPage) {\n      dispatch(\n        componentsActions.updateRootNodePropsReducer({\n          homepageDisplayName: pageDisplayName,\n        }),\n      )\n    }\n    if (!isParentPage && parentPageName) {\n      dispatch(\n        componentsActions.updateDefaultSubPagePathReducer({\n          pageName: parentPageName,\n          subPagePath: pageDisplayName,\n        }),\n      )\n    }\n  }, [dispatch, isParentPage, pageDisplayName, parentPageName])\n\n  const handleDeletePage = useCallback(() => {\n    if (isParentPage && pageDisplayNames.length > 1) {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"delete_page\",\n      })\n      shortcut.showDeleteDialog([pageDisplayName], \"page\", {\n        originPageSortedKey: pageDisplayNames,\n      })\n    }\n    if (!isParentPage && parentPageName) {\n      shortcut.showDeleteDialog([pageDisplayName], \"subpage\", {\n        parentPageName: parentPageName,\n      })\n    }\n  }, [\n    isParentPage,\n    pageDisplayName,\n    pageDisplayNames,\n    parentPageName,\n    shortcut,\n  ])\n\n  const handleClickRename = useCallback(() => {\n    openRenameModal()\n  }, [openRenameModal])\n\n  return (\n    <DropList minW=\"184px\">\n      <DropListItem\n        value=\"setHomePage\"\n        title={\n          isParentPage\n            ? t(\"editor.page.label_name.set_as_homepage\")\n            : t(\"editor.page.label_name.set_as_default_subpage\")\n        }\n        onClick={handleClickSetHomePage}\n      />\n      <DropListItem\n        value=\"RenameURL\"\n        title={\n          isParentPage\n            ? t(\"widget.page.label.rename_page_url\")\n            : t(\"widget.page.label.rename_url\")\n        }\n        onClick={handleClickRename}\n      />\n      <DropListItem\n        value=\"delete\"\n        title={t(\"editor.inspect.header.action_menu.delete\")}\n        deleted\n        onClick={handleDeletePage}\n      />\n    </DropList>\n  )\n}\n\nActionMenu.displayName = \"ActionMenu\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/PageSpaceTree/components/ActionMenu/interface.ts",
    "content": "export interface ActionMenuProps {\n  pageDisplayName: string\n  isParentPage: boolean\n  parentPageName?: string\n  openRenameModal: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/PageSpaceTree/components/ChangePathModal/interface.ts",
    "content": "export interface ModalProps {\n  onCloseModal: () => void\n  path: string\n  handleUpdateItem: (value: string) => void\n  isParentPage: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/PageSpaceTree/components/ChangePathModal/modal.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CloseIcon, Input } from \"@illa-design/react\"\nimport { PageLabel } from \"@/page/App/components/PagePanel/Components/Label\"\nimport { LeftAndRightLayout } from \"@/page/App/components/PagePanel/Layout/leftAndRight\"\nimport { SetterPadding } from \"@/page/App/components/PagePanel/Layout/setterPadding\"\nimport { ModalProps } from \"./interface\"\nimport {\n  modalHeaderCloseIconHotSpot,\n  modalHeaderWrapper,\n  modalWrapperStyle,\n  titleStyle,\n} from \"./style\"\n\nexport const Modal: FC<ModalProps> = (props) => {\n  const { onCloseModal, path, handleUpdateItem, isParentPage } = props\n  const { t } = useTranslation()\n\n  return (\n    <div css={modalWrapperStyle}>\n      <div css={modalHeaderWrapper}>\n        <span css={titleStyle}>\n          {isParentPage\n            ? t(\"widget.page.label.rename_page_url\")\n            : t(\"editor.page.label_name.edit_view\")}\n        </span>\n        <div css={modalHeaderCloseIconHotSpot} onClick={onCloseModal}>\n          <CloseIcon />\n        </div>\n      </div>\n      <LeftAndRightLayout>\n        <PageLabel\n          labelName={t(\"editor.page.label_name.view_path\")}\n          size=\"big\"\n          tooltip={t(\"editor.page.tooltips.view_path\")}\n        />\n        <SetterPadding>\n          <Input\n            w=\"160px\"\n            value={path}\n            colorScheme=\"techPurple\"\n            onChange={handleUpdateItem}\n          />\n        </SetterPadding>\n      </LeftAndRightLayout>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/PageSpaceTree/components/ChangePathModal/style.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const modalWrapperStyle = css`\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  background-color: ${globalColor(`--${illaPrefix}-white-01`)};\n  box-shadow: 0px 2px 16px rgba(0, 0, 0, 0.16);\n  border-radius: 8px;\n  overflow: hidden;\n  position: relative;\n  padding-bottom: 8px;\n`\n\nexport const modalHeaderWrapper = css`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 12px 16px;\n  width: 240px;\n`\n\nexport const modalHeaderCloseIconHotSpot = css`\n  width: 24px;\n  height: 24px;\n  font-size: 14px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  cursor: pointer;\n`\n\nexport const titleStyle = css`\n  font-weight: 500;\n  font-size: 16px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  max-width: 200px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/PageSpaceTree/components/PageItem/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, memo, useCallback, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch } from \"react-redux\"\nimport {\n  Dropdown,\n  PlusIcon,\n  SettingIcon,\n  Trigger,\n  useMessage,\n} from \"@illa-design/react\"\nimport HomepageIcon from \"@/assets/dataWorkspace/homepage.svg?react\"\nimport WebsiteIcon from \"@/assets/dataWorkspace/website.svg?react\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { isValidDisplayName } from \"@/utils/typeHelper\"\nimport { ActionMenu } from \"../ActionMenu\"\nimport { Modal } from \"../ChangePathModal/modal\"\nimport { PageItemProps } from \"./interface\"\nimport {\n  actionAreaContainerStyle,\n  baseIconStyle,\n  iconHotSpotContainerStyle,\n  pageItemContainerStyle,\n  pageItemInnerContainerStyle,\n  pageNameContainerStyle,\n  pageNameStyle,\n  parentPageNameStyle,\n  plusIconStyle,\n} from \"./style\"\n\nconst PageItem: FC<PageItemProps> = (props) => {\n  const {\n    isHomePage,\n    pageName,\n    level = 1,\n    parentPageName,\n    subPagePaths,\n    currentPagePath,\n    currentSubPagePath,\n  } = props\n\n  const isSelected = !currentSubPagePath && currentPagePath === pageName\n  const subPageIsSelected =\n    currentPagePath === parentPageName && pageName === currentSubPagePath\n\n  const dispatch = useDispatch()\n  const [modalVisible, setModalVisible] = useState(false)\n  const [actionMenuVisible, setActionMenuVisible] = useState(false)\n  const [currentPageName, setCurrentPageName] = useState(pageName)\n  const message = useMessage()\n  const { t } = useTranslation()\n\n  const handleClickChangePage = useCallback(() => {\n    if (!parentPageName) {\n      dispatch(\n        executionActions.updateCurrentPagePathReducer({\n          pageDisplayName: pageName,\n        }),\n      )\n    } else {\n      dispatch(\n        executionActions.updateCurrentPagePathReducer({\n          pageDisplayName: parentPageName,\n          subPagePath: pageName,\n        }),\n      )\n    }\n  }, [dispatch, pageName, parentPageName])\n\n  const handlerAfterClose = useCallback(() => {\n    if (!parentPageName) {\n      if (!isValidDisplayName(currentPageName)) {\n        message.error({\n          content: t(\"editor.display_name.validate_error\", {\n            displayName: currentPageName,\n          }),\n        })\n        setCurrentPageName(pageName)\n        return\n      }\n      dispatch(\n        componentsActions.updateComponentDisplayNameReducer({\n          displayName: pageName,\n          newDisplayName: currentPageName,\n        }),\n      )\n    } else {\n      dispatch(\n        componentsActions.updateSubPagePathReducer({\n          pageName: parentPageName,\n          subPagePath: currentPageName,\n          oldSubPagePath: pageName,\n        }),\n      )\n    }\n  }, [currentPageName, dispatch, message, pageName, parentPageName, t])\n  const handleOpenModal = useCallback(() => {\n    setModalVisible(true)\n  }, [])\n\n  const addSubPage = useCallback(() => {\n    if (!parentPageName) {\n      dispatch(\n        componentsActions.addSubPageReducer({\n          pageName: pageName,\n        }),\n      )\n    }\n  }, [dispatch, pageName, parentPageName])\n\n  return (\n    <>\n      <Trigger\n        withoutPadding\n        colorScheme=\"white\"\n        popupVisible={modalVisible}\n        content={\n          <Modal\n            path={currentPageName}\n            onCloseModal={() => {\n              setModalVisible(false)\n            }}\n            handleUpdateItem={setCurrentPageName}\n            isParentPage={level === 1}\n          />\n        }\n        trigger=\"focus\"\n        showArrow={false}\n        position=\"right\"\n        clickOutsideToClose\n        onVisibleChange={(visible) => {\n          if (visible) {\n            trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n              element: \"edit_view_show\",\n            })\n          }\n          if (!visible) {\n            setModalVisible(false)\n            handlerAfterClose()\n          }\n        }}\n      >\n        <span>\n          <Dropdown\n            position=\"bottom-end\"\n            trigger=\"contextmenu\"\n            popupVisible={actionMenuVisible}\n            dropList={\n              <ActionMenu\n                pageDisplayName={pageName}\n                isParentPage={level === 1}\n                parentPageName={parentPageName}\n                openRenameModal={handleOpenModal}\n              />\n            }\n            onVisibleChange={setActionMenuVisible}\n          >\n            <div\n              css={pageItemContainerStyle(\n                isSelected || subPageIsSelected,\n                level,\n              )}\n              onClick={handleClickChangePage}\n            >\n              <div css={pageItemInnerContainerStyle}>\n                <div css={pageNameContainerStyle}>\n                  {!parentPageName && <WebsiteIcon />}\n                  {parentPageName && (\n                    <span css={parentPageNameStyle}>/{parentPageName}</span>\n                  )}\n                  <span css={pageNameStyle}>/{pageName}</span>\n                </div>\n                <div css={actionAreaContainerStyle} className=\"icon-area\">\n                  {isHomePage && (\n                    <div css={iconHotSpotContainerStyle}>\n                      <HomepageIcon css={baseIconStyle} />\n                    </div>\n                  )}\n                  <div\n                    css={iconHotSpotContainerStyle}\n                    onClick={() => {\n                      setActionMenuVisible(true)\n                    }}\n                  >\n                    <SettingIcon css={plusIconStyle} />\n                  </div>\n                  {level === 1 && (\n                    <div css={iconHotSpotContainerStyle} onClick={addSubPage}>\n                      <PlusIcon css={plusIconStyle} />\n                    </div>\n                  )}\n                </div>\n              </div>\n            </div>\n          </Dropdown>\n        </span>\n      </Trigger>\n      {subPagePaths &&\n        Array.from(subPagePaths).map((subPagePath) => {\n          return (\n            <PageItem\n              key={subPagePath}\n              level={level + 1}\n              parentPageName={pageName}\n              isHomePage={false}\n              pageName={subPagePath}\n              currentPagePath={currentPagePath}\n              currentSubPagePath={currentSubPagePath}\n            />\n          )\n        })}\n    </>\n  )\n}\n\nPageItem.displayName = \"DataWorkspace-PageItem\"\nexport default memo(PageItem)\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/PageSpaceTree/components/PageItem/interface.ts",
    "content": "export interface PageItemProps {\n  isHomePage: boolean\n  pageName: string\n  level: number\n  parentPageName?: string\n  subPagePaths?: Set<string>\n  currentSubPagePath?: string\n  currentPagePath: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/PageSpaceTree/components/PageItem/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const pageItemContainerStyle = (\n  isSelected: boolean,\n  level: number,\n) => css`\n  padding-left: ${level > 1 ? level * 16 + 8 : 16}px;\n  padding-right: 16px;\n  background-color: ${isSelected\n    ? getColor(\"techPurple\", \"08\")\n    : \"transparent\"};\n  cursor: pointer;\n  :hover {\n    .icon-area {\n      transform: translateX(0);\n    }\n  }\n`\n\nexport const pageNameStyle = css`\n  font-size: 12px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-weight: 500;\n`\n\nexport const parentPageNameStyle = css`\n  font-size: 12px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-weight: 500;\n`\n\nexport const pageNameContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  flex: none;\n`\n\nexport const baseIconStyle = css`\n  font-size: 12px;\n  width: 12px;\n  height: 12px;\n  flex: none;\n`\n\nexport const actionAreaContainerStyle = css`\n  flex: none;\n  display: flex;\n  align-items: center;\n  transition: all 0.2s ease-in-out;\n  transform: translateX(48px);\n`\n\nexport const iconHotSpotContainerStyle = css`\n  flex: none;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 6px;\n`\n\nexport const plusIconStyle = css`\n  ${baseIconStyle};\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n\nexport const pageItemInnerContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  height: 24px;\n  overflow: hidden;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/PageSpaceTree/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, MouseEvent, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { PlusIcon } from \"@illa-design/react\"\nimport { PanelBar } from \"@/components/PanelBar\"\nimport { getPageDisplayNameMapViewDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { RootComponentNodeProps } from \"@/redux/currentApp/components/componentsState\"\nimport { getRootNodeExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { generatePageConfig } from \"@/utils/generators/generatePageOrSectionConfig\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport PageItem from \"./components/PageItem\"\nimport { pageSpaceTreeStyle } from \"./style\"\n\nexport const PageSpaceTree: FC = () => {\n  const { t } = useTranslation()\n  const rootNodeProps = useSelector(\n    getRootNodeExecutionResult,\n  ) as RootComponentNodeProps\n  const {\n    currentPageIndex,\n    homepageDisplayName,\n    pageSortedKey = [],\n    currentSubPagePath,\n  } = rootNodeProps\n\n  const currentPageDisplayName = pageSortedKey[currentPageIndex]\n  const dispatch = useDispatch()\n\n  const handleClickAddButton = useCallback(\n    (e: MouseEvent<HTMLButtonElement>) => {\n      e.stopPropagation()\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"add_page\",\n      })\n      const newPageConfig = generatePageConfig()\n      dispatch(componentsActions.addPageNodeWithSortOrderReducer(newPageConfig))\n    },\n    [dispatch],\n  )\n\n  const pageDisplayNameMapSubPageDisplayName = useSelector(\n    getPageDisplayNameMapViewDisplayName,\n  )\n\n  return (\n    <PanelBar\n      title={t(\"editor.data_work_space.pages_title\")}\n      destroyChildrenWhenClose\n      customIcon={\n        <IconHotSpot onClick={handleClickAddButton}>\n          <PlusIcon />\n        </IconHotSpot>\n      }\n      onIllaFocus={() => {\n        FocusManager.switchFocus(\"data_page\")\n      }}\n    >\n      <div css={pageSpaceTreeStyle}>\n        {Object.keys(pageDisplayNameMapSubPageDisplayName).map((key, index) => {\n          const isHomePage = homepageDisplayName\n            ? homepageDisplayName === key\n            : index === 0\n          return (\n            <PageItem\n              isHomePage={isHomePage}\n              pageName={key}\n              key={key}\n              level={1}\n              subPagePaths={pageDisplayNameMapSubPageDisplayName[key]}\n              currentPagePath={currentPageDisplayName}\n              currentSubPagePath={currentSubPagePath}\n            />\n          )\n        })}\n      </div>\n    </PanelBar>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/PageSpaceTree/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const pageSpaceTreeStyle = css`\n  padding-bottom: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/WorkSpaceTreeGroup/index.tsx",
    "content": "import { FC } from \"react\"\nimport { PanelBar } from \"@/components/PanelBar\"\nimport { WorkSpaceTreeGroupProps } from \"./interface\"\nimport { treeContainerStyle } from \"./style\"\n\nexport const WorkSpaceTreeGroup: FC<WorkSpaceTreeGroupProps> = (props) => {\n  const { title, children } = props\n  return (\n    <PanelBar title={title} size=\"small\" destroyChildrenWhenClose>\n      <div css={treeContainerStyle}>{children}</div>\n    </PanelBar>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/WorkSpaceTreeGroup/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface WorkSpaceTreeGroupProps {\n  title: string\n  children?: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/WorkSpaceTreeGroup/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const treeContainerStyle = css`\n  font-family: \"Fira Code\", monospace;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/WorkSpaceTreeItem/WorkSpaceTreeNode.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { toPath } from \"lodash-es\"\nimport { FC, memo } from \"react\"\nimport { CopyIcon, isArray, isObject } from \"@illa-design/react\"\nimport { WorkSpaceTreeNodeProps } from \"@/page/App/Module/DataWorkspace/components/WorkSpaceTreeItem/interface\"\nimport {\n  applyJsonValueColorStyle,\n  applySimpleItemContainerStyle,\n  jsonNameStyle,\n  labelNameAndValueContainerStyle,\n} from \"@/page/App/Module/DataWorkspace/components/WorkSpaceTreeItem/style\"\nimport { copyToClipboard } from \"@/utils/copyToClipboard\"\nimport { WorkSpaceTreeItem } from \".\"\nimport { renderJsonValue } from \"./utils\"\n\nexport const WorkSpaceTreeNode: FC<WorkSpaceTreeNodeProps> = memo(\n  (props: WorkSpaceTreeNodeProps) => {\n    const { name, value, level = 0, parentKey } = props\n\n    const handleClickCopy = () => {\n      copyToClipboard(\n        `{{${convertPathToString(toPath(`${parentKey}.${name}`))}}}`,\n      )\n    }\n\n    if (isObject(value) || isArray(value)) {\n      return (\n        <WorkSpaceTreeItem\n          title={name}\n          data={value}\n          level={level}\n          parentKey={parentKey}\n          isChild={level + 1 > 1}\n        />\n      )\n    } else {\n      return (\n        <div css={applySimpleItemContainerStyle(false, level + 1)}>\n          <div css={labelNameAndValueContainerStyle}>\n            <label css={jsonNameStyle}>\n              {level < 1 ? `{{${parentKey}.${name}}}` : name}&nbsp;\n            </label>\n            <label css={applyJsonValueColorStyle(typeof value)}>\n              {renderJsonValue(value)}\n            </label>\n          </div>\n          <IconHotSpot onClick={handleClickCopy} id=\"copy-icon-hot-spot\">\n            <CopyIcon />\n          </IconHotSpot>\n        </div>\n      )\n    }\n  },\n)\n\nWorkSpaceTreeNode.displayName = \"WorkSpaceTreeNode\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/WorkSpaceTreeItem/index.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport copyToClipboard from \"copy-to-clipboard\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { toPath } from \"lodash-es\"\nimport { FC, memo } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CaretRightIcon, CopyIcon } from \"@illa-design/react\"\nimport { panelBarItemContainerAnimationVariants } from \"@/components/PanelBar/style\"\nimport { getExpandedKeys } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { WorkSpaceTreeNode } from \"./WorkSpaceTreeNode\"\nimport { WorkSpaceTreeItemProps } from \"./interface\"\nimport {\n  applyExpandIconStyle,\n  applyObjectOrArrayContainerStyle,\n  applyTitleAndDescContainerStyle,\n  jsonContentStyle,\n  objectAndArrayDescStyle,\n  objectAndArrayTitleStyle,\n} from \"./style\"\n\nexport const WorkSpaceTreeItem: FC<WorkSpaceTreeItemProps> = memo(\n  (props: WorkSpaceTreeItemProps) => {\n    const { title, data, level, parentKey, isChild } = props\n    const expandedKeys = useSelector(getExpandedKeys)\n    const uniqueKey = parentKey === title ? parentKey : `${parentKey}/${title}`\n    const isExpanded = expandedKeys.includes(uniqueKey)\n    const dispatch = useDispatch()\n    const keyArr = Object.keys(data)\n    return (\n      <>\n        <div\n          css={applyObjectOrArrayContainerStyle(level)}\n          onClick={() => {\n            if (isExpanded) {\n              dispatch(configActions.removeExpandedKey(uniqueKey))\n            } else {\n              dispatch(\n                configActions.setExpandedKey(expandedKeys.concat(uniqueKey)),\n              )\n            }\n          }}\n        >\n          <div css={applyTitleAndDescContainerStyle}>\n            <span css={applyExpandIconStyle(isExpanded)}>\n              <CaretRightIcon />\n            </span>\n            <label css={objectAndArrayTitleStyle}>\n              {isChild\n                ? title\n                : `{{${convertPathToString(toPath(`${parentKey}.${title}`))}}}`}\n              &nbsp;\n            </label>\n            <label css={objectAndArrayDescStyle}>\n              {Array.isArray(data)\n                ? `[]${keyArr.length} items`\n                : `{}${keyArr.length} keys`}\n            </label>\n          </div>\n          <IconHotSpot\n            onClick={(e) => {\n              e.stopPropagation()\n              copyToClipboard(\n                `{{${convertPathToString(toPath(`${parentKey}.${title}`))}}}`,\n              )\n            }}\n            id=\"copy-icon-hot-spot\"\n          >\n            <CopyIcon />\n          </IconHotSpot>\n        </div>\n        <AnimatePresence>\n          {isExpanded && (\n            <motion.div\n              css={jsonContentStyle}\n              variants={panelBarItemContainerAnimationVariants}\n              animate={isExpanded ? \"enter\" : \"exit\"}\n              transition={{ duration: 0.2 }}\n              exit=\"exit\"\n            >\n              {keyArr.map((name) => (\n                <WorkSpaceTreeNode\n                  key={name}\n                  name={name}\n                  value={data[name]}\n                  itemKey={title + name}\n                  level={level + 1}\n                  parentKey={convertPathToString(\n                    toPath(`${parentKey}.${title}`),\n                  )}\n                />\n              ))}\n            </motion.div>\n          )}\n        </AnimatePresence>\n      </>\n    )\n  },\n)\n\nWorkSpaceTreeItem.displayName = \"WorkSpaceTreeItem\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/WorkSpaceTreeItem/interface.ts",
    "content": "export interface WorkSpaceTreeItemProps {\n  title: string\n  data: Record<string, any>\n  level: number\n  parentKey: string\n  isChild?: boolean\n}\n\nexport interface WorkSpaceTreeNodeProps {\n  name: string\n  value: unknown\n  itemKey: string\n  parentKey: string\n  level?: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/WorkSpaceTreeItem/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const itemNameStyle: SerializedStyles = css`\n  font-weight: 600;\n  cursor: pointer;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  overflow: hidden;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  max-width: 160px;\n  vertical-align: bottom;\n  display: inline-block;\n`\n\nexport const itemNameDescStyle: SerializedStyles = css`\n  display: inline-block;\n  vertical-align: bottom;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const jsonContentStyle = css`\n  font-family: \"Fira Code\", monospace;\n  height: 0;\n`\n\nexport const jsonNameStyle: SerializedStyles = css`\n  display: inline-block;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport function applyJsonValueColorStyle(type: string) {\n  let colorStyle = css``\n  switch (type) {\n    case \"number\": {\n      colorStyle = css`\n        color: #164;\n      `\n      break\n    }\n    case \"boolean\": {\n      colorStyle = css`\n        color: #219;\n      `\n      break\n    }\n    case \"string\": {\n      colorStyle = css`\n        color: #219;\n      `\n      break\n    }\n    case \"undefined\": {\n      colorStyle = css`\n        color: #708;\n      `\n      break\n    }\n    case \"symbol\": {\n      colorStyle = css`\n        color: #00c;\n      `\n      break\n    }\n    case \"bigint\": {\n      colorStyle = css`\n        color: #170;\n      `\n      break\n    }\n  }\n\n  return css`\n    ${colorStyle};\n    word-break: break-all;\n  `\n}\n\nexport const editIconHotSpotStyle = css`\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  cursor: pointer;\n  width: 16px;\n  height: 16px;\n  font-size: 12px;\n  margin-left: 4px;\n  position: relative;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n\nexport const globalStateItemContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  width: calc(100% - 16px);\n`\n\nexport const objectAndArrayTitleStyle = css`\n  font-size: 12px;\n  font-weight: 500;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  cursor: pointer;\n  overflow: hidden;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n`\n\nexport const objectAndArrayDescStyle = css`\n  font-size: 12px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n\nexport const applyObjectOrArrayContainerStyle = (level: number) => css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding-left: ${level * 16}px;\n  font-family: \"Fira Code\", monospace;\n  :hover {\n    .global-state-edit-icon-hot-spot {\n      visibility: visible;\n    }\n    #copy-icon-hot-spot {\n      visibility: visible;\n    }\n  }\n  #copy-icon-hot-spot {\n    visibility: hidden;\n  }\n`\n\nexport const applySimpleItemContainerStyle = (\n  isSelected: boolean,\n  level: number,\n) => css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding-left: ${level * 16}px;\n  background-color: ${isSelected ? getColor(\"techPurple\", \"08\") : \"\"};\n  font-size: 12px;\n  font-family: \"Fira Code\", monospace;\n  :hover {\n    .global-state-edit-icon-hot-spot {\n      visibility: visible;\n    }\n    #copy-icon-hot-spot {\n      visibility: visible;\n    }\n  }\n  :last-child {\n    padding-bottom: 4px;\n  }\n  #copy-icon-hot-spot {\n    visibility: hidden;\n  }\n`\n\nexport const labelNameAndValueContainerStyle = css`\n  display: flex;\n  align-items: center;\n  flex-wrap: wrap;\n`\n\nexport const applyExpandIconStyle = (isExpanded: boolean) => css`\n  font-size: 8px;\n  line-height: 0;\n  cursor: pointer;\n  transform-origin: center;\n  transform: rotate(${isExpanded ? 90 : 0}deg);\n  transition: transform 200ms;\n  width: 16px;\n  height: 16px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  flex: none;\n`\n\nexport const applyTitleAndDescContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/components/WorkSpaceTreeItem/utils.tsx",
    "content": "import { MAX_LEN_WITH_SNIPPETS } from \"@/components/CodeEditor\"\n\nexport const renderJsonValue = (value: unknown) => {\n  const type = typeof value\n  switch (type) {\n    case \"string\":\n      return `\"${\n        (value as string).length > 1024\n          ? (value as string).slice(0, MAX_LEN_WITH_SNIPPETS) + \"...\"\n          : value\n      }\"`\n    default:\n      return `${value}`\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/constant.ts",
    "content": "export const hiddenFields = [\"displayName\", \"userID\"]\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/index.tsx",
    "content": "import { FC } from \"react\"\nimport { leftPanelStyle } from \"../../style\"\nimport { ActionSpaceTree } from \"./components/ActionSpaceTree\"\nimport { ComponentSpaceTree } from \"./components/ComponentSpaceTree\"\nimport { GlobalsSpaceTree } from \"./components/GlobalsSpaceTree\"\nimport { LibrarySpaceTree } from \"./components/LibrariesTree\"\nimport { PageSpaceTree } from \"./components/PageSpaceTree\"\nimport { innerContainerStyle } from \"./style\"\n\nexport const DataWorkspace: FC = () => {\n  return (\n    <div css={leftPanelStyle}>\n      <div css={innerContainerStyle}>\n        <PageSpaceTree />\n        <ComponentSpaceTree />\n        <ActionSpaceTree />\n        <GlobalsSpaceTree />\n        <LibrarySpaceTree />\n      </div>\n    </div>\n  )\n}\n\nDataWorkspace.displayName = \"DataWorkspace\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/DataWorkspace/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\n\nexport function applyJsonValueColorStyle(\n  type: unknown,\n  canEdit?: boolean,\n): SerializedStyles {\n  let color = \"#999\"\n  switch (type) {\n    case \"number\":\n      color = \"#164\"\n      break\n    case \"boolean\":\n      color = \"#219\"\n      break\n    case \"string\":\n      color = \"#219\"\n      break\n    case \"undefined\":\n      color = \"#708\"\n      break\n    case \"function\":\n      color = \"#05a\"\n      break\n    case \"symbol\":\n      color = \"#00c\"\n      break\n    case \"bigint\":\n      color = \"#170\"\n      break\n    case \"object\":\n      color = \"#a50\"\n      break\n    default:\n      color = \"#999\"\n      break\n  }\n  return css`\n    color: ${color};\n    padding-right: ${canEdit ? \"4px\" : \"0\"};\n  `\n}\n\nexport const innerContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  overflow: auto;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/LeftPanel/Components/DebugButton/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { t } from \"i18next\"\nimport { FC, memo, useMemo } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Badge, BugIcon, Trigger, getColor } from \"@illa-design/react\"\nimport { isOpenDebugger } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getExecutionError } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\n\nconst DebugButton: FC = () => {\n  const debuggerData = useSelector(getExecutionError)\n  const debuggerVisible = useSelector(isOpenDebugger)\n\n  const debugMessageNumber = useMemo(() => {\n    if (debuggerData) {\n      let count = 0\n      Object.keys(debuggerData).forEach((errors) => {\n        if (Array.isArray(debuggerData[errors])) {\n          count += debuggerData[errors].length\n        }\n      })\n      return count\n    }\n    return undefined\n  }, [debuggerData])\n  const dispatch = useDispatch()\n\n  const handleClickDebuggerIcon = () => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"debug\",\n      parameter2: debugMessageNumber ?? 0,\n    })\n    dispatch(configActions.updateDebuggerVisible(!debuggerVisible))\n  }\n\n  return (\n    <Trigger position=\"right\" content={t(\"flow.editor.app.tooltips.debug\")}>\n      <IconHotSpot onClick={handleClickDebuggerIcon}>\n        <Badge count={debugMessageNumber}>\n          <BugIcon color={getColor(\"grayBlue\", \"02\")} />\n        </Badge>\n      </IconHotSpot>\n    </Trigger>\n  )\n}\n\nexport default memo(DebugButton)\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/LeftPanel/Components/HistoryButton/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { getCurrentTeamInfo, getPlanUtils } from \"@illa-public/user-data\"\nimport { canUseUpgradeFeature } from \"@illa-public/user-role-utils\"\nimport { t } from \"i18next\"\nimport { FC, memo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { useNavigate, useParams } from \"react-router-dom\"\nimport { HistoryIcon, Trigger, getColor } from \"@illa-design/react\"\n\nconst HistoryButton: FC = () => {\n  const { teamIdentifier, appId } = useParams()\n\n  const teamInfo = useSelector(getCurrentTeamInfo)\n\n  const navigate = useNavigate()\n  const upgradeModal = useUpgradeModal()\n\n  const canUseBillingFeature = canUseUpgradeFeature(\n    teamInfo?.myRole,\n    getPlanUtils(teamInfo),\n    teamInfo?.totalTeamLicense?.teamLicensePurchased,\n    teamInfo?.totalTeamLicense?.teamLicenseAllPaid,\n  )\n\n  const handleOpenHistory = () => {\n    if (!canUseBillingFeature) {\n      upgradeModal({\n        modalType: \"upgrade\",\n        from: \"app_edit_more_history\",\n      })\n    } else {\n      navigate(`/${teamIdentifier}/appHistory/${appId}`)\n    }\n  }\n\n  return (\n    <Trigger\n      position=\"right\"\n      content={t(\"flow.editor.app.tooltips.edit_history\")}\n    >\n      <IconHotSpot onClick={handleOpenHistory}>\n        <HistoryIcon color={getColor(\"grayBlue\", \"02\")} />\n      </IconHotSpot>\n    </Trigger>\n  )\n}\n\nexport default memo(HistoryButton)\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/LeftPanel/Components/MissingResourceButton/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { t } from \"i18next\"\nimport { FC, memo, useEffect, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { QuestionCircleIcon, Trigger, getColor } from \"@illa-design/react\"\nimport MissingResourceModal from \"@/page/App/components/MissingRosourceModal\"\nimport { getHasMissingResourceAction } from \"@/redux/currentApp/action/actionSelector\"\n\nconst MissingResourceButton: FC = () => {\n  const hasMissingResources = useSelector(getHasMissingResourceAction)\n\n  const [shownMissingResource, setShownMissingResource] =\n    useState(hasMissingResources)\n  const [shownTooltip, setShownTooltip] = useState(false)\n\n  useEffect(() => {\n    setShownMissingResource(hasMissingResources)\n  }, [hasMissingResources])\n\n  const handleClickMissingResourceIcon = () => {\n    setShownMissingResource(true)\n  }\n\n  const handleCloseModal = (shown: boolean) => {\n    if (shown) {\n      setShownMissingResource(true)\n    } else {\n      setShownMissingResource(false)\n      setShownTooltip(true)\n      setTimeout(() => {\n        setShownTooltip(false)\n      }, 1500)\n    }\n  }\n\n  return (\n    hasMissingResources && (\n      <>\n        <Trigger\n          content={t(\"flow.editor.flow.tooltips.missing_resources\")}\n          position=\"right\"\n          popupVisible={shownTooltip}\n          onVisibleChange={setShownTooltip}\n        >\n          <IconHotSpot onClick={handleClickMissingResourceIcon}>\n            <QuestionCircleIcon color={getColor(\"orange\", \"03\")} />\n          </IconHotSpot>\n        </Trigger>\n        <MissingResourceModal\n          shown={shownMissingResource}\n          changeShown={handleCloseModal}\n        />\n      </>\n    )\n  )\n}\n\nexport default memo(MissingResourceButton)\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/LeftPanel/Components/MoreActionButton/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { isILLAAPiError } from \"@illa-public/illa-net\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { getCurrentTeamInfo, getPlanUtils } from \"@illa-public/user-data\"\nimport { canUseUpgradeFeature } from \"@illa-public/user-role-utils\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { FC, MouseEvent, memo, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useNavigate, useParams } from \"react-router-dom\"\nimport {\n  DropList,\n  DropListItem,\n  Dropdown,\n  MoreIcon,\n  Switch,\n  getColor,\n  useMessage,\n} from \"@illa-design/react\"\nimport { UpgradeTag } from \"@/components/UpgradeTag\"\nimport {\n  getAppInfo,\n  getCurrentAppWaterMarkConfig,\n} from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { appInfoActions } from \"@/redux/currentApp/appInfo/appInfoSlice\"\nimport { updateWaterMarkConfig } from \"@/services/apps\"\nimport { takeSnapShot } from \"@/services/history\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { isMAC } from \"@/utils/userAgent\"\nimport { keyTextStyle, spaceBetweenStyle, upgradeStyle } from \"./style\"\nimport { duplicateApp } from \"./utils\"\n\nconst MoreActionButton: FC = () => {\n  const { teamIdentifier, appId } = useParams()\n  const [duplicateLoading, setDuplicateLoading] = useState(false)\n\n  const { t } = useTranslation()\n  const navigate = useNavigate()\n  const dispatch = useDispatch()\n  const upgradeModal = useUpgradeModal()\n\n  const appInfo = useSelector(getAppInfo)\n  const teamInfo = useSelector(getCurrentTeamInfo)\n  const waterMark = useSelector(getCurrentAppWaterMarkConfig)\n\n  const message = useMessage()\n\n  const canUseBillingFeature = canUseUpgradeFeature(\n    teamInfo?.myRole,\n    getPlanUtils(teamInfo),\n    teamInfo?.totalTeamLicense?.teamLicensePurchased,\n    teamInfo?.totalTeamLicense?.teamLicenseAllPaid,\n  )\n\n  const handleDropdownVisibleChange = (visible: boolean) => {\n    if (visible) {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n        element: \"app_duplicate\",\n        parameter5: appId,\n      })\n    }\n  }\n\n  const handleDuplicateApp = async () => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"app_duplicate\",\n      parameter5: appId,\n    })\n    if (duplicateLoading) return\n    setDuplicateLoading(true)\n    try {\n      const response = await duplicateApp(appInfo.appId, appInfo.appName)\n      navigate(`/${teamIdentifier}/app/${response.data.appId}`)\n    } catch (error) {\n      if (isILLAAPiError(error)) {\n        message.error({ content: t(\"dashboard.app.duplicate_fail\") })\n      } else {\n        message.error({ content: t(\"network_error\") })\n      }\n    } finally {\n      setDuplicateLoading(false)\n    }\n  }\n\n  const handleSaveToHistory = async () => {\n    if (appId) {\n      try {\n        await takeSnapShot(appId)\n        message.success({ content: t(\"editor.history.message.suc.save\") })\n      } catch (error) {\n        if (isILLAAPiError(error)) {\n          message.error({ content: t(\"editor.history.message.fail.save\") })\n        } else {\n          message.error({ content: t(\"network_error\") })\n        }\n      }\n    }\n  }\n\n  const handleWaterMarkChange = async (value: boolean, event: MouseEvent) => {\n    if (appId) {\n      event.stopPropagation()\n      const res = await updateWaterMarkConfig(!value, appId)\n      dispatch(appInfoActions.updateAppInfoReducer(res.data))\n    }\n  }\n\n  const checkUpgrade = () => {\n    if (!canUseBillingFeature) {\n      upgradeModal({\n        modalType: \"upgrade\",\n        from: \"app_edit_more_watermark\",\n      })\n    }\n  }\n\n  return (\n    <Dropdown\n      position=\"bottom-end\"\n      trigger=\"click\"\n      triggerProps={{ closeDelay: 0, openDelay: 0 }}\n      onVisibleChange={handleDropdownVisibleChange}\n      dropList={\n        <DropList>\n          <DropListItem\n            key=\"duplicate\"\n            value=\"duplicate\"\n            title={t(\"duplicate\")}\n            onClick={handleDuplicateApp}\n          />\n          {isCloudVersion && (\n            <>\n              {canUseBillingFeature && (\n                <DropListItem\n                  key=\"saveHistory\"\n                  value=\"saveHistory\"\n                  title={\n                    <div css={spaceBetweenStyle}>\n                      <span>{t(\"editor.history.save\")}</span>\n                      <span css={keyTextStyle}>\n                        {isMAC()\n                          ? t(\"editor.history.save_keyboard.cmds\")\n                          : t(\"editor.history.save_keyboard.ctrls\")}\n                      </span>\n                    </div>\n                  }\n                  onClick={handleSaveToHistory}\n                />\n              )}\n              <DropListItem\n                key=\"configWaterMark\"\n                value=\"configWaterMark\"\n                title={\n                  <span css={upgradeStyle}>\n                    {t(\"billing.advanced.feature\")}\n                    {canUseBillingFeature ? (\n                      <Switch\n                        checked={!waterMark}\n                        onChange={handleWaterMarkChange}\n                      />\n                    ) : (\n                      <UpgradeTag />\n                    )}\n                  </span>\n                }\n                onClick={checkUpgrade}\n              />\n            </>\n          )}\n        </DropList>\n      }\n    >\n      <IconHotSpot>\n        <MoreIcon color={getColor(\"grayBlue\", \"02\")} />\n      </IconHotSpot>\n    </Dropdown>\n  )\n}\n\nexport default memo(MoreActionButton)\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/LeftPanel/Components/MoreActionButton/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const rowCenter = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const spaceBetweenStyle = css`\n  ${rowCenter};\n  justify-content: space-between;\n  gap: 8px;\n`\n\nexport const keyTextStyle = css`\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 14px;\n  font-weight: 400;\n  line-height: 22px;\n  text-transform: capitalize;\n`\n\nexport const upgradeStyle = css`\n  ${rowCenter};\n  gap: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/LeftPanel/Components/MoreActionButton/utils.ts",
    "content": "import { fetchCopyApp } from \"@/services/apps\"\n\nconst APP_NAME_MAX_LENGTH = 128\nconst COPY_SUFFIX = \" Copy\"\nconst trimmedLength = APP_NAME_MAX_LENGTH - COPY_SUFFIX.length\nexport const duplicateApp = (appId: string, appName?: string) => {\n  const newAppName = `${(appName || \"\").slice(0, trimmedLength)}${COPY_SUFFIX}`\n  return fetchCopyApp(appId, newAppName)\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/LeftPanel/Components/ToolBar/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getIsILLAGuideMode } from \"@/redux/config/configSelector\"\nimport DebugButton from \"../DebugButton\"\nimport HistoryButton from \"../HistoryButton\"\nimport MissingResourceButton from \"../MissingResourceButton\"\nimport MoreActionButton from \"../MoreActionButton\"\nimport { ToolBarContainerStyle } from \"./style\"\n\nconst ToolBar: FC = () => {\n  const isGuideMode = useSelector(getIsILLAGuideMode)\n\n  return (\n    <div css={ToolBarContainerStyle}>\n      <MissingResourceButton />\n      <DebugButton />\n      {!isGuideMode && <HistoryButton />}\n      {!isGuideMode && <MoreActionButton />}\n    </div>\n  )\n}\n\nexport default memo(ToolBar)\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/LeftPanel/Components/ToolBar/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const ToolBarContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  height: 100%;\n  border-right: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  background-color: white;\n  padding: 12px;\n  gap: 24px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/LeftPanel/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { isOpenLeftPanel } from \"@/redux/config/configSelector\"\nimport { DataWorkspace } from \"../DataWorkspace\"\nimport ToolBar from \"./Components/ToolBar\"\nimport { leftPanelContainerStyle } from \"./style\"\n\nconst LeftPanel: FC = () => {\n  const showLeftPanel = useSelector(isOpenLeftPanel)\n\n  return (\n    <div css={leftPanelContainerStyle}>\n      <ToolBar />\n      {showLeftPanel && <DataWorkspace />}\n    </div>\n  )\n}\n\nexport default memo(LeftPanel)\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/LeftPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const leftPanelContainerStyle = css`\n  display: flex;\n  height: 100%;\n  flex: none;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/AppName/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, useState } from \"react\"\nimport { PenIcon } from \"@illa-design/react\"\nimport { AppSettingModal } from \"@/page/App/Module/PageNavBar/AppSettingModal\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { AppNameProps } from \"./interface\"\nimport { nameContainerStyle, nameStyle } from \"./style\"\n\nexport const AppName: FC<AppNameProps> = (props) => {\n  const { appInfo } = props\n\n  const [appSettingVisible, setAppSettingVisible] = useState(false)\n\n  const trackHoverOnAppName = () => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.HOVER, {\n      element: \"app_rename\",\n    })\n  }\n\n  const handleOpenAppSettingModal = () => {\n    setAppSettingVisible(true)\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n      element: \"app_setting_modal\",\n      parameter5: appInfo.appId,\n    })\n  }\n\n  return (\n    <>\n      <div\n        css={nameContainerStyle}\n        onMouseEnter={trackHoverOnAppName}\n        onClick={handleOpenAppSettingModal}\n      >\n        <span css={nameStyle}>{appInfo.appName}</span>\n        <PenIcon size=\"16px\" />\n      </div>\n      <AppSettingModal\n        appInfo={appInfo}\n        visible={appSettingVisible}\n        onVisibleChange={(visible) => {\n          setAppSettingVisible(visible)\n        }}\n        onSaveEvent={() => {\n          trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n            element: \"app_setting_modal_save\",\n            parameter5: appInfo.appId,\n          })\n        }}\n        onCloseEvent={() => {\n          trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n            element: \"app_setting_modal_close\",\n            parameter5: appInfo.appId,\n          })\n        }}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/AppName/interface.ts",
    "content": "import { AppInfoShape } from \"@illa-public/public-types\"\n\nexport interface AppNameProps {\n  appInfo: AppInfoShape\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/AppName/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const triggerStyle = css`\n  margin-top: 20px;\n`\n\nexport const nameStyle = css`\n  font-weight: 500;\n  line-height: 18px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const nameContainerStyle = css`\n  display: inline-flex;\n  gap: 8px;\n  cursor: pointer;\n  height: 18px;\n  align-items: center;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  & > svg {\n    display: none;\n  }\n  &:hover > svg {\n    display: block;\n    align-self: flex-start;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/AppSettingModal/index.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { Controller, useForm, useFormState } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport {\n  Button,\n  CloseIcon,\n  Input,\n  Modal,\n  TextArea,\n  getColor,\n  useMessage,\n} from \"@illa-design/react\"\nimport { AppSettingModalProps } from \"@/page/App/Module/PageNavBar/AppSettingModal/interface\"\nimport { applyConfigItemLabelText } from \"@/page/App/components/Actions/ControlledElement/style\"\nimport { appInfoActions } from \"@/redux/currentApp/appInfo/appInfoSlice\"\nimport { updateAppConfig } from \"@/services/apps\"\nimport {\n  closeIconHotSpotStyle,\n  formLabelStyle,\n  gridFormFieldStyle,\n  gridFormStyle,\n  gridItemStyle,\n  gridValidStyle,\n  modalHeaderWrapperStyle,\n  modalTitleStyle,\n  modalWrapperStyle,\n} from \"./style\"\n\nexport interface AppSettingFields {\n  appName: string\n  description?: string\n}\n\nexport const AppSettingModal: FC<AppSettingModalProps> = (props) => {\n  const { appInfo, visible, onVisibleChange, onSaveEvent, onCloseEvent } = props\n\n  const { control, formState, handleSubmit, reset } = useForm<AppSettingFields>(\n    {\n      mode: \"onSubmit\",\n      criteriaMode: \"firstError\",\n      defaultValues: {\n        appName: appInfo?.appName ?? \"\",\n        description: appInfo?.config?.description ?? \"\",\n      },\n    },\n  )\n\n  const { isSubmitting, isDirty } = useFormState({\n    control,\n  })\n\n  const { t } = useTranslation()\n  const { appId } = useParams()\n  const dispatch = useDispatch()\n\n  const message = useMessage()\n\n  const onSubmit = useCallback(\n    async (data: AppSettingFields) => {\n      try {\n        onSaveEvent()\n        const res = await updateAppConfig(appInfo.appId, {\n          description: data.description,\n          appName: data.appName,\n        })\n        if (res.data.appId === appId) {\n          dispatch(appInfoActions.updateAppInfoReducer(res.data))\n        }\n        reset({\n          appName: data.appName,\n          description: data.description,\n        })\n        message.success({\n          content: t(\"dashboard.app.rename_success\"),\n        })\n      } catch (error) {\n        message.error({\n          content: t(\"dashboard.app.rename_fail\"),\n        })\n      }\n      onVisibleChange(false)\n    },\n    [\n      onVisibleChange,\n      onSaveEvent,\n      appInfo.appId,\n      dispatch,\n      appId,\n      reset,\n      message,\n      t,\n    ],\n  )\n\n  return (\n    <Modal\n      maskClosable\n      withoutPadding\n      w=\"528px\"\n      visible={visible}\n      footer={false}\n      onCancel={() => {\n        onCloseEvent()\n        onVisibleChange(false)\n      }}\n    >\n      <div css={modalWrapperStyle}>\n        <header css={modalHeaderWrapperStyle}>\n          <h3 css={modalTitleStyle}>\n            {t(\"new_dashboard.app_setting.app_setting\")}\n          </h3>\n          <span\n            css={closeIconHotSpotStyle}\n            onClick={() => {\n              onCloseEvent()\n              onVisibleChange(false)\n            }}\n          >\n            <CloseIcon />\n          </span>\n        </header>\n        <form\n          css={gridFormStyle}\n          autoComplete=\"off\"\n          onSubmit={handleSubmit(onSubmit)}\n        >\n          <section css={gridFormFieldStyle}>\n            <section css={gridItemStyle}>\n              <label css={formLabelStyle}>\n                {t(\"new_dashboard.app_setting.app_name\")}\n                <span css={applyConfigItemLabelText(getColor(\"red\", \"03\"))}>\n                  *\n                </span>\n              </label>\n              <div css={gridValidStyle}>\n                <Controller\n                  name=\"appName\"\n                  control={control}\n                  render={({ field }) => (\n                    <Input\n                      {...field}\n                      colorScheme=\"techPurple\"\n                      error={!!formState?.errors.appName}\n                      placeholder={t(\n                        \"new_dashboard.app_setting.placeholder.app_name\",\n                      )}\n                    />\n                  )}\n                  rules={{\n                    required: t(\n                      \"page.user.sign_up.error_message.username.require\",\n                    ),\n                    maxLength: {\n                      value: 280,\n                      message: t(\n                        \"page.user.sign_up.error_message.username.length\",\n                      ),\n                    },\n                  }}\n                />\n              </div>\n            </section>\n            <section css={gridItemStyle}>\n              <label css={formLabelStyle}>\n                {t(\"new_dashboard.app_setting.description\")}\n              </label>\n              <div css={gridValidStyle}>\n                <Controller\n                  name=\"description\"\n                  control={control}\n                  render={({ field }) => (\n                    <TextArea\n                      {...field}\n                      showWordLimit\n                      maxLength={180}\n                      autoSize={{ minRows: 6 }}\n                      colorScheme=\"techPurple\"\n                      error={!!formState?.errors.description}\n                      placeholder={t(\n                        \"new_dashboard.app_setting.placeholder.description\",\n                      )}\n                    />\n                  )}\n                />\n              </div>\n            </section>\n          </section>\n          <Button\n            colorScheme=\"techPurple\"\n            loading={isSubmitting}\n            disabled={!isDirty}\n            fullWidth\n          >\n            {t(\"save\")}\n          </Button>\n        </form>\n      </div>\n    </Modal>\n  )\n}\n\nAppSettingModal.displayName = \"AppSettingModal\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/AppSettingModal/interface.ts",
    "content": "import { AppInfoShape } from \"@illa-public/public-types\"\n\nexport interface AppSettingModalProps {\n  appInfo: AppInfoShape\n  visible: boolean\n  onVisibleChange: (visible: boolean) => void\n  onSaveEvent: () => void\n  onCloseEvent: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/AppSettingModal/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix, zIndex } from \"@illa-design/react\"\n\nexport const modalWrapperStyle = css`\n  padding: 24px 24px 0;\n  width: 100%;\n`\n\nexport const modalWithMaskWrapperStyle = css`\n  width: 100vw;\n  height: 100vh;\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: ${zIndex.modal};\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n\nexport const maskStyle = css`\n  width: 100%;\n  height: 100%;\n  position: absolute;\n  top: 0;\n  left: 0;\n  background-color: ${getColor(\"white\", \"05\")};\n  backdrop-filter: blur(5px);\n  z-index: -1;\n`\n\nexport const modalHeaderWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 0 16px 16px;\n  width: 486px;\n  position: relative;\n`\n\nexport const modalTitleStyle = css`\n  font-weight: 600;\n  font-size: 16px;\n  line-height: 24px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  margin: 0;\n  text-align: center;\n`\n\nexport const closeIconHotSpotStyle = css`\n  position: absolute;\n  right: 0;\n  top: 0;\n  width: 24px;\n  height: 24px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  cursor: pointer;\n  font-size: 12px;\n`\n\nexport const gridFormStyle: SerializedStyles = css`\n  display: grid;\n  gap: 32px;\n  padding-bottom: 24px;\n`\n\nexport const gridFormFieldStyle: SerializedStyles = css`\n  display: grid;\n  gap: 24px;\n`\n\nexport const gridItemStyle: SerializedStyles = css`\n  display: grid;\n  gap: 8px;\n`\n\nexport const gridValidStyle: SerializedStyles = css``\n\nexport const inputDisabledStyle = css`\n  &:disabled {\n    -webkit-text-fill-color: ${getColor(\"grayBlue\", \"05\")};\n  }\n`\n\nexport const formLabelStyle: SerializedStyles = css`\n  font-size: 14px;\n  line-height: 22px;\n  font-weight: 500;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const descriptionStyle: SerializedStyles = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const errorMsgStyle: SerializedStyles = css`\n  position: relative;\n  font-size: 14px;\n  padding-left: 24px;\n  line-height: 22px;\n  color: ${globalColor(`--${illaPrefix}-orange-03`)};\n`\n\nexport const errorIconStyle: SerializedStyles = css`\n  position: absolute;\n  font-size: 16px;\n  line-height: 0;\n  top: 3px;\n  left: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/AppSizeButtonGroup/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { Variants, motion } from \"framer-motion\"\nimport { FC, MouseEvent, useCallback, useEffect } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport DesktopIcon from \"@/assets/appSize/desktop.svg?react\"\nimport CustomIcon from \"@/assets/appSize/filter.svg?react\"\nimport FluidIcon from \"@/assets/appSize/fluid.svg?react\"\nimport TabletIcon from \"@/assets/appSize/tablet.svg?react\"\nimport { PreviewPopContent } from \"@/page/App/Module/PageNavBar/PreviewPopContent\"\nimport { getViewportSizeSelector } from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { ViewportSizeType } from \"@/redux/currentApp/components/componentsState\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport {\n  appSizeContainerStyle,\n  appSizeIconContainerStyle,\n  appSizeIconStyle,\n  getAppSizeIconSelectedStyle,\n  previewButtonGroupWrapperStyle,\n} from \"./style\"\n\nconst AppSizeIcons = [\n  {\n    type: \"fluid\",\n    Icon: FluidIcon,\n  },\n  {\n    type: \"desktop\",\n    Icon: DesktopIcon,\n  },\n  {\n    type: \"tablet\",\n    Icon: TabletIcon,\n  },\n  {\n    type: \"custom\",\n    Icon: CustomIcon,\n  },\n]\n\nconst defaultAppSize = {\n  fluid: {\n    viewportWidth: undefined,\n    viewportHeight: undefined,\n  },\n  desktop: {\n    viewportWidth: 1280,\n    viewportHeight: undefined,\n  },\n  tablet: {\n    viewportWidth: 1080,\n    viewportHeight: undefined,\n  },\n}\n\nconst variants: Variants = {\n  hidden: {\n    height: 0,\n    opacity: 0,\n    visibility: \"hidden\",\n    transitionEnd: {\n      display: \"none\",\n    },\n  },\n  shown: {\n    height: \"unset\",\n    opacity: 1,\n    visibility: \"visible\",\n    display: \"inherit\",\n  },\n}\n\nexport const AppSizeButtonGroup: FC = () => {\n  const { viewportSizeType, viewportWidth, viewportHeight } = useSelector(\n    getViewportSizeSelector,\n  )\n  const dispatch = useDispatch()\n\n  const showCustomInputs = viewportSizeType === \"custom\"\n  const currentSizeType = viewportSizeType ?? \"fluid\"\n\n  useEffect(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SELECT, {\n      element: \"preview_size\",\n      parameter2: currentSizeType,\n    })\n  }, [currentSizeType])\n\n  const updateAppSize = useCallback(\n    ({\n      viewportWidth,\n      viewportHeight,\n      viewportSizeType,\n    }: {\n      viewportWidth?: number\n      viewportHeight?: number\n      viewportSizeType?: ViewportSizeType\n    }) => {\n      dispatch(\n        componentsActions.updateViewportSizeReducer({\n          viewportWidth,\n          viewportHeight,\n          viewportSizeType,\n        }),\n      )\n    },\n    [dispatch],\n  )\n\n  const handleAppSizeTypeChange = useCallback(\n    (e: MouseEvent<HTMLSpanElement>) => {\n      const newType = e.currentTarget.dataset.key as ViewportSizeType\n      const sizeObj =\n        newType !== \"custom\"\n          ? defaultAppSize[newType]\n          : {\n              viewportHeight,\n              viewportWidth,\n            }\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"preview_size\",\n        parameter2: newType,\n      })\n      updateAppSize({\n        ...sizeObj,\n        viewportSizeType: newType,\n      })\n    },\n    [updateAppSize, viewportHeight, viewportWidth],\n  )\n\n  return (\n    <div css={previewButtonGroupWrapperStyle}>\n      <div css={appSizeContainerStyle}>\n        {AppSizeIcons.map((info) => {\n          const { Icon, type } = info\n          return (\n            <span\n              key={type}\n              data-key={type}\n              css={appSizeIconContainerStyle}\n              onClick={handleAppSizeTypeChange}\n            >\n              <span\n                css={[\n                  appSizeIconStyle,\n                  getAppSizeIconSelectedStyle(currentSizeType === type),\n                ]}\n              >\n                <Icon />\n              </span>\n            </span>\n          )\n        })}\n      </div>\n      <motion.div\n        initial=\"hidden\"\n        animate={showCustomInputs ? \"shown\" : \"hidden\"}\n        variants={variants}\n        transition={{ duration: 0.5, ease: \"easeInOut\" }}\n      >\n        <PreviewPopContent />\n      </motion.div>\n    </div>\n  )\n}\n\nAppSizeButtonGroup.displayName = \"AppSizeButtonGroup\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/AppSizeButtonGroup/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const previewButtonGroupWrapperStyle = css`\n  display: flex;\n  pointer-events: auto;\n  position: relative;\n  align-items: center;\n  height: 32px;\n`\n\nexport const appSizeContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const appSizeIconContainerStyle = css`\n  width: 32px;\n  height: 32px;\n  display: flex;\n  cursor: pointer;\n`\n\nexport const appSizeIconStyle = css`\n  margin: auto;\n  height: 100%;\n  display: flex;\n  & > svg {\n    width: 16px;\n    height: 16px;\n    margin: auto;\n  }\n`\n\nexport const getAppSizeIconSelectedStyle = (\n  active: boolean,\n): SerializedStyles => {\n  if (active) {\n    return css`\n      box-shadow: inset 0px -2px 0px ${getColor(\"grayBlue\", \"02\")};\n    `\n  }\n  return css``\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/CollaboratorsList/ListItem/index.tsx",
    "content": "import { FC } from \"react\"\nimport {\n  getListItemContainerStyle,\n  nicknameStyle,\n} from \"@/page/App/Module/PageNavBar/CollaboratorsList/ListItem/style\"\nimport { Avatar } from \"@/page/App/components/Avatar\"\nimport { UserListItemProps } from \"./interface\"\n\nexport const UserListItem: FC<UserListItemProps> = (props) => {\n  const { id, avatar, nickname, type } = props\n\n  return (\n    <div css={getListItemContainerStyle(type)}>\n      <Avatar\n        userID={id}\n        nickname={nickname}\n        avatar={avatar}\n        showTooltips={true}\n      />\n      {type === \"list\" && <span css={nicknameStyle}>{nickname || \"\"}</span>}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/CollaboratorsList/ListItem/interface.ts",
    "content": "export interface UserListItemProps {\n  id?: string\n  type?: string\n  nickname: string\n  avatar?: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/CollaboratorsList/ListItem/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const avatarStyle = css`\n  width: 32px;\n  height: 32px;\n  line-height: 32px;\n  text-align: center;\n  border-radius: 50%;\n  display: inline-block;\n  flex-shrink: 0;\n`\n\nexport const getListItemContainerStyle = (type: string = \"\") => {\n  if (type === \"list\") {\n    return css`\n      display: flex;\n      gap: 8px;\n      font-weight: 500;\n      font-size: 14px;\n      height: 32px;\n      &:not(:last-child) {\n        margin-bottom: 12px;\n      }\n    `\n  }\n  return css`\n    display: inline-flex;\n  `\n}\n\nexport const nicknameStyle = css`\n  line-height: 22px;\n  height: 22px;\n  align-self: center;\n  font-family: \"Inter\";\n  font-size: 14px;\n  text-align: left;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/CollaboratorsList/index.tsx",
    "content": "import { FC, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Trigger } from \"@illa-design/react\"\nimport { UserListItem } from \"@/page/App/Module/PageNavBar/CollaboratorsList/ListItem\"\nimport {\n  avatarContainerStyle,\n  moreIconStyle,\n  userInfoListContainerStyle,\n} from \"@/page/App/Module/PageNavBar/CollaboratorsList/style\"\nimport { getCurrentAppAttachUsers } from \"@/redux/currentApp/collaborators/collaboratorsSelector\"\nimport { CollaboratorsInfo } from \"@/redux/currentApp/collaborators/collaboratorsState\"\n\nexport const CollaboratorsList: FC = () => {\n  const [mouseOver, setMouseOver] = useState(false)\n  const currentCollaborator = useSelector(getCurrentAppAttachUsers) || []\n  const usersLength = currentCollaborator.length\n\n  const getRenderDOM = (dataList: CollaboratorsInfo[], type?: string) => (\n    <>\n      {dataList.map((user: CollaboratorsInfo, index) => {\n        const { id, nickname, avatar } = user\n        return (\n          <UserListItem\n            id={`${id}`}\n            type={type}\n            nickname={nickname}\n            avatar={avatar}\n            key={index}\n          />\n        )\n      })}\n    </>\n  )\n  if (usersLength <= 4) {\n    return (\n      <div css={avatarContainerStyle}>{getRenderDOM(currentCollaborator)}</div>\n    )\n  }\n\n  return (\n    <div css={avatarContainerStyle}>\n      {getRenderDOM(currentCollaborator.slice(0, 3))}\n      <Trigger\n        trigger=\"hover\"\n        popupVisible={mouseOver}\n        onVisibleChange={setMouseOver}\n        content={\n          <div css={userInfoListContainerStyle}>\n            {getRenderDOM(currentCollaborator, \"list\")}\n          </div>\n        }\n        position=\"bottom-end\"\n        showArrow={false}\n        withoutPadding\n        colorScheme=\"white\"\n      >\n        <div css={moreIconStyle}>\n          <span>{usersLength - 3 <= 99 ? `+${usersLength - 3}` : \"99+\"}</span>\n        </div>\n      </Trigger>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/CollaboratorsList/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const avatarContainerStyle = css`\n  display: flex;\n  position: relative;\n  gap: 8px;\n`\n\nexport const moreIconStyle = css`\n  width: 32px;\n  height: 32px;\n  line-height: 32px;\n  text-align: center;\n  border-radius: 50%;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-05`)};\n  color: ${globalColor(`--${illaPrefix}-white-01`)};\n  border: 1px solid ${globalColor(`--${illaPrefix}-white-01`)};\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  cursor: pointer;\n  & span {\n    margin: 8px;\n    font-size: 12px;\n    line-height: 16px;\n    vertical-align: middle;\n  }\n`\n\nexport const userInfoListContainerStyle = css`\n  position: absolute;\n  top: 3px;\n  right: 0;\n  width: 172px;\n  max-height: 240px;\n  overflow: auto;\n  background-color: ${globalColor(`--${illaPrefix}-white-01`)};\n  border-radius: 8px;\n  border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.08);\n  padding: 16px;\n  z-index: 10;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/DeloyButtonGroup/index.tsx",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  Button,\n  DownIcon,\n  DropList,\n  DropListItem,\n  Dropdown,\n  PlayFillIcon,\n} from \"@illa-design/react\"\nimport { UpgradeTag } from \"@/components/UpgradeTag\"\nimport {\n  deployButtonStyle,\n  deployConfigButtonStyle,\n  deployConfigDescStyle,\n  deployLabelStyle,\n  deployMenuStyle,\n  deployMenuWithTagStyle,\n} from \"@/page/App/Module/PageNavBar/DeloyButtonGroup/style\"\n\nexport interface DeployButtonGroupProps {\n  onClickDeploy: () => void\n  onClickDeployMenu: (value: string | number) => void\n  loading: boolean\n  isGuideMode: boolean\n  canUseBillingFeature: boolean\n  disPrivate: boolean\n  isPublic?: boolean\n}\n\nexport const DeployButtonGroup: FC<DeployButtonGroupProps> = (props) => {\n  const { t } = useTranslation()\n  const {\n    loading,\n    isPublic,\n    isGuideMode,\n    canUseBillingFeature,\n    onClickDeploy,\n    disPrivate,\n    onClickDeployMenu,\n  } = props\n\n  if (!isCloudVersion || isGuideMode) {\n    return (\n      <Button\n        loading={loading}\n        colorScheme=\"techPurple\"\n        size=\"medium\"\n        leftIcon={<PlayFillIcon />}\n        onClick={onClickDeploy}\n      >\n        {isGuideMode\n          ? t(\"editor.tutorial.panel.tutorial.modal.fork\")\n          : t(\"deploy\")}\n      </Button>\n    )\n  }\n\n  return (\n    <div css={deployButtonStyle}>\n      <Button\n        loading={loading}\n        colorScheme=\"techPurple\"\n        size=\"medium\"\n        bdRadius=\"8px 0 0 8px\"\n        leftIcon={<PlayFillIcon />}\n        onClick={onClickDeploy}\n      >\n        {isPublic ? t(\"new_deploy.button.public\") : t(\"deploy\")}\n      </Button>\n      <Dropdown\n        position=\"bottom-end\"\n        trigger=\"click\"\n        triggerProps={{ closeDelay: 0, openDelay: 0 }}\n        dropList={\n          <DropList onClickItem={onClickDeployMenu}>\n            <DropListItem\n              key=\"private\"\n              value=\"private\"\n              disabled={disPrivate}\n              title={\n                <div css={deployMenuStyle}>\n                  <div css={deployLabelStyle}>\n                    {t(\"new_deploy.title.private_app\")}\n                  </div>\n                  <div css={deployConfigDescStyle}>\n                    {t(\"new_deploy.desc.private_app\")}\n                  </div>\n                </div>\n              }\n            />\n            <DropListItem\n              key=\"public\"\n              value=\"public\"\n              title={\n                <div css={deployMenuStyle}>\n                  {canUseBillingFeature ? (\n                    <div css={deployLabelStyle}>\n                      {t(\"new_deploy.title.public_app\")}\n                    </div>\n                  ) : (\n                    <div css={deployMenuWithTagStyle}>\n                      <span css={deployLabelStyle}>\n                        {t(\"new_deploy.title.public_app\")}\n                      </span>\n                      <UpgradeTag />\n                    </div>\n                  )}\n                  <div css={deployConfigDescStyle}>\n                    {t(\"new_deploy.desc.public_app\")}\n                  </div>\n                </div>\n              }\n            />\n          </DropList>\n        }\n      >\n        <Button\n          css={deployConfigButtonStyle}\n          colorScheme=\"techPurple\"\n          bdRadius=\"0 8px 8px 0\"\n          leftIcon={<DownIcon />}\n        />\n      </Dropdown>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/DeloyButtonGroup/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const deployConfigButtonStyle = css`\n  position: relative;\n\n  &:before {\n    border-radius: 1px;\n    background: ${getColor(\"white\", \"06\")};\n    width: 1px;\n    height: 12px;\n    content: \"\";\n    position: absolute;\n    left: 0;\n  }\n`\nexport const deployMenuStyle = css`\n  padding: 8px 0;\n  display: flex;\n  flex-direction: column;\n  gap: 2px;\n`\n\nexport const deployMenuWithTagStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const deployButtonStyle = css`\n  display: flex;\n`\n\nexport const deployLabelStyle = css`\n  font-weight: 500;\n  line-height: 22px;\n`\nexport const deployConfigDescStyle = css`\n  font-size: 12px;\n  font-weight: 400;\n  line-height: 20px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/PreviewPopContent/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { useCallback, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CloseIcon, InputNumber, useMessage } from \"@illa-design/react\"\nimport {\n  closeIconStyle,\n  inputAreaLabelWrapperStyle,\n  inputAreaWrapperStyle,\n} from \"@/page/App/Module/PageNavBar/style\"\nimport {\n  BODY_MIN_HEIGHT,\n  BODY_MIN_WIDTH,\n  FOOTER_MIN_HEIGHT,\n  HEADER_MIN_HEIGHT,\n  LEFT_MIN_WIDTH,\n  RIGHT_MIN_WIDTH,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getViewportSizeSelector } from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\n\nconst validateHeight = (currentHeight: number | undefined) => {\n  return !(\n    currentHeight != undefined &&\n    currentHeight < BODY_MIN_HEIGHT + HEADER_MIN_HEIGHT + FOOTER_MIN_HEIGHT\n  )\n}\n\nconst validateWidth = (currentWidth: number | undefined) => {\n  return !(\n    currentWidth != undefined &&\n    currentWidth < BODY_MIN_WIDTH + LEFT_MIN_WIDTH + RIGHT_MIN_WIDTH\n  )\n}\n\nexport const PreviewPopContent = () => {\n  const { viewportWidth, viewportHeight } = useSelector(getViewportSizeSelector)\n\n  const [inputWidth, setInputWidth] = useState(viewportWidth)\n  const [inputHeight, setInputHeight] = useState(viewportHeight)\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n  const message = useMessage()\n\n  const width = validateWidth(inputWidth) ? inputWidth : viewportWidth\n  const height = validateHeight(inputHeight) ? inputHeight : viewportHeight\n\n  const saveNewViewportSize = useCallback(() => {\n    dispatch(\n      componentsActions.updateViewportSizeReducer({\n        viewportWidth: width,\n        viewportHeight: height,\n        viewportSizeType: \"custom\",\n      }),\n    )\n  }, [dispatch, height, width])\n\n  const handleUpdateInputWidth = useCallback((value?: number) => {\n    setInputWidth(value)\n  }, [])\n\n  const handleUpdateInputHeight = useCallback((value?: number) => {\n    setInputHeight(value)\n  }, [])\n\n  const handleOnBlurInputHeight = useCallback(() => {\n    const isValidate = validateHeight(inputHeight)\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n      element: \"custom_size_input\",\n      parameter2: \"h\",\n      parameter3: inputHeight,\n    })\n    if (!isValidate) {\n      message.error({\n        content: t(\"frame_size.invalid_tips\", {\n          size: BODY_MIN_HEIGHT + HEADER_MIN_HEIGHT + FOOTER_MIN_HEIGHT,\n        }),\n      })\n      return\n    }\n    saveNewViewportSize()\n  }, [inputHeight, message, saveNewViewportSize, t])\n\n  const handleOnBlurInputWidth = useCallback(() => {\n    const isValidate = validateWidth(inputWidth)\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n      element: \"custom_size_input\",\n      parameter2: \"w\",\n      parameter3: inputWidth,\n    })\n    if (!isValidate) {\n      message.error({\n        content: t(\"frame_size.invalid_tips\", {\n          size: BODY_MIN_WIDTH + LEFT_MIN_WIDTH + RIGHT_MIN_WIDTH,\n        }),\n      })\n      return\n    }\n    saveNewViewportSize()\n  }, [inputWidth, message, saveNewViewportSize, t])\n\n  const handleOnFocusOnWidth = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.FOCUS, {\n      element: \"custom_size_input\",\n      parameter2: \"w\",\n    })\n  }, [])\n\n  const handleOnFocusOnHeight = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.FOCUS, {\n      element: \"custom_size_input\",\n      parameter2: \"h\",\n    })\n  }, [])\n\n  return (\n    <div css={inputAreaWrapperStyle}>\n      <div css={inputAreaLabelWrapperStyle}>\n        <span>W</span>\n        <CloseIcon css={closeIconStyle} />\n        <span>H:</span>\n      </div>\n      <div css={inputAreaLabelWrapperStyle}>\n        <InputNumber\n          w=\"100px\"\n          colorScheme=\"techPurple\"\n          value={inputWidth}\n          placeholder=\"--\"\n          onChange={handleUpdateInputWidth}\n          onBlur={handleOnBlurInputWidth}\n          onFocus={handleOnFocusOnWidth}\n          min={BODY_MIN_WIDTH + LEFT_MIN_WIDTH + RIGHT_MIN_WIDTH}\n          suffix=\"px\"\n          hideControl\n        />\n        <CloseIcon css={closeIconStyle} />\n        <InputNumber\n          w=\"100px\"\n          colorScheme=\"techPurple\"\n          value={inputHeight}\n          placeholder=\"--\"\n          suffix=\"px\"\n          hideControl\n          onChange={handleUpdateInputHeight}\n          onBlur={handleOnBlurInputHeight}\n          onFocus={handleOnFocusOnHeight}\n          min={BODY_MIN_HEIGHT + HEADER_MIN_HEIGHT + FOOTER_MIN_HEIGHT}\n        />\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/ShareAppButton/index.tsx",
    "content": "import { UpgradeIcon } from \"@illa-public/icon\"\nimport { ShareAppPC } from \"@illa-public/invite-modal\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport { MemberInfo, USER_STATUS } from \"@illa-public/public-types\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport {\n  getCurrentTeamInfo,\n  getCurrentUser,\n  getPlanUtils,\n  teamActions,\n} from \"@illa-public/user-data\"\nimport {\n  canManageInvite,\n  canUseUpgradeFeature,\n  openShareAppModal,\n} from \"@illa-public/user-role-utils\"\nimport {\n  getILLABuilderURL,\n  getMarketLinkTemplate,\n  isCloudVersion,\n} from \"@illa-public/utils\"\nimport { getAuthToken } from \"@illa-public/utils\"\nimport { FC, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Button, getColor } from \"@illa-design/react\"\nimport { ShareAppButtonProps } from \"@/page/App/Module/PageNavBar/ShareAppButton/interface\"\nimport { appInfoActions } from \"@/redux/currentApp/appInfo/appInfoSlice\"\nimport { copyToClipboard } from \"@/utils/copyToClipboard\"\nimport { track, trackInEditor } from \"@/utils/mixpanelHelper\"\n\nexport const ShareAppButton: FC<ShareAppButtonProps> = (props) => {\n  const { t } = useTranslation()\n  const { appInfo } = props\n\n  const currentUserInfo = useSelector(getCurrentUser)\n\n  const teamInfo = useSelector(getCurrentTeamInfo)!!\n\n  const canUseBillingFeature = canUseUpgradeFeature(\n    teamInfo?.myRole,\n    getPlanUtils(teamInfo),\n    teamInfo?.totalTeamLicense?.teamLicensePurchased,\n    teamInfo?.totalTeamLicense?.teamLicenseAllPaid,\n  )\n\n  const upgradeModal = useUpgradeModal()\n  const [shareModalVisible, setShareModalVisible] = useState(false)\n\n  const dispatch = useDispatch()\n\n  const showInvite = canManageInvite(\n    teamInfo.myRole,\n    teamInfo?.permission?.allowEditorManageTeamMember,\n    teamInfo?.permission?.allowViewerManageTeamMember,\n  )\n\n  const handleClick = () => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"invite_entry\",\n    })\n    if (\n      !openShareAppModal(\n        teamInfo,\n        teamInfo.myRole,\n        appInfo.config.public,\n        appInfo.config.publishedToMarketplace,\n      )\n    ) {\n      upgradeModal({ modalType: \"upgrade\", from: \"app_edit_share\" })\n      return\n    }\n    setShareModalVisible(true)\n  }\n\n  return (\n    <>\n      <Button\n        colorScheme=\"grayBlue\"\n        rightIcon={\n          isCloudVersion &&\n          !canUseBillingFeature && (\n            <UpgradeIcon color={getColor(\"techPurple\", \"03\")} />\n          )\n        }\n        onClick={handleClick}\n      >\n        {t(\"share\")}\n      </Button>\n      <MixpanelTrackProvider\n        basicTrack={track}\n        pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR}\n      >\n        {shareModalVisible && (\n          <ShareAppPC\n            itemID={appInfo.appId}\n            onInvitedChange={(userList) => {\n              const memberListInfo: MemberInfo[] = userList.map((user) => {\n                return {\n                  ...user,\n                  userID: \"\",\n                  nickname: \"\",\n                  avatar: \"\",\n                  userStatus: USER_STATUS.PENDING,\n                  permission: {},\n                  createdAt: \"\",\n                  updatedAt: \"\",\n                }\n              })\n              dispatch(teamActions.updateInvitedUserReducer(memberListInfo))\n            }}\n            appDesc={appInfo.config.description}\n            appName={appInfo.appName}\n            onAppInfoUpdate={(appConfig) => {\n              const { publishWithAIAgent } = appConfig\n              dispatch(\n                appInfoActions.updateAppInfoReducer({\n                  ...appInfo,\n                  appName: appConfig.appName,\n                  config: {\n                    ...appInfo.config,\n                    description: appConfig.appDesc,\n                    publishWithAIAgent,\n                  },\n                }),\n              )\n            }}\n            isDeployed={appInfo.deployed}\n            title={t(\"user_management.modal.social_media.default_text.app\", {\n              appName: appInfo.appName,\n            })}\n            editRedirectURL={`${getILLABuilderURL(window.customDomain)}/${\n              teamInfo.identifier\n            }/app/${appInfo.appId}`}\n            useRedirectURL={`${getILLABuilderURL(window.customDomain)}/${\n              teamInfo.identifier\n            }/deploy/app/${appInfo.appId}`}\n            defaultAllowInviteLink={teamInfo.permission.inviteLinkEnabled}\n            onInviteLinkStateChange={(enableInviteLink) => {\n              dispatch(\n                teamActions.updateTeamMemberPermissionReducer({\n                  teamID: teamInfo.id,\n                  newPermission: {\n                    ...teamInfo.permission,\n                    inviteLinkEnabled: enableInviteLink,\n                  },\n                }),\n              )\n            }}\n            onClose={() => {\n              setShareModalVisible(false)\n            }}\n            canInvite={showInvite}\n            defaultBalance={\n              isCloudVersion ? teamInfo.currentTeamLicense.balance : Infinity\n            }\n            teamID={teamInfo.id}\n            currentUserRole={teamInfo.myRole}\n            onBalanceChange={(balance) => {\n              dispatch(\n                teamActions.updateTeamMemberSubscribeReducer({\n                  teamID: teamInfo.id,\n                  subscribeInfo: {\n                    ...teamInfo.currentTeamLicense,\n                    balance: balance,\n                  },\n                }),\n              )\n            }}\n            defaultAppPublic={appInfo.config.public}\n            defaultAppContribute={appInfo.config.publishedToMarketplace}\n            defaultPublishWithAIAgent={appInfo.config.publishWithAIAgent}\n            appID={appInfo.appId}\n            userRoleForThisApp={teamInfo.myRole}\n            ownerTeamID={teamInfo.id}\n            ownerTeamIdentify={teamInfo.identifier}\n            onAppPublic={(isPublic) => {\n              dispatch(appInfoActions.updateAppPublicReducer(isPublic))\n            }}\n            onAppContribute={(isContributed) => {\n              dispatch(appInfoActions.updateAppContributeReducer(isContributed))\n              if (isContributed) {\n                dispatch(appInfoActions.updateAppDeployedReducer(true))\n                const newUrl = new URL(getMarketLinkTemplate(appInfo.appId))\n                newUrl.searchParams.set(\"token\", getAuthToken())\n                window.open(newUrl, \"_blank\")\n              }\n            }}\n            onCopyPublicLink={(link) => {\n              copyToClipboard(\n                t(\"user_management.modal.custom_copy_text_app_invite\", {\n                  userName: currentUserInfo.nickname,\n                  teamName: teamInfo.name,\n                  inviteLink: link,\n                }),\n              )\n            }}\n            onCopyContributeLink={(link) => {\n              track(\n                ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR,\n                {\n                  element: \"invite_modal_public_copy\",\n                  parameter5: appInfo.appId,\n                },\n              )\n              copyToClipboard(\n                t(\"user_management.modal.contribute.default_text.app\", {\n                  appName: appInfo.appName,\n                  appLink: link,\n                }),\n              )\n            }}\n            onCopyEditInviteLink={(link) => {\n              copyToClipboard(\n                t(\"user_management.modal.custom_copy_text_app_invite\", {\n                  userName: currentUserInfo.nickname,\n                  teamName: teamInfo.name,\n                  inviteLink: link,\n                }),\n              )\n            }}\n            onCopyUseInviteLink={(link) => {\n              copyToClipboard(\n                t(\"user_management.modal.custom_copy_text_app_invite\", {\n                  userName: currentUserInfo.nickname,\n                  teamName: teamInfo.name,\n                  inviteLink: link,\n                }),\n              )\n            }}\n            canUseBillingFeature={canUseBillingFeature}\n            onShare={(name) => {\n              const { publishedToMarketplace } = appInfo.config\n              track(\n                ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n                ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR,\n                {\n                  element: \"share_modal_social_media\",\n                  parameter1: publishedToMarketplace,\n                  parameter4: name,\n                  parameter5: appInfo.appId,\n                },\n              )\n            }}\n          />\n        )}\n      </MixpanelTrackProvider>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/ShareAppButton/interface.ts",
    "content": "import { AppInfoShape } from \"@illa-public/public-types\"\n\nexport interface ShareAppButtonProps {\n  appInfo: AppInfoShape\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/WindowIcons/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { useCallback } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  WindowBottomIcon,\n  WindowLeftIcon,\n  WindowRightIcon,\n} from \"@illa-design/react\"\nimport {\n  isOpenBottomPanel,\n  isOpenLeftPanel,\n  isOpenRightPanel,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { windowIconBodyStyle, windowIconStyle } from \"./style\"\n\nexport const WindowIcons = () => {\n  const dispatch = useDispatch()\n\n  const leftPanelVisible = useSelector(isOpenLeftPanel)\n  const rightPanelVisible = useSelector(isOpenRightPanel)\n  const bottomPanelVisible = useSelector(isOpenBottomPanel)\n\n  const handleClickLeftWindowIcon = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"panel_show\",\n      parameter2: \"left\",\n      parameter3: !leftPanelVisible ? \"show\" : \"hidden\",\n    })\n    dispatch(configActions.updateLeftPanel(!leftPanelVisible))\n  }, [dispatch, leftPanelVisible])\n  const handleClickRightWindowIcon = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"panel_show\",\n      parameter2: \"right\",\n      parameter3: !rightPanelVisible ? \"show\" : \"hidden\",\n    })\n    dispatch(configActions.updateRightPanel(!rightPanelVisible))\n  }, [dispatch, rightPanelVisible])\n  const handleClickBottomWindowIcon = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"panel_show\",\n      parameter2: \"bottom\",\n      parameter3: !bottomPanelVisible ? \"show\" : \"hidden\",\n    })\n    dispatch(configActions.updateBottomPanel(!bottomPanelVisible))\n  }, [bottomPanelVisible, dispatch])\n\n  return (\n    <div\n      style={{\n        pointerEvents: \"auto\",\n      }}\n    >\n      <span css={windowIconBodyStyle} onClick={handleClickLeftWindowIcon}>\n        <WindowLeftIcon _css={windowIconStyle(leftPanelVisible)} />\n      </span>\n      <span css={windowIconBodyStyle} onClick={handleClickBottomWindowIcon}>\n        <WindowBottomIcon _css={windowIconStyle(bottomPanelVisible)} />\n      </span>\n      <span css={windowIconBodyStyle} onClick={handleClickRightWindowIcon}>\n        <WindowRightIcon _css={windowIconStyle(rightPanelVisible)} />\n      </span>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/WindowIcons/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const lineStyle = css`\n  display: inline-block;\n  width: 1px;\n  height: 16px;\n  margin: 0 16px;\n  background-color: ${getColor(\"grayBlue\", \"08\")};\n`\n\nexport const windowIconBodyStyle = css`\n  width: 24px;\n  height: 24px;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  margin-right: 2px;\n  border-radius: 4px;\n  cursor: pointer;\n\n  &:hover {\n    background: ${getColor(\"grayBlue\", \"09\")};\n  }\n`\n\nexport function windowIconStyle(selected: boolean): SerializedStyles {\n  return css`\n    flex: none;\n    width: 16px;\n    height: 16px;\n    font-size: 16px;\n    color: ${selected\n      ? getColor(\"grayBlue\", \"03\")\n      : getColor(\"grayBlue\", \"05\")};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/index.tsx",
    "content": "import { isILLAAPiError } from \"@illa-public/illa-net\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { getCurrentTeamInfo, getPlanUtils } from \"@illa-public/user-data\"\nimport {\n  canUseUpgradeFeature,\n  showShareAppModal,\n} from \"@illa-public/user-role-utils\"\nimport {\n  fromNow,\n  getILLABuilderURL,\n  getILLACloudURL,\n  isCloudVersion,\n} from \"@illa-public/utils\"\nimport { FC, useCallback, useEffect, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Link, useParams } from \"react-router-dom\"\nimport {\n  Button,\n  ExitIcon,\n  FullScreenIcon,\n  QuestionCircleIcon,\n  getColor,\n  useMessage,\n  useModal,\n} from \"@illa-design/react\"\nimport Logo from \"@/assets/illa-logo.svg?react\"\nimport SnowIcon from \"@/assets/snow-icon.svg?react\"\nimport { AppName } from \"@/page/App/Module/PageNavBar/AppName\"\nimport { AppSizeButtonGroup } from \"@/page/App/Module/PageNavBar/AppSizeButtonGroup\"\nimport { CollaboratorsList } from \"@/page/App/Module/PageNavBar/CollaboratorsList\"\nimport { DeployButtonGroup } from \"@/page/App/Module/PageNavBar/DeloyButtonGroup\"\nimport { ShareAppButton } from \"@/page/App/Module/PageNavBar/ShareAppButton\"\nimport { WindowIcons } from \"@/page/App/Module/PageNavBar/WindowIcons\"\nimport { PageNavBarProps } from \"@/page/App/Module/PageNavBar/interface\"\nimport {\n  getIsILLAEditMode,\n  getIsILLAGuideMode,\n  getIsILLAPreviewMode,\n  getIsOnline,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getHasMissingResourceAction } from \"@/redux/currentApp/action/actionSelector\"\nimport { getAppInfo } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { appInfoActions } from \"@/redux/currentApp/appInfo/appInfoSlice\"\nimport { fetchDeployApp, forkCurrentApp } from \"@/services/apps\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport MissingResourceModal from \"../../components/MissingRosourceModal\"\nimport {\n  buttonGroupStyle,\n  descriptionStyle,\n  informationStyle,\n  logoCursorStyle,\n  missingContentStyle,\n  missingHeaderContainerStyle,\n  missingResourceHeaderStyle,\n  missingResourceModalContainerStyle,\n  navBarStyle,\n  rightContentStyle,\n  rowCenter,\n  saveFailedTipStyle,\n  viewControlStyle,\n} from \"./style\"\n\nexport const PageNavBar: FC<PageNavBarProps> = (props) => {\n  const { className } = props\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const message = useMessage()\n\n  const { teamIdentifier } = useParams()\n\n  const appInfo = useSelector(getAppInfo)\n  const isOnline = useSelector(getIsOnline)\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const isPreviewMode = useSelector(getIsILLAPreviewMode)\n  const isGuideMode = useSelector(getIsILLAGuideMode)\n  const teamInfo = useSelector(getCurrentTeamInfo)!!\n  const hasMissingResources = useSelector(getHasMissingResourceAction)\n  const modal = useModal()\n\n  const upgradeModal = useUpgradeModal()\n\n  const [deployLoading, setDeployLoading] = useState<boolean>(false)\n  const [shownMissingResource, setShownMissingResource] = useState(false)\n\n  const canUseBillingFeature = canUseUpgradeFeature(\n    teamInfo.myRole,\n    getPlanUtils(teamInfo),\n    teamInfo?.totalTeamLicense?.teamLicensePurchased,\n    teamInfo?.totalTeamLicense?.teamLicenseAllPaid,\n  )\n\n  const deployApp = useCallback(\n    async (\n      appId: string,\n      isPublic: boolean,\n      onSuccess?: () => void,\n      onFailed?: (error: unknown) => void,\n    ) => {\n      setDeployLoading(true)\n      try {\n        await fetchDeployApp(appId, isPublic)\n        dispatch(appInfoActions.updateAppDeployedReducer(true))\n        dispatch(appInfoActions.updateAppPublicReducer(isPublic))\n        window.open(\n          `${getILLABuilderURL(\n            window.customDomain,\n          )}/${teamIdentifier}/deploy/app/${appId}`,\n          \"_blank\",\n        )\n        onSuccess?.()\n      } catch (error) {\n        message.error({\n          content: t(\"editor.deploy.fail\"),\n        })\n        onFailed?.(error)\n      } finally {\n        setDeployLoading(false)\n      }\n    },\n    [dispatch, teamIdentifier, message, t],\n  )\n\n  const forkGuideAppAndDeploy = useCallback(\n    async (appName: string) => {\n      setDeployLoading(true)\n      const appId = await forkCurrentApp(appName)\n      await deployApp(appId, false)\n      setDeployLoading(false)\n    },\n    [deployApp],\n  )\n\n  const handleClickDeploy = async () => {\n    if (isGuideMode) {\n      await forkGuideAppAndDeploy(appInfo.appName)\n    } else {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"deploy\",\n      })\n      if (hasMissingResources) {\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n          element: \"missing_resource_confirm_modal\",\n        })\n        modal.show({\n          children: (\n            <div css={missingResourceModalContainerStyle}>\n              <div css={missingHeaderContainerStyle}>\n                <QuestionCircleIcon color={getColor(\"orange\", \"03\")} />\n                <h6 css={missingResourceHeaderStyle}>\n                  {t(\n                    \"editor.action.panel.title.missing_resource.missing_resources\",\n                  )}\n                </h6>\n              </div>\n              <p css={missingContentStyle}>\n                {t(\n                  \"editor.action.panel.desc.missing_resource.some_resources_of_th\",\n                )}\n              </p>\n            </div>\n          ),\n          okText: t(\"editor.action.panel.button.missing_resource.deploy\"),\n          cancelText: t(\n            \"editor.action.panel.button.missing_resource.configure\",\n          ),\n          maskClosable: false,\n          okButtonProps: {\n            colorScheme: \"black\",\n          },\n          w: \"320px\",\n          minW: \"320px\",\n          onOk: async () => {\n            trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n              element: \"missing_resource_confirm_modal_deploy\",\n            })\n            await deployApp(appInfo.appId, appInfo.config.public)\n          },\n          onCancel() {\n            trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n              element: \"missing_resource_confirm_modal_configure\",\n            })\n            setShownMissingResource(true)\n          },\n        })\n        return\n      }\n      await deployApp(appInfo.appId, appInfo.config.public)\n    }\n  }\n\n  const handleClickDeployMenu = useCallback(\n    async (key: string | number) => {\n      if (key === \"public\" && !canUseBillingFeature) {\n        upgradeModal({\n          modalType: \"upgrade\",\n          from: \"app_edit_deploy_public\",\n        })\n      } else {\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.REQUEST, {\n          element: \"invite_modal_public_switch\",\n          parameter1: \"deploy\",\n          parameter2: \"trigger\",\n          parameter4: appInfo.config.public ? \"on\" : \"off\",\n          parameter5: appInfo.appId,\n        })\n        await deployApp(\n          appInfo.appId,\n          key === \"public\",\n          () => {\n            trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.REQUEST, {\n              element: \"invite_modal_public_switch\",\n              parameter1: \"deploy\",\n              parameter2: \"suc\",\n              parameter4: appInfo.config.public ? \"on\" : \"off\",\n              parameter5: appInfo.appId,\n            })\n          },\n          (error) => {\n            trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.REQUEST, {\n              element: \"invite_modal_public_switch\",\n              parameter1: \"deploy\",\n              parameter2: \"failed\",\n              parameter3: isILLAAPiError(error)\n                ? error?.data?.errorFlag\n                : \"unknown\",\n              parameter4: appInfo.config.public ? \"on\" : \"off\",\n              parameter5: appInfo.appId,\n            })\n          },\n        )\n      }\n    },\n    [\n      appInfo.appId,\n      appInfo.config.public,\n      canUseBillingFeature,\n      deployApp,\n      upgradeModal,\n    ],\n  )\n\n  const handlePreviewButtonClick = useCallback(() => {\n    if (isEditMode) {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"preview\",\n      })\n      dispatch(configActions.updateIllaMode(\"preview\"))\n    } else {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"exit_preview\",\n      })\n      dispatch(configActions.updateIllaMode(\"edit\"))\n    }\n  }, [dispatch, isEditMode])\n\n  const PreviewButton = (\n    <Button\n      colorScheme=\"grayBlue\"\n      leftIcon={isEditMode ? <FullScreenIcon /> : <ExitIcon />}\n      variant=\"fill\"\n      bdRadius=\"8px\"\n      onClick={handlePreviewButtonClick}\n    >\n      {isEditMode ? t(\"preview.button_text\") : t(\"exit_preview\")}\n    </Button>\n  )\n\n  const canShowShareAppModal = showShareAppModal(\n    teamInfo,\n    teamInfo.myRole,\n    appInfo.config.public,\n    appInfo.config.publishedToMarketplace,\n    appInfo.deployed,\n  )\n\n  useEffect(() => {\n    !isGuideMode &&\n      canShowShareAppModal &&\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, { element: \"invite_entry\" })\n  }, [canShowShareAppModal, isGuideMode])\n\n  return (\n    <div className={className} css={navBarStyle}>\n      <div css={rowCenter}>\n        <Link to={getILLACloudURL(window.customDomain)}>\n          <Logo width=\"34px\" css={logoCursorStyle} />\n        </Link>\n\n        <div css={informationStyle}>\n          <AppName appInfo={appInfo} />\n          {isOnline ? (\n            <div css={descriptionStyle}>\n              {t(\"edit_at\") + \" \" + fromNow(appInfo?.updatedAt)}\n            </div>\n          ) : (\n            <div css={saveFailedTipStyle}>\n              <SnowIcon />\n              <span> {t(\"edit_failed\")}</span>\n            </div>\n          )}\n        </div>\n      </div>\n      <div css={viewControlStyle()}>\n        {isEditMode && <WindowIcons />}\n        {isPreviewMode && <AppSizeButtonGroup />}\n      </div>\n      <div css={rightContentStyle}>\n        {isEditMode ? (\n          <div css={buttonGroupStyle}>\n            {isCloudVersion && (\n              <>\n                <CollaboratorsList />\n                {canShowShareAppModal && <ShareAppButton appInfo={appInfo} />}\n              </>\n            )}\n            {PreviewButton}\n            {/* {hasMissingResources && (\n              <ResourceMissingTipButton ref={missingResourceButtonRef} />\n            )} */}\n            <DeployButtonGroup\n              disPrivate={appInfo.config.publishedToMarketplace}\n              loading={deployLoading}\n              isPublic={appInfo.config.public}\n              isGuideMode={isGuideMode}\n              canUseBillingFeature={canUseBillingFeature}\n              onClickDeploy={handleClickDeploy}\n              onClickDeployMenu={handleClickDeployMenu}\n            />\n          </div>\n        ) : (\n          PreviewButton\n        )}\n      </div>\n      <MissingResourceModal\n        shown={shownMissingResource}\n        changeShown={setShownMissingResource}\n      />\n    </div>\n  )\n}\n\nPageNavBar.displayName = \"PageNavBar\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/interface.ts",
    "content": "import { HTMLAttributes } from \"react\"\n\nexport interface PageNavBarProps extends HTMLAttributes<HTMLDivElement> {}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/resp.ts",
    "content": "export interface DeployResp {\n  version: number\n  releaseVersion: number\n  mainlineVersion: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/PageNavBar/style.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const navBarStyle = css`\n  display: flex;\n  box-sizing: border-box;\n  flex-direction: row;\n  align-items: center;\n  justify-content: space-between;\n  border-bottom: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  padding: 6px 16px;\n  overflow-x: auto;\n  overflow-y: hidden;\n  gap: 16px;\n`\n\nexport const rowCenter = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n`\n\nexport const viewControlStyle = () => css`\n  pointer-events: none;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  position: absolute;\n  left: 0;\n  right: 0;\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  justify-content: center;\n  ${rowCenter};\n\n  & > svg {\n    &:hover {\n      color: ${getColor(\"grayBlue\", \"02\")};\n      cursor: pointer;\n    }\n  }\n`\n\nexport const rightContentStyle = css`\n  display: flex;\n  align-self: flex-end;\n  justify-content: space-between;\n  align-items: center;\n  gap: 29px;\n`\n\nexport const buttonGroupStyle = css`\n  display: inline-flex;\n  gap: 8px;\n`\n\nexport const badgeStyle = css`\n  z-index: 3;\n`\n\nexport const informationStyle = css`\n  margin-left: 24px;\n  display: flex;\n  flex-direction: column;\n  font-size: 12px;\n  flex-shrink: 1;\n`\n\nexport const descriptionStyle = css`\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  overflow: hidden;\n  height: 18px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n\nexport const saveFailedTipStyle = css`\n  display: flex;\n  align-items: center;\n  width: 100%;\n  height: 18px;\n  color: ${getColor(\"grayBlue\", \"03\")};\n  gap: 4px;\n`\n\nexport const logoCursorStyle = css`\n  cursor: pointer;\n`\n\nexport const closeIconStyle = css`\n  width: 8px;\n  height: 8px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n\nexport const inputAreaWrapperStyle = css`\n  width: 100%;\n  gap: 8px;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  position: absolute;\n  left: calc(100% + 16px);\n  top: 0;\n`\n\nexport const inputAreaLabelWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  font-size: 12px;\n  gap: 8px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const nameStyle = css`\n  font-weight: 500;\n  cursor: pointer;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const missingResourceModalContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n  justify-content: center;\n  align-items: center;\n`\n\nexport const missingHeaderContainerStyle = css`\n  display: flex;\n  gap: 8px;\n`\n\nexport const missingResourceHeaderStyle = css`\n  margin: 0;\n  padding: 0;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 16px;\n  font-weight: 500;\n  line-height: 24px;\n`\n\nexport const missingContentStyle = css`\n  font-size: 14px;\n  font-weight: 400;\n  line-height: 18px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  margin: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/components/DetailList/constants.ts",
    "content": "export const PROCESS_DETAIL_LIST_HEIGHT = 400\nexport const PROCESS_DETAIL_ITEM_HEIGHT = 52\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/components/DetailList/index.tsx",
    "content": "import VirtualList from \"rc-virtual-list\"\nimport { FC, useSyncExternalStore } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { updateFileDetailStore } from \"@/page/App/Module/UploadDetail/store\"\nimport {\n  PROCESS_DETAIL_ITEM_HEIGHT,\n  PROCESS_DETAIL_LIST_HEIGHT,\n} from \"./constants\"\nimport { FileItemDetail } from \"./item\"\nimport { emptyStateStyle, fileListContainerStyle } from \"./style\"\n\nexport const UploadFileList: FC = () => {\n  const { t } = useTranslation()\n\n  const uploadFiles = useSyncExternalStore(\n    updateFileDetailStore.subscribe,\n    updateFileDetailStore.getSnapshot,\n  )\n\n  return (\n    <div css={fileListContainerStyle}>\n      {uploadFiles.length > 0 ? (\n        <VirtualList\n          height={PROCESS_DETAIL_LIST_HEIGHT}\n          itemHeight={PROCESS_DETAIL_ITEM_HEIGHT}\n          itemKey=\"queryID\"\n          data={uploadFiles}\n        >\n          {(item) => {\n            return (\n              <FileItemDetail\n                {...item}\n                onDelete={updateFileDetailStore.deleteFileDetailInfo}\n                onRetry={updateFileDetailStore.retryUpload}\n              />\n            )\n          }}\n        </VirtualList>\n      ) : (\n        <div css={emptyStateStyle}>\n          {t(\"drive.upload_modal.nothing_upload\")}\n        </div>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/components/DetailList/interface.ts",
    "content": "export enum FILE_ITEM_DETAIL_STATUS_IN_UI {\n  PROCESSING = \"processing\",\n  SUCCESS = \"success\",\n  ERROR = \"error\",\n  WAITING = \"waiting\",\n}\n\nexport interface FileItemDetailProps {\n  loaded: number\n  total: number\n  status: FILE_ITEM_DETAIL_STATUS_IN_UI\n  fileName: string\n  contentType: string\n  queryID: string\n  abortController?: AbortController\n  onDelete: (queryID: string, status: FILE_ITEM_DETAIL_STATUS_IN_UI) => void\n  onRetry: (queryID: string) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/components/DetailList/item.tsx",
    "content": "import { getFileIconByContentType } from \"@illa-public/icon\"\nimport { GCS_OBJECT_TYPE } from \"@illa-public/public-types\"\nimport { forwardRef, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  DeleteIcon,\n  ErrorIcon,\n  Progress,\n  SuccessIcon,\n  TriggerProvider,\n  getColor,\n  useModal,\n} from \"@illa-design/react\"\nimport { FILE_ITEM_DETAIL_STATUS_IN_UI, FileItemDetailProps } from \"./interface\"\nimport {\n  fileItemDetailInnerContainerStyle,\n  fileItemDetailOuterContainerStyle,\n  fileNameStyle,\n  fileTypeIconStyle,\n  iconAndNameContainerStyle,\n  iconHotSpotStyle,\n  nameAndProcessContainerStyle,\n  processContainerStyle,\n} from \"./style\"\n\nexport const getIconByStatus = (\n  status: FILE_ITEM_DETAIL_STATUS_IN_UI,\n  total: number,\n  loaded: number,\n  onClickRetry: () => void,\n) => {\n  switch (status) {\n    case FILE_ITEM_DETAIL_STATUS_IN_UI.PROCESSING:\n      const percent = (loaded / total) * 100\n      return (\n        <TriggerProvider renderInBody={false}>\n          <Progress\n            type=\"miniCircle\"\n            percent={percent > 90 ? 90 : parseFloat(percent.toFixed(2))}\n          />\n        </TriggerProvider>\n      )\n\n    case FILE_ITEM_DETAIL_STATUS_IN_UI.SUCCESS:\n      return <SuccessIcon color={getColor(\"green\", \"03\")} />\n    case FILE_ITEM_DETAIL_STATUS_IN_UI.ERROR:\n      return <ErrorIcon onClick={onClickRetry} color={getColor(\"red\", \"03\")} />\n    default:\n      return null\n  }\n}\n\nexport const FileItemDetail = forwardRef<HTMLDivElement, FileItemDetailProps>(\n  (props, ref) => {\n    const {\n      fileName,\n      contentType,\n      status,\n      total,\n      loaded,\n      abortController,\n      onRetry,\n      onDelete,\n      queryID,\n    } = props\n\n    const modal = useModal()\n    const { t } = useTranslation()\n\n    const onClickRetry = useCallback(() => {\n      onRetry && onRetry(queryID)\n    }, [onRetry, queryID])\n\n    const onClickDeleteOK = useCallback(() => {\n      abortController?.abort()\n      onDelete && onDelete(queryID, status)\n    }, [abortController, onDelete, queryID, status])\n\n    const onClickDelete = useCallback(() => {\n      if (\n        status === FILE_ITEM_DETAIL_STATUS_IN_UI.SUCCESS ||\n        status === FILE_ITEM_DETAIL_STATUS_IN_UI.ERROR\n      ) {\n        onClickDeleteOK()\n      } else {\n        modal.show({\n          z: 1020,\n          title: t(\"drive.modal.delete_going_on_task.title\"),\n          content: t(\"drive.modal.delete_going_on_task.description\"),\n          okText: t(\"drive.modal.delete_going_on_task.delete\"),\n          cancelText: t(\"drive.modal.delete_going_on_task.cancel\"),\n          okButtonProps: {\n            colorScheme: \"red\",\n          },\n          onOk: onClickDeleteOK,\n        })\n      }\n    }, [modal, onClickDeleteOK, status, t])\n\n    return (\n      <>\n        <div css={fileItemDetailOuterContainerStyle} ref={ref}>\n          <div css={fileItemDetailInnerContainerStyle}>\n            <div css={nameAndProcessContainerStyle}>\n              <div css={iconAndNameContainerStyle}>\n                {getFileIconByContentType(\n                  GCS_OBJECT_TYPE.FILE,\n                  contentType,\n                  fileTypeIconStyle,\n                )}\n                <span css={fileNameStyle(status)}>{fileName}</span>\n              </div>\n              <div css={processContainerStyle}>\n                {getIconByStatus(status, total, loaded, onClickRetry)}\n                <span css={iconHotSpotStyle} onClick={onClickDelete}>\n                  <DeleteIcon />\n                </span>\n              </div>\n            </div>\n          </div>\n        </div>\n      </>\n    )\n  },\n)\n\nFileItemDetail.displayName = \"FileItemDetail\"\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/components/DetailList/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { PROCESS_DETAIL_LIST_HEIGHT } from \"./constants\"\nimport { FILE_ITEM_DETAIL_STATUS_IN_UI } from \"./interface\"\n\nexport const fileListContainerStyle = css`\n  padding: 0;\n`\n\n// Item Style\nexport const fileItemDetailOuterContainerStyle = css`\n  height: 52px;\n  display: flex;\n  justify-content: space-between;\n`\n\nexport const fileItemDetailInnerContainerStyle = css`\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  height: 36px;\n`\n\nexport const iconAndNameContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 12px;\n`\n\nexport const nameAndProcessContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  background-color: ${getColor(\"grayBlue\", \"09\")};\n  border-radius: 2px;\n  width: 100%;\n  padding: 0 12px;\n  height: 36px;\n`\n\nexport const fileTypeIconStyle = css`\n  width: 16px;\n  height: 20px;\n`\n\nexport const fileNameStyle = (status: FILE_ITEM_DETAIL_STATUS_IN_UI) => css`\n  color: ${status === FILE_ITEM_DETAIL_STATUS_IN_UI.ERROR\n    ? getColor(\"red\", \"03\")\n    : getColor(\"grayBlue\", \"02\")};\n  display: inline-block;\n  max-width: 364px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n`\n\nexport const processContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 16px;\n`\n\nexport const iconHotSpotStyle = css`\n  width: 16px;\n  height: 16px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n`\n\n// empty style\nexport const emptyStateStyle = css`\n  display: flex;\n  width: 100%;\n  height: ${PROCESS_DETAIL_LIST_HEIGHT}px;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/components/ProcessDetailModal/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC } from \"react\"\nimport { MinimizeIcon, Modal, getColor } from \"@illa-design/react\"\nimport { UploadFileList } from \"../DetailList\"\nimport { IUpdateDetailModalProps } from \"./interface\"\nimport { buttonGroupContainerStyle, modalContainerStyle } from \"./style\"\n\nexport const ProcessDetailModal: FC<IUpdateDetailModalProps> = (props) => {\n  const { open, changeOpen } = props\n\n  return (\n    <Modal\n      title={null}\n      visible={open}\n      footer={false}\n      closable={false}\n      onCancel={() => {\n        changeOpen(false)\n      }}\n    >\n      <div css={modalContainerStyle}>\n        <div css={buttonGroupContainerStyle}>\n          <IconHotSpot\n            inactiveColor={getColor(\"grayBlue\", \"02\")}\n            onClick={() => {\n              changeOpen(false)\n            }}\n          >\n            <MinimizeIcon />\n          </IconHotSpot>\n        </div>\n        <UploadFileList />\n      </div>\n    </Modal>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/components/ProcessDetailModal/interface.ts",
    "content": "export interface IUpdateDetailModalProps {\n  open: boolean\n  changeOpen: (open: boolean) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/components/ProcessDetailModal/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const modalContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 24px;\n`\n\nexport const buttonGroupContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: end;\n  gap: 8px;\n`\n\nexport const iconHotSpotStyle = css`\n  width: 24px;\n  height: 24px;\n  font-size: 24px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  cursor: pointer;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/index.tsx",
    "content": "import { motion } from \"framer-motion\"\nimport { FC, useState, useSyncExternalStore } from \"react\"\nimport { ClearIcon, Loading, SuccessIcon, UploadIcon } from \"@illa-design/react\"\nimport { ProcessDetailModal } from \"./components/ProcessDetailModal\"\nimport { updateFileDetailStore } from \"./store\"\nimport {\n  closeIconStyle,\n  controllerAreaContainerStyle,\n  placeholderIconStyle,\n  processingTextStyle,\n  uploadDetailContainerStyle,\n  uploadDetailOuterContainerStyle,\n} from \"./style\"\nimport { getAreaStatues, getSuccessFiles } from \"./utils\"\n\nconst getStatusIcon = (status: \"success\" | \"processing\" | \"initial\") => {\n  switch (status) {\n    case \"success\":\n      return <SuccessIcon />\n    case \"processing\":\n      return <Loading colorScheme=\"grayBlue\" />\n    case \"initial\":\n    default:\n      return <span css={placeholderIconStyle} />\n  }\n}\n\nexport const UploadDetailButton: FC = () => {\n  const [processModalVisible, setProcessModalVisible] = useState(false)\n  const [showButton, setShowButton] = useState(true)\n  const uploadFiles = useSyncExternalStore(\n    updateFileDetailStore.subscribe,\n    updateFileDetailStore.getSnapshot,\n  )\n\n  return (\n    <>\n      <motion.div\n        initial={{\n          y: 0,\n        }}\n        animate={\n          showButton\n            ? {\n                y: -32,\n              }\n            : {\n                y: 16,\n              }\n        }\n        css={uploadDetailOuterContainerStyle}\n      >\n        <div\n          css={uploadDetailContainerStyle}\n          onMouseEnter={() => {\n            if (!showButton) {\n              setShowButton(true)\n            }\n          }}\n        >\n          <div\n            css={controllerAreaContainerStyle}\n            onClick={() => {\n              if (showButton) {\n                setProcessModalVisible(true)\n              } else {\n                setShowButton(true)\n              }\n            }}\n          >\n            <UploadIcon />\n            <span css={processingTextStyle}>\n              {getSuccessFiles(uploadFiles).length}/{uploadFiles.length}\n            </span>\n            {getStatusIcon(getAreaStatues(uploadFiles))}\n          </div>\n          <ClearIcon\n            onClick={() => {\n              setShowButton(false)\n            }}\n            css={closeIconStyle(showButton)}\n          />\n        </div>\n      </motion.div>\n      <ProcessDetailModal\n        open={processModalVisible}\n        changeOpen={setProcessModalVisible}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/store/index.ts",
    "content": "import {\n  CollarModalType,\n  handleCollaPurchaseError,\n} from \"@illa-public/upgrade-modal\"\nimport { uploadFileToDrive } from \"@/utils/drive/upload/getSingedURL\"\nimport { IUploadDetailStore } from \"./interface\"\n\nexport const updateFileDetailStore: IUploadDetailStore = {\n  fileDetailInfos: [],\n  listeners: [],\n  subscribe(listener) {\n    updateFileDetailStore.listeners.push(listener)\n    return () => {\n      updateFileDetailStore.listeners = updateFileDetailStore.listeners.filter(\n        (l) => l !== listener,\n      )\n    }\n  },\n  addFileDetailInfo(fileDetailInfo) {\n    updateFileDetailStore.fileDetailInfos = [\n      ...updateFileDetailStore.fileDetailInfos,\n      fileDetailInfo,\n    ]\n    updateFileDetailStore.listeners.forEach((listener) => listener())\n  },\n  updateFileDetailInfo(queryID, fileDetailInfo) {\n    const index = updateFileDetailStore.fileDetailInfos.findIndex(\n      (item) => item.queryID === queryID,\n    )\n    if (index !== -1) {\n      updateFileDetailStore.fileDetailInfos[index] = {\n        ...updateFileDetailStore.fileDetailInfos[index],\n        ...fileDetailInfo,\n      }\n      updateFileDetailStore.fileDetailInfos = [\n        ...updateFileDetailStore.fileDetailInfos,\n      ]\n      updateFileDetailStore.listeners.forEach((listener) => listener())\n    }\n  },\n  deleteFileDetailInfo(queryID) {\n    updateFileDetailStore.fileDetailInfos =\n      updateFileDetailStore.fileDetailInfos.filter(\n        (item) => item.queryID !== queryID,\n      )\n    updateFileDetailStore.listeners.forEach((listener) => listener())\n  },\n  retryUpload(queryID) {\n    const uploadInfo = updateFileDetailStore.fileDetailInfos.find(\n      (item) => item.queryID === queryID,\n    )\n    if (uploadInfo && uploadInfo.saveToILLADriveParams) {\n      uploadFileToDrive(\n        queryID,\n        uploadInfo.saveToILLADriveParams.fileData,\n        uploadInfo.saveToILLADriveParams,\n        uploadInfo.abortController?.signal!,\n      ).catch((e) => {\n        handleCollaPurchaseError(\n          e,\n          CollarModalType.STORAGE,\n          \"upload_detail_re_try_storage_not_enough\",\n        )\n      })\n      updateFileDetailStore.listeners.forEach((listener) => listener())\n    }\n  },\n  getSnapshot() {\n    return updateFileDetailStore.fileDetailInfos\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/store/interface.ts",
    "content": "import { FILE_ITEM_DETAIL_STATUS_IN_UI } from \"../components/DetailList/interface\"\n\ninterface ISaveToILLADriveParams {\n  fileData: File\n  folder: string\n  allowAnonymous: boolean\n  replace: boolean\n}\nexport interface FileDetailInfos {\n  loaded: number\n  total: number\n  status: FILE_ITEM_DETAIL_STATUS_IN_UI\n  fileName: string\n  contentType: string\n  queryID: string\n  abortController?: AbortController\n  saveToILLADriveParams?: ISaveToILLADriveParams\n}\nexport interface IUploadDetailStore {\n  fileDetailInfos: FileDetailInfos[]\n  listeners: (() => void)[]\n  subscribe: (onStoreChange: () => void) => () => void\n  addFileDetailInfo: (fileDetailInfo: FileDetailInfos) => void\n  updateFileDetailInfo: (\n    queryID: string,\n    fileDetailInfo: Partial<{\n      loaded: number\n      total: number\n      status: FILE_ITEM_DETAIL_STATUS_IN_UI\n      saveToILLADriveParams: ISaveToILLADriveParams\n    }>,\n  ) => void\n  deleteFileDetailInfo: (queryID: string) => void\n  retryUpload: (queryID: string) => void\n  getSnapshot: () => FileDetailInfos[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const uploadDetailContainerStyle = css`\n  padding: 5px 16px;\n  padding-right: 8px;\n  border-radius: 16px;\n  background-color: ${getColor(\"white\", \"01\")};\n  color: ${getColor(\"grayBlue\", \"02\")};\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.16);\n  width: fit-content;\n  pointer-events: all;\n`\n\nexport const uploadDetailOuterContainerStyle = css`\n  position: absolute;\n  width: 100%;\n  bottom: 0;\n  display: flex;\n  justify-content: center;\n  pointer-events: none;\n`\n\nexport const controllerAreaContainerStyle = css`\n  display: flex;\n  gap: 8px;\n  align-items: center;\n  cursor: pointer;\n  user-select: none;\n`\n\nexport const processingTextStyle = css`\n  font-size: 14px;\n  line-height: 22px;\n`\n\nexport const placeholderIconStyle = css`\n  display: inline-block;\n  width: 16px;\n  height: 16px;\n`\n\nexport const closeIconStyle = (showButton: boolean) => css`\n  color: ${getColor(\"grayBlue\", \"06\")};\n  display: ${showButton ? \"flex\" : \"none\"};\n  cursor: pointer;\n  margin-left: 16px;\n  font-size: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/Module/UploadDetail/utils.ts",
    "content": "import { FILE_ITEM_DETAIL_STATUS_IN_UI } from \"./components/DetailList/interface\"\nimport { FileDetailInfos } from \"./store/interface\"\n\nexport const getSuccessFiles = (files: FileDetailInfos[]) => {\n  return files.filter(\n    (file) => file.status === FILE_ITEM_DETAIL_STATUS_IN_UI.SUCCESS,\n  )\n}\n\nexport const getFailedFiles = (files: FileDetailInfos[]) => {\n  return files.filter(\n    (file) => file.status === FILE_ITEM_DETAIL_STATUS_IN_UI.ERROR,\n  )\n}\n\nexport const getProcessingFiles = (files: FileDetailInfos[]) => {\n  return files.filter(\n    (file) => file.status === FILE_ITEM_DETAIL_STATUS_IN_UI.PROCESSING,\n  )\n}\n\nexport const getWaitingFiles = (files: FileDetailInfos[]) => {\n  return files.filter(\n    (file) => file.status === FILE_ITEM_DETAIL_STATUS_IN_UI.WAITING,\n  )\n}\n\nexport const getAreaStatues = (files: FileDetailInfos[]) => {\n  const finishedFiles = [...getFailedFiles(files), ...getSuccessFiles(files)]\n  const readyFiles = [...getWaitingFiles(files), ...getProcessingFiles(files)]\n  const isFinished =\n    finishedFiles.length > 0 && finishedFiles.length === files.length\n  const isReady = readyFiles.length > 0\n  if (isFinished) {\n    return \"success\"\n  }\n  if (isReady) {\n    return \"processing\"\n  }\n  return \"initial\"\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionGuidePanel/components/ActionSection/index.tsx",
    "content": "import { getIconFromResourceType } from \"@illa-public/icon\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport {\n  INIT_ACTION_ADVANCED_CONFIG,\n  INIT_ACTION_MOCK_CONFIG,\n  actionItemInitial,\n  getInitialContent,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionContent,\n  ActionItem,\n  ActionType,\n  GlobalDataActionContent,\n  Resource,\n} from \"@illa-public/public-types\"\nimport {\n  ActionGenerator,\n  ResourceGeneratorProvider,\n  getResourceNameFromResourceType,\n} from \"@illa-public/resource-generator\"\nimport { FC, Suspense, memo, useCallback, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { v4 } from \"uuid\"\nimport { Button, NextIcon, useMessage } from \"@illa-design/react\"\nimport { useCreateAction } from \"@/page/App/components/Actions/hook\"\nimport { getIsILLAGuideMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getAllResources } from \"@/redux/resource/resourceSelector\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { fetchCreateAction } from \"@/services/action\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { track } from \"@/utils/mixpanelHelper\"\nimport { PanelSectionProps } from \"./interface\"\nimport {\n  basicButtonStyle,\n  categoryItemContainerStyle,\n  categoryItemNameStyle,\n  categoryTitleStyle,\n  headerContainerStyle,\n} from \"./style\"\n\nconst ActionPanelSection: FC<PanelSectionProps> = (props) => {\n  const { actionTypes, title, hasMore, changeLoading, filterFunc } = props\n  const { t } = useTranslation()\n\n  const [generatorVisible, setGeneratorVisible] = useState<boolean>()\n  const [currentActionType, setCurrentActionType] =\n    useState<ActionType | null>()\n\n  const isGuideMode = useSelector(getIsILLAGuideMode)\n  const resourceList = useSelector(getAllResources)\n  const dispatch = useDispatch()\n  const message = useMessage()\n\n  const handleClickActionType = (type: ActionType | null) => {\n    return async () => {\n      switch (type) {\n        case \"transformer\": {\n          const displayName = DisplayNameGenerator.generateDisplayName(type)\n          const initialContent = getInitialContent(type)\n          const data: Omit<ActionItem<ActionContent>, \"actionID\"> = {\n            actionType: type,\n            displayName,\n            content: initialContent,\n            isVirtualResource: false,\n            config: {\n              public: false,\n              advancedConfig: INIT_ACTION_ADVANCED_CONFIG,\n              mockConfig: INIT_ACTION_MOCK_CONFIG,\n            },\n            ...actionItemInitial,\n          }\n          if (isGuideMode) {\n            const createActionData: ActionItem<ActionContent> = {\n              ...data,\n              actionID: v4(),\n            }\n            dispatch(actionActions.addActionItemReducer(createActionData))\n            dispatch(configActions.changeSelectedAction(createActionData))\n            return\n          }\n          changeLoading(true)\n          try {\n            const { data: responseData } = await fetchCreateAction(data)\n            message.success({\n              content: t(\"editor.action.action_list.message.success_created\"),\n            })\n            dispatch(actionActions.addActionItemReducer(responseData))\n            dispatch(configActions.changeSelectedAction(responseData))\n          } catch (_e) {\n            message.error({\n              content: t(\"editor.action.action_list.message.failed\"),\n            })\n            DisplayNameGenerator.removeDisplayName(displayName)\n          } finally {\n            changeLoading(false)\n          }\n          break\n        }\n        case \"globalData\": {\n          const displayName = DisplayNameGenerator.generateDisplayName(\"state\")\n          dispatch(\n            componentsActions.setGlobalStateReducer({\n              key: displayName,\n              value: \"\",\n              oldKey: \"\",\n            }),\n          )\n          const createActionData: ActionItem<GlobalDataActionContent> = {\n            actionID: displayName,\n            displayName: displayName,\n            actionType: \"globalData\",\n            triggerMode: \"manually\",\n            isVirtualResource: true,\n            content: {\n              initialValue: \"\",\n            },\n            transformer: {\n              enable: false,\n              rawData: \"\",\n            },\n            config: {\n              public: false,\n              advancedConfig: INIT_ACTION_ADVANCED_CONFIG,\n              mockConfig: INIT_ACTION_MOCK_CONFIG,\n            },\n          }\n          dispatch(configActions.changeSelectedAction(createActionData))\n\n          break\n        }\n        case \"illadrive\": {\n          const displayName = DisplayNameGenerator.generateDisplayName(type)\n          const initialContent = getInitialContent(type)\n          const data: Omit<ActionItem<ActionContent>, \"actionID\"> = {\n            actionType: type,\n            displayName,\n            content: initialContent,\n            isVirtualResource: true,\n            config: {\n              public: false,\n              advancedConfig: INIT_ACTION_ADVANCED_CONFIG,\n              mockConfig: INIT_ACTION_MOCK_CONFIG,\n            },\n            ...actionItemInitial,\n          }\n          try {\n            const { data: responseData } = await fetchCreateAction(data)\n            message.success({\n              content: t(\"editor.action.action_list.message.success_created\"),\n            })\n            dispatch(actionActions.addActionItemReducer(responseData))\n            dispatch(configActions.changeSelectedAction(responseData))\n          } catch (_e) {\n            message.error({\n              content: t(\"editor.action.action_list.message.failed\"),\n            })\n            DisplayNameGenerator.removeDisplayName(displayName)\n          }\n          break\n        }\n        default: {\n          setGeneratorVisible(true)\n          setCurrentActionType(type)\n        }\n      }\n    }\n  }\n\n  const [handleDirectCreateAction, handleCreateAgentAction] = useCreateAction()\n\n  const handleFinishCreateNewResource = useCallback(\n    (resource: Resource, isUpdate: boolean) => {\n      track(\n        ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n        ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR,\n        {\n          element: \"resource_configure_save\",\n          parameter5: resource.resourceType,\n        },\n      )\n      if (isUpdate) {\n        dispatch(resourceActions.updateResourceItemReducer(resource))\n      } else {\n        dispatch(resourceActions.addResourceItemReducer(resource))\n      }\n      handleDirectCreateAction(resource.resourceType, resource.resourceID)\n    },\n    [dispatch, handleDirectCreateAction],\n  )\n\n  return (\n    <>\n      <div css={headerContainerStyle}>\n        <h6 css={categoryTitleStyle}>{title}</h6>\n        {hasMore && (\n          <Button\n            colorScheme=\"techPurple\"\n            variant=\"text\"\n            rightIcon={<NextIcon />}\n            onClick={handleClickActionType(null)}\n          >\n            {t(\"editor.action.panel.label.option.general.more\")}\n          </Button>\n        )}\n      </div>\n      <section css={categoryItemContainerStyle}>\n        {actionTypes.filter(filterFunc ?? ((type) => type)).map((type) => (\n          <button\n            css={basicButtonStyle}\n            key={type}\n            onClick={handleClickActionType(type)}\n          >\n            <Suspense>{getIconFromResourceType(type, \"16px\")}</Suspense>\n            <span css={categoryItemNameStyle}>\n              {getResourceNameFromResourceType(type)}\n            </span>\n          </button>\n        ))}\n      </section>\n      {generatorVisible && (\n        <MixpanelTrackProvider\n          basicTrack={track}\n          pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR}\n        >\n          <ResourceGeneratorProvider\n            allResource={resourceList}\n            createOrUpdateResourceCallback={handleFinishCreateNewResource}\n          >\n            <ActionGenerator\n              visible={generatorVisible}\n              onClose={() => setGeneratorVisible(false)}\n              defaultStep={currentActionType ? \"createAction\" : \"select\"}\n              defaultActionType={currentActionType}\n              canBackToSelect={false}\n              handleDirectCreateAction={handleDirectCreateAction}\n              handleCreateAgentAction={handleCreateAgentAction}\n            />\n          </ResourceGeneratorProvider>\n        </MixpanelTrackProvider>\n      )}\n    </>\n  )\n}\n\nexport default memo(ActionPanelSection)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionGuidePanel/components/ActionSection/interface.ts",
    "content": "import { ActionType } from \"@illa-public/public-types\"\n\nexport interface PanelSectionProps {\n  actionTypes: ActionType[]\n  changeLoading: (isLoading: boolean) => void\n  filterFunc?: (actionType: ActionType) => boolean\n  title: string\n  hasMore: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionGuidePanel/components/ActionSection/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const categoryTitleStyle = css`\n  padding: 0;\n  padding-top: 16px;\n  padding-bottom: 8px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n  margin: 0;\n`\n\nexport const headerContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  width: 536px;\n`\n\nexport const categoryItemContainerStyle = css`\n  display: grid;\n  gap: 16px;\n  grid-template-columns: repeat(3, 168px);\n`\n\nexport const basicButtonStyle = css`\n  display: flex;\n  width: 100%;\n  padding: 8px 16px;\n  gap: 12px;\n  align-items: center;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  border-radius: 8px;\n  background-color: white;\n  cursor: pointer;\n  transition: all 0.2s ease-in-out;\n  &:hover {\n    box-shadow: 0 4px 10px 0 ${getColor(\"blackAlpha\", \"07\")};\n    background-color: ${getColor(\"techPurple\", \"08\")};\n    border-color: ${getColor(\"techPurple\", \"03\")};\n  }\n`\n\nexport const categoryItemNameStyle = css`\n  font-weight: 500;\n  font-size: 12px;\n  line-height: 20px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionGuidePanel/components/AgentSection/index.tsx",
    "content": "import { getAIAgentMarketplaceInfo } from \"@illa-public/market-agent\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport {\n  INIT_ACTION_ADVANCED_CONFIG,\n  actionItemInitial,\n  getInitialAgentContent,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionContent,\n  ActionItem,\n  Agent,\n  AiAgentActionContent,\n  Resource,\n} from \"@illa-public/public-types\"\nimport {\n  ActionGenerator,\n  ResourceGeneratorProvider,\n} from \"@illa-public/resource-generator\"\nimport { FC, memo, useCallback, useEffect, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { v4 } from \"uuid\"\nimport { Button, NextIcon, Skeleton, useMessage } from \"@illa-design/react\"\nimport { getAgentIcon } from \"@/page/App/components/Actions/getIcon\"\nimport { useCreateAction } from \"@/page/App/components/Actions/hook\"\nimport { aiAgentActions } from \"@/redux/aiAgent/dashboardTeamAIAgentSlice\"\nimport { getIsILLAGuideMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { getAllResources } from \"@/redux/resource/resourceSelector\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { fetchCreateAction } from \"@/services/action\"\nimport { forkAIAgentToTeam } from \"@/services/agent\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { track } from \"@/utils/mixpanelHelper\"\nimport { getRecommendAgentID } from \"../../constans\"\nimport { AgentPanelSectionProps } from \"./interface\"\nimport {\n  basicButtonStyle,\n  categoryItemContainerStyle,\n  categoryTitleStyle,\n  descStyle,\n  headerContainerStyle,\n  titleAndContentContainerStyle,\n  titleStyle,\n} from \"./style\"\n\nconst AgentPanelSection: FC<AgentPanelSectionProps> = (props) => {\n  const { agents, title, hasMore, changeLoading } = props\n  const { t } = useTranslation()\n  const [generatorVisible, setGeneratorVisible] = useState<boolean>()\n  const [recommendAgents, setRecommendAgents] = useState<Agent[]>([])\n  const [isLoadingRecommendAgents, setIsLoadingRecommendAgents] =\n    useState(false)\n\n  const isGuideMode = useSelector(getIsILLAGuideMode)\n  const resourceList = useSelector(getAllResources)\n  const dispatch = useDispatch()\n  const message = useMessage()\n  const filterAgents = agents.slice(0, 4)\n\n  const [handleDirectCreateAction, handleCreateAgentAction] = useCreateAction()\n\n  const handleFinishCreateNewResource = useCallback(\n    (resource: Resource, isUpdate: boolean) => {\n      track(\n        ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n        ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR,\n        {\n          element: \"resource_configure_save\",\n          parameter5: resource.resourceType,\n        },\n      )\n      if (isUpdate) {\n        dispatch(resourceActions.updateResourceItemReducer(resource))\n      } else {\n        dispatch(resourceActions.addResourceItemReducer(resource))\n      }\n      handleDirectCreateAction(resource.resourceType, resource.resourceID)\n    },\n    [dispatch, handleDirectCreateAction],\n  )\n\n  const handleClickAction = useCallback(\n    (item: Agent, fromRecommend?: boolean) => {\n      return async () => {\n        if (fromRecommend) {\n          const response = await forkAIAgentToTeam(item.aiAgentID)\n          dispatch(\n            aiAgentActions.addTeamAIAgentReducer({\n              aiAgent: response.data,\n            }),\n          )\n          item = response.data\n        }\n        const displayName = DisplayNameGenerator.generateDisplayName(\"aiagent\")\n        const initalAgentContent = getInitialAgentContent(item)\n        const data: Omit<ActionItem<AiAgentActionContent>, \"actionID\"> = {\n          actionType: \"aiagent\",\n          displayName,\n          resourceID: item.aiAgentID,\n          content: {\n            ...initalAgentContent,\n            virtualResource: item,\n          },\n          isVirtualResource: true,\n          ...actionItemInitial,\n          config: {\n            public: false,\n            advancedConfig: INIT_ACTION_ADVANCED_CONFIG,\n            icon: item.icon,\n          },\n        }\n        if (isGuideMode) {\n          const createActionData: ActionItem<ActionContent> = {\n            ...data,\n            actionID: v4(),\n          }\n          dispatch(actionActions.addActionItemReducer(createActionData))\n          dispatch(configActions.changeSelectedAction(createActionData))\n          return\n        }\n        changeLoading(true)\n        try {\n          const { data: responseData } = await fetchCreateAction(data)\n          message.success({\n            content: t(\"editor.action.action_list.message.success_created\"),\n          })\n          dispatch(actionActions.addActionItemReducer(responseData))\n          dispatch(configActions.changeSelectedAction(responseData))\n        } catch (_e) {\n          message.error({\n            content: t(\"editor.action.action_list.message.failed\"),\n          })\n          DisplayNameGenerator.removeDisplayName(displayName)\n        } finally {\n          changeLoading(false)\n        }\n      }\n    },\n    [changeLoading, dispatch, isGuideMode, message, t],\n  )\n\n  useEffect(() => {\n    const abortController = new AbortController()\n    if (filterAgents.length < 4) {\n      const fetchMarketAgentList = async () => {\n        setIsLoadingRecommendAgents(true)\n        const needFetchAgentID = getRecommendAgentID().slice(\n          filterAgents.length,\n        )\n        const needFetches = needFetchAgentID.map((id) =>\n          getAIAgentMarketplaceInfo(id, abortController.signal),\n        )\n        Promise.all(needFetches)\n          .then((res) => {\n            const result = res.map((item) => item.data.aiAgent)\n            setRecommendAgents(result)\n          })\n          .finally(() => setIsLoadingRecommendAgents(false))\n      }\n      fetchMarketAgentList()\n    }\n\n    return () => {\n      abortController.abort()\n      setIsLoadingRecommendAgents(false)\n    }\n  }, [filterAgents.length])\n\n  return (\n    <>\n      <div css={headerContainerStyle}>\n        <h6 css={categoryTitleStyle}>{title}</h6>\n        {hasMore && (\n          <Button\n            colorScheme=\"techPurple\"\n            variant=\"text\"\n            rightIcon={<NextIcon />}\n            onClick={() => setGeneratorVisible(true)}\n          >\n            {t(\"editor.action.panel.label.option.general.more\")}\n          </Button>\n        )}\n      </div>\n      <section css={categoryItemContainerStyle}>\n        {filterAgents.map((agent) => (\n          <button\n            css={basicButtonStyle}\n            key={agent.aiAgentID}\n            onClick={handleClickAction(agent)}\n          >\n            {getAgentIcon(agent, \"32px\")}\n            <div css={titleAndContentContainerStyle}>\n              <span css={titleStyle}>{agent.name}</span>\n              <span css={descStyle}>{agent.description}</span>\n            </div>\n          </button>\n        ))}\n        {filterAgents.length < 4 &&\n          (isLoadingRecommendAgents\n            ? getRecommendAgentID()\n                .slice(4 - filterAgents.length)\n                .map((v) => (\n                  <button css={basicButtonStyle} key={v}>\n                    <Skeleton\n                      text={false}\n                      animation\n                      image={{\n                        shape: \"square\",\n                        w: \"100%\",\n                        h: \"32px\",\n                        mr: \"0 !important\",\n                      }}\n                      h=\"32px\"\n                      w=\"100%\"\n                    />\n                  </button>\n                ))\n            : recommendAgents.map((agent) => (\n                <button\n                  css={basicButtonStyle}\n                  key={agent.aiAgentID}\n                  onClick={handleClickAction(agent, true)}\n                >\n                  {getAgentIcon(agent, \"32px\")}\n                  <div css={titleAndContentContainerStyle}>\n                    <span css={titleStyle}>{agent.name}</span>\n                    <span css={descStyle}>{agent.description}</span>\n                  </div>\n                </button>\n              )))}\n      </section>\n      {generatorVisible && (\n        <MixpanelTrackProvider\n          basicTrack={track}\n          pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR}\n        >\n          <ResourceGeneratorProvider\n            allResource={resourceList}\n            createOrUpdateResourceCallback={handleFinishCreateNewResource}\n          >\n            <ActionGenerator\n              visible={generatorVisible}\n              onClose={() => setGeneratorVisible(false)}\n              defaultStep=\"createAction\"\n              defaultActionType=\"aiagent\"\n              canBackToSelect={false}\n              handleDirectCreateAction={handleDirectCreateAction}\n              handleCreateAgentAction={handleCreateAgentAction}\n            />\n          </ResourceGeneratorProvider>\n        </MixpanelTrackProvider>\n      )}\n    </>\n  )\n}\n\nexport default memo(AgentPanelSection)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionGuidePanel/components/AgentSection/interface.ts",
    "content": "import { Agent } from \"@illa-public/public-types\"\n\nexport interface AgentPanelSectionProps {\n  agents: Agent[]\n  changeLoading: (isLoading: boolean) => void\n  title: string\n  hasMore: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionGuidePanel/components/AgentSection/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const categoryTitleStyle = css`\n  padding: 0;\n  padding-top: 16px;\n  padding-bottom: 8px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n  margin: 0;\n`\n\nexport const headerContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  width: 536px;\n`\n\nexport const categoryItemContainerStyle = css`\n  display: grid;\n  gap: 16px;\n  padding-bottom: 16px;\n  grid-template-columns: repeat(2, 260px);\n`\n\nexport const basicButtonStyle = css`\n  display: flex;\n  width: 100%;\n  padding: 12px;\n  gap: 8px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  border-radius: 8px;\n  background-color: white;\n  cursor: pointer;\n  transition: all 0.2s ease-in-out;\n  &:hover {\n    box-shadow: 0 4px 10px 0 ${getColor(\"blackAlpha\", \"07\")};\n    background-color: ${getColor(\"techPurple\", \"08\")};\n    border-color: ${getColor(\"techPurple\", \"03\")};\n  }\n`\n\nexport const titleAndContentContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n`\n\nexport const titleStyle = css`\n  display: inline-block;\n  line-height: 16px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 12px;\n  font-weight: 500;\n  text-align: left;\n`\n\nexport const descStyle = css`\n  width: 196px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  line-height: 14px;\n  font-size: 12px;\n  color: ${getColor(\"grayBlue\", \"03\")};\n  font-weight: 400;\n  text-align: left;\n  word-break: break-all;\n  display: -webkit-box;\n  -webkit-box-orient: vertical;\n  -webkit-line-clamp: 2;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionGuidePanel/constans.ts",
    "content": "import { ActionType } from \"@illa-public/public-types\"\nimport { isCloudVersion } from \"@illa-public/utils\"\n\nexport const RECOMMEND_RESOURCES_SELF_HOST: ActionType[] = [\n  \"restapi\",\n  \"mysql\",\n  \"postgresql\",\n  \"airtable\",\n  \"supabasedb\",\n]\n\nexport const MORE_DATA_TYPE_SELF_HOST: ActionType[] = [\n  \"transformer\",\n  \"globalData\",\n]\n\nexport const ONLY_CLOUD_MODE_DATA_TYPE: ActionType[] = [\"aiagent\", \"illadrive\"]\n\nexport const RECOMMEND_RESOURCES_CLOUD: ActionType[] = [\n  \"restapi\",\n  \"mysql\",\n  \"huggingface\",\n  \"postgresql\",\n]\n\nexport const getRecommendAgentID = () => {\n  switch (import.meta.env.ILLA_APP_ENV) {\n    case \"beta\":\n      return [\"ILAfx4p1C7c5\", \"ILAfx4p1C7c4\", \"ILAfx4p1C7c3\", \"ILAfx4p1C7dm\"]\n    case \"production\":\n      return [\"ILAfx4p1C7eu\", \"ILAfx4p1C7en\", \"ILAfx4p1C7ee\", \"ILAfx4p1C7eh\"]\n    default:\n      return [\"ILAfx4p1C7dC\", \"ILAfx4p1C7dB\", \"ILAfx4p1C7dA\", \"ILAfx4p1C7dz\"]\n  }\n}\n\nexport function filterSelfHostActionType(actionType: ActionType) {\n  if (!isCloudVersion) return !ONLY_CLOUD_MODE_DATA_TYPE.includes(actionType)\n  return !!actionType\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionGuidePanel/index.tsx",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport { FC, memo, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { Loading } from \"@illa-design/react\"\nimport { getDashboardTeamAIAgentList } from \"@/redux/aiAgent/dashboardTeamAIAgentSelector\"\nimport ActionPanelSection from \"./components/ActionSection\"\nimport AgentPanelSection from \"./components/AgentSection\"\nimport {\n  MORE_DATA_TYPE_SELF_HOST,\n  RECOMMEND_RESOURCES_CLOUD,\n  RECOMMEND_RESOURCES_SELF_HOST,\n} from \"./constans\"\nimport {\n  guidePanelContainerStyle,\n  guidePanelOutContainerStyle,\n  loadingContainerStyle,\n} from \"./style\"\n\nconst ActionGuidePanel: FC = () => {\n  const { t } = useTranslation()\n  const [isLoading, setIsLoading] = useState(false)\n  const agentList = useSelector(getDashboardTeamAIAgentList)\n\n  return (\n    <>\n      <div css={guidePanelOutContainerStyle}>\n        <div css={guidePanelContainerStyle}>\n          {!isCloudVersion ? (\n            <>\n              <ActionPanelSection\n                title={t(\n                  \"editor.action.panel.label.general.connect-data-source\",\n                )}\n                actionTypes={RECOMMEND_RESOURCES_SELF_HOST}\n                changeLoading={setIsLoading}\n                hasMore\n              />\n              <ActionPanelSection\n                title={t(\"editor.action.panel.label.general.more-type\")}\n                actionTypes={MORE_DATA_TYPE_SELF_HOST}\n                changeLoading={setIsLoading}\n                hasMore={false}\n              />\n            </>\n          ) : (\n            <>\n              <ActionPanelSection\n                title={t(\n                  \"editor.action.panel.label.general.connect-data-source\",\n                )}\n                actionTypes={RECOMMEND_RESOURCES_CLOUD}\n                changeLoading={setIsLoading}\n                hasMore\n              />\n              <AgentPanelSection\n                title={t(\"editor.action.panel.label.general.ai_agent_title\")}\n                agents={agentList}\n                hasMore\n                changeLoading={setIsLoading}\n              />\n            </>\n          )}\n          {isLoading && (\n            <div css={loadingContainerStyle}>\n              <Loading colorScheme=\"techPurple\" />\n            </div>\n          )}\n        </div>\n      </div>\n    </>\n  )\n}\n\nexport default memo(ActionGuidePanel)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionGuidePanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const guidePanelOutContainerStyle = css`\n  display: flex;\n  width: 100%;\n  height: 100%;\n  padding: 24px 16px;\n  overflow-x: auto;\n`\n\nexport const guidePanelContainerStyle = css`\n  width: 584px;\n  height: 100%;\n  position: relative;\n  margin: 0 auto;\n`\n\nexport const loadingContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  position: absolute;\n  top: 0;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  background-color: ${getColor(\"white\", \"03\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionList/index.tsx",
    "content": "import { FC, HTMLAttributes, useCallback, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useGoogleAuthStatus } from \"@/hooks/useGoogleAuthStatus\"\nimport { SearchHeader } from \"@/page/App/components/Actions/SearchHeader\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport { ActionListWithNewButton } from \"./listWithNewButton\"\nimport { searchHeaderContainerStyle } from \"./style\"\n\nexport const ActionList: FC<HTMLAttributes<HTMLDivElement>> = (props) => {\n  const { className } = props\n\n  const [searchActionValue, setSearchActionValue] = useState(\"\")\n\n  const handleOnSearch = useCallback((value: string) => {\n    setSearchActionValue(value)\n  }, [])\n\n  const actionList = useSelector(getActionList)\n\n  const dispatch = useDispatch()\n\n  useGoogleAuthStatus((resourceID: string) => {\n    const resourceAction = actionList.find((r) => r.resourceID === resourceID)\n    if (resourceAction) {\n      dispatch(configActions.changeSelectedAction(resourceAction))\n    }\n  })\n\n  return (\n    <div className={className} css={searchHeaderContainerStyle}>\n      <SearchHeader onSearch={handleOnSearch} />\n      <ActionListWithNewButton searchActionValue={searchActionValue} />\n    </div>\n  )\n}\n\nActionList.displayName = \"ActionList\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionList/interface.ts",
    "content": "export interface ListWithNewButtonProps {\n  searchActionValue: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionList/listWithNewButton.tsx",
    "content": "import { UpgradeIcon, getIconFromResourceType } from \"@illa-public/icon\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport {\n  INIT_ACTION_ADVANCED_CONFIG,\n  INIT_ACTION_MOCK_CONFIG,\n  actionItemInitial,\n  generateBaseActionItem,\n  getInitialContent,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionContent,\n  ActionItem,\n  ActionType,\n  GlobalDataActionContent,\n  Resource,\n} from \"@illa-public/public-types\"\nimport {\n  ActionGenerator,\n  ResourceGeneratorProvider,\n} from \"@illa-public/resource-generator\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { isSubscribeForUseDrive } from \"@illa-public/upgrade-modal/utils\"\nimport { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { isEqual } from \"lodash-es\"\nimport { FC, useCallback, useContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { v4 } from \"uuid\"\nimport {\n  AddIcon,\n  Button,\n  DropList,\n  DropListItem,\n  Dropdown,\n  Empty,\n  List,\n  Space,\n  useMessage,\n  useModal,\n} from \"@illa-design/react\"\nimport ActionListEmptyState from \"@/assets/action-list-empty-state.svg?react\"\nimport {\n  getCachedAction,\n  getIsILLAGuideMode,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getActionMixedList } from \"@/redux/currentApp/action/actionSelector\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getAllResources } from \"@/redux/resource/resourceSelector\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { fetchCreateAction } from \"@/services/action\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { track } from \"@/utils/mixpanelHelper\"\nimport { ShortCutContext } from \"@/utils/shortcut/shortcutProvider\"\nimport DatabaseIcon from \"../../Icons/database\"\nimport { ActionListItem } from \"../ActionListItem\"\nimport { onCopyActionItem } from \"../api\"\nimport { useCreateAction } from \"../hook\"\nimport { ListWithNewButtonProps } from \"./interface\"\nimport {\n  actionListEmptyStyle,\n  addNewActionButtonStyle,\n  createDropListItemContainerStyle,\n  dropListWithUpgradeIconStyle,\n  listContainerStyle,\n  listStyle,\n  prefixIconContainerStyle,\n  upgradeContainerStyle,\n} from \"./style\"\n\nexport const ActionListWithNewButton: FC<ListWithNewButtonProps> = (props) => {\n  const { searchActionValue } = props\n  const selectedAction = useSelector(getSelectedAction)\n  const cachedAction = useSelector(getCachedAction)\n  const isGuideMode = useSelector(getIsILLAGuideMode)\n  const resourceList = useSelector(getAllResources)\n  const shortcut = useContext(ShortCutContext)\n  const [generatorVisible, setGeneratorVisible] = useState<boolean>()\n  const [currentActionType, setCurrentActionType] =\n    useState<ActionType | null>()\n  const actionList = useSelector(getActionMixedList)\n  const teamInfo = useSelector(getCurrentTeamInfo)!\n  const upgradeModal = useUpgradeModal()\n\n  const searchList = actionList.filter((value) => {\n    return value.displayName\n      .toLowerCase()\n      .includes(searchActionValue.toLowerCase())\n  })\n\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const modal = useModal()\n  const message = useMessage()\n\n  const handleClickActionType = (type: ActionType | null) => {\n    return async () => {\n      switch (type) {\n        case \"transformer\": {\n          const displayName = DisplayNameGenerator.generateDisplayName(type)\n          const initialContent = getInitialContent(type)\n          const data: Omit<ActionItem<ActionContent>, \"actionID\"> = {\n            actionType: type,\n            displayName,\n            content: initialContent,\n            isVirtualResource: false,\n            config: {\n              public: false,\n              advancedConfig: INIT_ACTION_ADVANCED_CONFIG,\n              mockConfig: INIT_ACTION_MOCK_CONFIG,\n            },\n            ...actionItemInitial,\n          }\n          if (isGuideMode) {\n            const createActionData: ActionItem<ActionContent> = {\n              ...data,\n              actionID: v4(),\n            }\n            dispatch(actionActions.addActionItemReducer(createActionData))\n            dispatch(configActions.changeSelectedAction(createActionData))\n            return\n          }\n          try {\n            const { data: responseData } = await fetchCreateAction(data)\n            message.success({\n              content: t(\"editor.action.action_list.message.success_created\"),\n            })\n            dispatch(actionActions.addActionItemReducer(responseData))\n            dispatch(configActions.changeSelectedAction(responseData))\n          } catch (_e) {\n            message.error({\n              content: t(\"editor.action.action_list.message.failed\"),\n            })\n            DisplayNameGenerator.removeDisplayName(displayName)\n          }\n          break\n        }\n        case \"globalData\": {\n          const displayName = DisplayNameGenerator.generateDisplayName(\"state\")\n          dispatch(\n            componentsActions.setGlobalStateReducer({\n              key: displayName,\n              value: \"\",\n              oldKey: \"\",\n            }),\n          )\n          const createActionData: ActionItem<GlobalDataActionContent> = {\n            actionID: displayName,\n            displayName: displayName,\n            actionType: \"globalData\",\n            triggerMode: \"manually\",\n            isVirtualResource: true,\n            content: {\n              initialValue: \"\",\n            },\n            transformer: {\n              enable: false,\n              rawData: \"\",\n            },\n            config: {\n              public: false,\n              advancedConfig: INIT_ACTION_ADVANCED_CONFIG,\n              mockConfig: INIT_ACTION_MOCK_CONFIG,\n            },\n          }\n          dispatch(configActions.changeSelectedAction(createActionData))\n          break\n        }\n        case \"illadrive\": {\n          if (!isSubscribeForUseDrive(teamInfo)) {\n            upgradeModal({\n              modalType: \"upgrade\",\n              from: \"drive_action\",\n            })\n            return\n          }\n          const displayName = DisplayNameGenerator.generateDisplayName(type)\n          const initialContent = getInitialContent(type)\n          const baseData = generateBaseActionItem(displayName, \"\")\n          const data = {\n            ...baseData,\n            actionType: type,\n            content: initialContent,\n            isVirtualResource: true,\n          }\n\n          if (isGuideMode) {\n            const createActionData: ActionItem<ActionContent> = {\n              ...data,\n              actionID: v4(),\n            }\n            dispatch(actionActions.addActionItemReducer(createActionData))\n            dispatch(configActions.changeSelectedAction(createActionData))\n            return\n          }\n          try {\n            const { data: responseData } = await fetchCreateAction(data)\n            message.success({\n              content: t(\"editor.action.action_list.message.success_created\"),\n            })\n            dispatch(actionActions.addActionItemReducer(responseData))\n            dispatch(configActions.changeSelectedAction(responseData))\n          } catch (_e) {\n            message.error({\n              content: t(\"editor.action.action_list.message.failed\"),\n            })\n            DisplayNameGenerator.removeDisplayName(displayName)\n          }\n          break\n        }\n        default: {\n          setGeneratorVisible(true)\n          setCurrentActionType(type)\n        }\n      }\n    }\n  }\n\n  const [handleDirectCreateAction, handleCreateAgentAction] = useCreateAction()\n\n  const handleFinishCreateNewResource = useCallback(\n    (resource: Resource, isUpdate: boolean) => {\n      track(\n        ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n        ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR,\n        {\n          element: \"resource_configure_save\",\n          parameter5: resource.resourceType,\n        },\n      )\n      if (isUpdate) {\n        dispatch(resourceActions.updateResourceItemReducer(resource))\n      } else {\n        dispatch(resourceActions.addResourceItemReducer(resource))\n      }\n      handleDirectCreateAction(\n        resource.resourceType,\n        resource.resourceID,\n        () => {\n          setGeneratorVisible(false)\n        },\n      )\n    },\n    [dispatch, handleDirectCreateAction],\n  )\n\n  return (\n    <>\n      <Dropdown\n        dropList={\n          <DropList w=\"222px\">\n            <DropListItem\n              value=\"database\"\n              key=\"database\"\n              title={\n                <div css={createDropListItemContainerStyle}>\n                  <span css={prefixIconContainerStyle}>\n                    <DatabaseIcon />\n                  </span>\n                  {t(\n                    \"editor.action.panel.label.option.general.create-resource\",\n                  )}\n                </div>\n              }\n              onClick={handleClickActionType(null)}\n            />\n            <DropListItem\n              key=\"transformer\"\n              value=\"transformer\"\n              title={\n                <div css={createDropListItemContainerStyle}>\n                  <span css={prefixIconContainerStyle}>\n                    {getIconFromResourceType(\"transformer\", \"16px\")}\n                  </span>\n                  {t(\"editor.action.panel.label.option.general.js\")}\n                </div>\n              }\n              onClick={handleClickActionType(\"transformer\")}\n            />\n            <DropListItem\n              key=\"globalData\"\n              value=\"globalData\"\n              title={\n                <div css={createDropListItemContainerStyle}>\n                  <span css={prefixIconContainerStyle}>\n                    {getIconFromResourceType(\"globalData\", \"16px\")}\n                  </span>\n                  {t(\"editor.action.panel.label.option.general.global-data\")}\n                </div>\n              }\n              onClick={handleClickActionType(\"globalData\")}\n            />\n            {isCloudVersion && (\n              <>\n                <DropListItem\n                  key=\"aiagent\"\n                  value=\"aiagent\"\n                  title={\n                    <div css={createDropListItemContainerStyle}>\n                      <span css={prefixIconContainerStyle}>\n                        {getIconFromResourceType(\"aiagent\", \"16px\")}\n                      </span>\n                      {t(\"editor.action.panel.label.option.general.ai-agent\")}\n                    </div>\n                  }\n                  onClick={handleClickActionType(\"aiagent\")}\n                />\n                <DropListItem\n                  key=\"illaDrive\"\n                  value=\"illaDrive\"\n                  title={\n                    <div css={dropListWithUpgradeIconStyle}>\n                      <div css={createDropListItemContainerStyle}>\n                        <span css={prefixIconContainerStyle}>\n                          {getIconFromResourceType(\"illadrive\", \"16px\")}\n                        </span>\n                        ILLA Drive\n                      </div>\n                      {!isSubscribeForUseDrive(teamInfo) && (\n                        <div css={upgradeContainerStyle}>\n                          <UpgradeIcon />\n                          <span>{t(\"Upgrade\")}</span>\n                        </div>\n                      )}\n                    </div>\n                  }\n                  onClick={handleClickActionType(\"illadrive\")}\n                />\n              </>\n            )}\n          </DropList>\n        }\n      >\n        <Button\n          colorScheme=\"techPurple\"\n          variant=\"light\"\n          ml=\"16px\"\n          mr=\"16px\"\n          mb=\"8px\"\n          _css={addNewActionButtonStyle}\n        >\n          <Space size=\"4px\" direction=\"horizontal\" alignItems=\"center\">\n            <AddIcon size=\"14px\" />\n            {t(\"editor.action.action_list.btn.new\")}\n          </Space>\n        </Button>\n      </Dropdown>\n      <div css={listContainerStyle}>\n        {searchList.length != 0 && (\n          <List\n            _css={listStyle}\n            bordered={false}\n            split={false}\n            data={searchList}\n            render={(data) => {\n              return (\n                <ActionListItem\n                  action={data}\n                  onCopyItem={onCopyActionItem}\n                  onDeleteItem={(action) => {\n                    if (action.actionType === \"globalData\") {\n                      shortcut.showDeleteDialog(\n                        [action.displayName],\n                        \"globalData\",\n                      )\n                    } else {\n                      shortcut.showDeleteDialog([action.displayName], \"action\")\n                    }\n                  }}\n                  onItemClick={(action) => {\n                    if (selectedAction === null) {\n                      dispatch(configActions.changeSelectedAction(action))\n                      return\n                    }\n                    // is a change action\n                    if (selectedAction?.displayName !== action.displayName) {\n                      if (isEqual(cachedAction, selectedAction)) {\n                        dispatch(configActions.changeSelectedAction(action))\n                      } else {\n                        // show dialog\n                        modal.show({\n                          children: t(\n                            \"editor.action.action_list.message.confirm_switch\",\n                          ),\n                          onOk: () => {\n                            dispatch(configActions.changeSelectedAction(action))\n                          },\n                          okButtonProps: {\n                            colorScheme: \"red\",\n                          },\n                        })\n                      }\n                    }\n                  }}\n                />\n              )\n            }}\n            renderRaw\n            renderKey={(data) => {\n              return data.displayName\n            }}\n          />\n        )}\n        {searchList.length == 0 && searchActionValue !== \"\" && (\n          <Empty\n            paddingVertical=\"23px\"\n            divideSize=\"4px\"\n            icon={<ActionListEmptyState />}\n            description={t(\"editor.action.action_list.tips.not_found\")}\n          />\n        )}\n        {searchList.length == 0 && searchActionValue == \"\" && (\n          <div css={actionListEmptyStyle}>\n            {t(\"editor.action.action_list.tips.empty\")}\n          </div>\n        )}\n        {generatorVisible && (\n          <MixpanelTrackProvider\n            basicTrack={track}\n            pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR}\n          >\n            <ResourceGeneratorProvider\n              allResource={resourceList}\n              createOrUpdateResourceCallback={handleFinishCreateNewResource}\n            >\n              <ActionGenerator\n                visible={generatorVisible}\n                onClose={() => setGeneratorVisible(false)}\n                defaultStep={currentActionType ? \"createAction\" : \"select\"}\n                defaultActionType={currentActionType}\n                canBackToSelect={!currentActionType}\n                handleDirectCreateAction={handleDirectCreateAction}\n                handleCreateAgentAction={handleCreateAgentAction}\n              />\n            </ResourceGeneratorProvider>\n          </MixpanelTrackProvider>\n        )}\n      </div>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionList/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const searchHeaderContainerStyle = css`\n  width: 255px;\n  min-width: 255px;\n  display: flex;\n  flex-direction: column;\n  border-right: 1px solid ${getColor(\"grayBlue\", \"08\")};\n`\n\nexport const addNewActionButtonStyle = css`\n  flex-shrink: 1;\n`\n\nexport const listContainerStyle = css`\n  flex-grow: 1;\n  width: 100%;\n  height: 0;\n  flex-shrink: 0;\n  overflow-y: auto;\n`\n\nexport const listStyle = css`\n  width: 100%;\n`\n\nexport const actionListEmptyStyle = css`\n  margin: 8px 16px;\n  padding: 8px 12px;\n  font-size: 12px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  border-radius: 4px;\n  border: dashed 1px ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n`\n\nexport const createDropListItemContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const prefixIconContainerStyle = css`\n  font-size: 16px;\n  width: 16px;\n  height: 16px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n\nexport const dropListWithUpgradeIconStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n`\n\nexport const upgradeContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  color: ${getColor(\"techPurple\", \"03\")};\n  font-size: 12px;\n  font-style: normal;\n  line-height: 20px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionListItem/index.tsx",
    "content": "import { getIconFromResourceType } from \"@illa-public/icon\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { Agent, GlobalDataActionContent } from \"@illa-public/public-types\"\nimport { isEqual } from \"lodash-es\"\nimport {\n  Suspense,\n  forwardRef,\n  useCallback,\n  useEffect,\n  useMemo,\n  useState,\n} from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  DropList,\n  DropListItem,\n  Dropdown,\n  Input,\n  LoadingIcon,\n  WarningCircleIcon,\n  getColor,\n  useMessage,\n} from \"@illa-design/react\"\nimport { ActionListItemProps } from \"@/page/App/components/Actions/ActionListItem/interface\"\nimport { getAgentIcon } from \"@/page/App/components/Actions/getIcon\"\nimport {\n  getCachedAction,\n  getIsILLAGuideMode,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { fetchUpdateAction } from \"@/services/action\"\nimport { RootState } from \"@/store\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { isObject, isValidDisplayName } from \"@/utils/typeHelper\"\nimport {\n  actionIconContainer,\n  actionItemDotStyle,\n  actionItemLeftStyle,\n  applyActionItemContainerStyle,\n  applyActionItemTitleStyle,\n  runningTimeStyle,\n  warningCircleStyle,\n} from \"./style\"\n\nconst Item = DropListItem\n\nexport const ActionListItem = forwardRef<HTMLDivElement, ActionListItemProps>(\n  (props, ref) => {\n    const { action, onItemClick, onCopyItem, onDeleteItem } = props\n\n    const { t } = useTranslation()\n    const selectedAction = useSelector(getSelectedAction)!!\n    const cachedAction = useSelector(getCachedAction)\n    const message = useMessage()\n\n    const error = useSelector((state: RootState) => {\n      const targetActionErrors =\n        state.currentApp.execution.error[action.displayName]\n      if (isObject(targetActionErrors)) {\n        return Object.keys(targetActionErrors).length > 0\n      }\n      return false\n    })\n\n    const isGuideMode = useSelector(getIsILLAGuideMode)\n    const executionResult = useSelector(getExecutionResult)\n\n    const startRunningTime: number =\n      executionResult[action.displayName]?.startTime\n\n    const endRunningTime: number = executionResult[action.displayName]?.endTime\n\n    const isRunning: boolean = executionResult[action.displayName]?.isRunning\n\n    const isMocking: boolean =\n      executionResult[action.displayName]?.config?.mockConfig?.enabled\n\n    const [currentRunningTime, setCurrentRunningTime] = useState(0)\n\n    const dealData = useCallback(() => {\n      return window.setInterval(() => {\n        const currentTime = new Date().getTime() - startRunningTime\n        setCurrentRunningTime(currentTime)\n      }, 10)\n    }, [startRunningTime])\n\n    useEffect((): any => {\n      let time = -1\n      if (isRunning) {\n        time = dealData()\n      }\n      return () => {\n        if (time !== -1) {\n          window.clearInterval(time)\n        }\n      }\n    }, [isRunning, dealData])\n\n    const isChanged = useMemo(() => {\n      return (\n        selectedAction?.actionID === action.actionID &&\n        !isEqual(selectedAction, cachedAction)\n      )\n    }, [action.actionID, cachedAction, selectedAction])\n\n    const [editName, setEditName] = useState(false)\n    const [changing, setChanging] = useState(false)\n    const dispatch = useDispatch()\n\n    const changeDisplayName = useCallback(\n      async (newName: string) => {\n        if (newName === action.displayName) {\n          setEditName(false)\n          return\n        }\n        if (!isValidDisplayName(newName)) {\n          message.error({\n            content: t(\"editor.display_name.validate_error\", {\n              displayName: newName,\n            }),\n          })\n          setEditName(false)\n          return\n        }\n        if (DisplayNameGenerator.isAlreadyGenerate(newName)) {\n          message.error({\n            content: t(\"editor.display_name.duplicate_error\", {\n              displayName: newName,\n            }),\n          })\n          setEditName(false)\n          return\n        }\n        const newAction = {\n          ...action,\n          displayName: newName,\n        }\n\n        if (action.actionType === \"globalData\") {\n          DisplayNameGenerator.addDisplayNames([newName])\n          DisplayNameGenerator.removeDisplayName(action.displayName)\n          dispatch(\n            componentsActions.setGlobalStateReducer({\n              key: newName,\n              value: (action.content as GlobalDataActionContent).initialValue,\n              oldKey: action.displayName,\n            }),\n          )\n          setEditName(false)\n          return\n        }\n\n        if (isGuideMode) {\n          dispatch(\n            actionActions.updateActionDisplayNameReducer({\n              newDisplayName: newName,\n              oldDisplayName: action.displayName,\n              actionID: newAction.actionID,\n            }),\n          )\n          setEditName(false)\n          return\n        }\n        setChanging(true)\n        try {\n          await fetchUpdateAction(newAction)\n          dispatch(\n            actionActions.updateActionDisplayNameReducer({\n              newDisplayName: newName,\n              oldDisplayName: action.displayName,\n              actionID: newAction.actionID,\n            }),\n          )\n          setEditName(false)\n        } catch (_e) {\n          message.error({\n            content: t(\"change_fail\"),\n          })\n          setEditName(false)\n        }\n\n        setChanging(false)\n      },\n      [action, isGuideMode, dispatch, message, t],\n    )\n\n    const calcTimeString = useCallback(\n      (startTime?: number, endTime?: number) => {\n        if (startTime && endTime) {\n          const time = endTime - startTime\n          if (time > 1000) {\n            return `${(time / 1000).toFixed(2)}s`\n          }\n          return `${time}ms`\n        } else {\n          return \"\"\n        }\n      },\n      [],\n    )\n\n    const calcLoadingTimeString = useCallback((currentRunningTime: number) => {\n      return currentRunningTime > 1000\n        ? `${(currentRunningTime / 1000).toFixed(2)}s`\n        : `${currentRunningTime}ms`\n    }, [])\n\n    return (\n      <Dropdown\n        trigger=\"contextmenu\"\n        position=\"right-start\"\n        dropList={\n          <DropList w=\"184px\">\n            <Item\n              key={\"rename\"}\n              value={\"rename\"}\n              title={t(\"editor.action.action_list.contextMenu.rename\")}\n              onClick={() => {\n                trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.RENAME, {\n                  element: \"action_rename\",\n                  parameter1: action.actionType,\n                  parameter2: \"manage\",\n                })\n                setEditName(true)\n              }}\n            />\n            <Item\n              key={\"duplicate\"}\n              value={\"duplicate\"}\n              title={t(\"editor.action.action_list.contextMenu.duplicate\")}\n              onClick={() => {\n                trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.DUPLICATE, {\n                  element: \"action_duplicate\",\n                  parameter1: action.actionType,\n                })\n                onCopyItem(action)\n              }}\n            />\n            <Item\n              key={\"delete\"}\n              value={\"delete\"}\n              title={t(\"editor.action.action_list.contextMenu.delete\")}\n              deleted\n              onClick={() => {\n                trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.DELETE, {\n                  element: \"action_delete\",\n                  parameter1: action.actionType,\n                })\n                onDeleteItem(action)\n              }}\n            />\n          </DropList>\n        }\n      >\n        <div\n          css={applyActionItemContainerStyle(\n            selectedAction?.displayName === action.displayName,\n          )}\n          ref={ref}\n          onClick={() => {\n            onItemClick(action)\n          }}\n          onDoubleClick={() => {\n            onItemClick(action)\n            setEditName(true)\n          }}\n        >\n          <div css={actionItemLeftStyle}>\n            <div css={actionIconContainer}>\n              <Suspense>\n                {action.actionType === \"aiagent\" &&\n                \"virtualResource\" in action.content\n                  ? getAgentIcon(\n                      action.content.virtualResource as Agent,\n                      \"16px\",\n                    )\n                  : getIconFromResourceType(action.actionType, \"16px\")}\n              </Suspense>\n              {error && <WarningCircleIcon css={warningCircleStyle} />}\n            </div>\n            {!editName ? (\n              <div css={applyActionItemTitleStyle(error)}>\n                {action.displayName}\n              </div>\n            ) : (\n              <Input\n                ml=\"8px\"\n                colorScheme=\"techPurple\"\n                size=\"small\"\n                onPressEnter={(e) => {\n                  changeDisplayName(e.currentTarget.value)\n                }}\n                defaultValue={action.displayName}\n                autoFocus\n                disabled={changing}\n                suffix={\n                  changing && (\n                    <LoadingIcon c={getColor(\"grayBlue\", \"05\")} spin={true} />\n                  )\n                }\n                onBlur={(event) => {\n                  changeDisplayName(event.target.value)\n                }}\n              />\n            )}\n            {isChanged && <div css={actionItemDotStyle} />}\n          </div>\n          <div css={runningTimeStyle}>\n            {isMocking\n              ? t(\"editor.action.panel.option.mock.label\")\n              : isRunning\n                ? calcLoadingTimeString(currentRunningTime)\n                : calcTimeString(startRunningTime, endRunningTime)}\n          </div>\n        </div>\n      </Dropdown>\n    )\n  },\n)\n\nActionListItem.displayName = \"ActionListItem\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionListItem/interface.ts",
    "content": "import { ActionContent } from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { HTMLAttributes } from \"react\"\n\nexport interface ActionListItemProps extends HTMLAttributes<HTMLDivElement> {\n  action: ActionItem<ActionContent>\n  onItemClick: (action: ActionItem<ActionContent>) => void\n  onCopyItem: (action: ActionItem<ActionContent>) => void\n  onDeleteItem: (action: ActionItem<ActionContent>) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionListItem/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const actionIconContainer = css`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  position: relative;\n  flex-shrink: 0;\n  width: 16px;\n  height: 16px;\n`\n\nexport const actionItemDotStyle = css`\n  flex-shrink: 0;\n  width: 8px;\n  margin-left: 9px;\n  height: 8px;\n  margin-right: 9px;\n  box-sizing: border-box;\n  border-radius: 50%;\n  background: ${globalColor(`--${illaPrefix}-blue-03`)};\n`\n\nexport function applyActionItemTitleStyle(error: boolean): SerializedStyles {\n  return css`\n    flex-shrink: 1;\n    font-weight: 500;\n    margin-left: 8px;\n    overflow: hidden;\n    color: ${error\n      ? globalColor(`--${illaPrefix}-red-03`)\n      : globalColor(`--${illaPrefix}-grayBlue-02`)};\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  `\n}\n\nexport const timeStyle = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const warningCircleStyle = css`\n  position: absolute;\n  color: ${globalColor(`--${illaPrefix}-red-03`)};\n  font-size: 8px;\n  bottom: 0;\n  right: 0;\n`\n\nexport function applyActionItemContainerStyle(\n  selected: boolean,\n): SerializedStyles {\n  return css`\n    background: ${selected\n      ? globalColor(`--${illaPrefix}-techPurple-08`)\n      : \"transparent\"};\n    width: 100%;\n    align-items: center;\n    display: flex;\n    flex-direction: row;\n    padding-left: 16px;\n    padding-right: 16px;\n    height: 40px;\n    font-size: 14px;\n\n    &:hover {\n      background: ${selected\n        ? globalColor(`--${illaPrefix}-techPurple-08`)\n        : globalColor(`--${illaPrefix}-grayBlue-09`)};\n    }\n  `\n}\n\nexport const actionItemLeftStyle = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  display: flex;\n  overflow: hidden;\n  flex-direction: row;\n  align-items: center;\n  flex-grow: 1;\n`\n\nexport const runningTimeStyle = css`\n  font-size: 12px;\n  font-weight: 400;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AIAgentPanel/index.tsx",
    "content": "import { getLLM } from \"@illa-public/market-agent\"\nimport { AiAgentActionContent, Params } from \"@illa-public/public-types\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Input } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { RecordEditor } from \"@/components/RecordEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport HorizontalWithLabel from \"../Layout/HorizontalWithLabel\"\nimport { TransformerComponent } from \"../TransformerComponent\"\n\nconst AIAgentPanel: FC = () => {\n  const currentAction = useSelector(getCachedAction)!\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n\n  const aiAgentContent = currentAction.content as AiAgentActionContent\n\n  const handleChangeInput = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...currentAction,\n          content: {\n            ...aiAgentContent,\n            input: value,\n          },\n        }),\n      )\n    },\n    [currentAction, dispatch, aiAgentContent],\n  )\n\n  const handleChangeVariableValue = useCallback(\n    (index: number, key: string, value: string) => {\n      let newList: Params[] = [...aiAgentContent.variables]\n      newList[index] = { key, value }\n      dispatch(\n        configActions.updateCachedAction({\n          ...currentAction,\n          content: {\n            ...aiAgentContent,\n            variables: newList,\n          },\n        }),\n      )\n    },\n    [aiAgentContent, currentAction, dispatch],\n  )\n\n  const variables = useMemo(() => {\n    const resourcesKeys = (aiAgentContent.virtualResource?.variables ?? []).map(\n      (item) => item.key,\n    )\n\n    let resourcesKeyValues: Record<string, string> = {}\n    if ((aiAgentContent.virtualResource?.variables ?? []).length > 0) {\n      ;(aiAgentContent.virtualResource?.variables ?? []).forEach((item) => {\n        if (!item) return\n        resourcesKeyValues[item.key] = item.value\n      })\n    }\n\n    let currentActionKeyValues: Record<string, string> = {}\n\n    if (aiAgentContent.variables.length > 0) {\n      aiAgentContent.variables.forEach((item) => {\n        if (!item) return\n        currentActionKeyValues[item.key] = item.value\n      })\n    }\n\n    const variable = resourcesKeys.map((item) => {\n      return {\n        key: item,\n        value: currentActionKeyValues[item] || resourcesKeyValues[item] || \"\",\n      }\n    })\n    return variable\n  }, [aiAgentContent.variables, aiAgentContent.virtualResource?.variables])\n\n  return (\n    <div>\n      {aiAgentContent.virtualResource && (\n        <HorizontalWithLabel labelName={t(\"editor.ai-agent.label.model\")}>\n          <Input\n            prefix={getLLM(aiAgentContent.virtualResource.model)?.logo}\n            colorScheme=\"techPurple\"\n            readOnly\n            value={getLLM(aiAgentContent.virtualResource.model)?.name}\n          />\n        </HorizontalWithLabel>\n      )}\n      {variables.length > 0 && (\n        <RecordEditor\n          fillOnly\n          records={variables}\n          onChangeValue={handleChangeVariableValue}\n          label={t(\"editor.ai-agent.label.variable\")}\n        />\n      )}\n      <HorizontalWithLabel\n        labelName={t(\"editor.action.panel.label.ai-agent.input\")}\n      >\n        <CodeEditor\n          lang={CODE_LANG.JAVASCRIPT}\n          expectValueType={VALIDATION_TYPES.STRING}\n          modalTitle={t(\"editor.action.panel.label.ai-agent.input\")}\n          value={aiAgentContent.input}\n          onChange={handleChangeInput}\n        />\n      </HorizontalWithLabel>\n      <TransformerComponent />\n    </div>\n  )\n}\n\nAIAgentPanel.displayName = \"AIAgentPanel\"\n\nexport default AIAgentPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionEventHandler/index.tsx",
    "content": "import { ActionContent } from \"@illa-public/public-types\"\nimport { klona } from \"klona/json\"\nimport { FC, Suspense, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { TriggerProvider } from \"@illa-design/react\"\nimport {\n  actionEventHandlerStyle,\n  actionEventHandlerWrapperStyle,\n} from \"@/page/App/components/Actions/ActionPanel/ActionEventHandler/style\"\nimport RenderPanelSetter from \"@/page/App/components/InspectPanel/components/PanelSetter\"\nimport { SelectedProvider } from \"@/page/App/components/InspectPanel/context/selectedContext\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getNewWidgetPropsByUpdateSlice } from \"@/utils/componentNode\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport {\n  actionFailedEventHandlerConfig,\n  actionSuccessEventHandlerConfig,\n} from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nexport const ActionEventHandler: FC = () => {\n  const { t } = useTranslation()\n  const action = useSelector(getCachedAction)\n  const dispatch = useDispatch()\n\n  const handleUpdateDsl = useCallback(\n    (attrPath: string, value: any) => {\n      if (action != undefined) {\n        const newActionContent = klona(action.content || {})\n\n        const updateSlice: Record<string, unknown> = { [attrPath]: value }\n\n        const result = getNewWidgetPropsByUpdateSlice(\n          updateSlice,\n          newActionContent as unknown as Record<string, unknown>,\n        ) as unknown as ActionContent\n        dispatch(\n          configActions.updateCachedAction({\n            ...action,\n            content: result,\n          }),\n        )\n      }\n    },\n    [action, dispatch],\n  )\n\n  const handleUpdateMultiAttrDSL = useCallback(\n    (updateSlice: Record<string, unknown>) => {\n      if (!isObject(updateSlice) || action == undefined) return\n      const newActionContent = klona(action.content || {})\n      const result = getNewWidgetPropsByUpdateSlice(\n        updateSlice,\n        newActionContent as unknown as Record<string, unknown>,\n      ) as unknown as ActionContent\n      dispatch(\n        configActions.updateCachedAction({\n          ...action,\n          content: result,\n        }),\n      )\n    },\n    [action, dispatch],\n  )\n\n  // keep empty\n  const handleUpdateOtherMultiAttrDSL = useCallback(\n    (_displayName: string, _updateSlice: Record<string, unknown>) => {\n      return\n    },\n    [],\n  )\n\n  return (\n    <Suspense>\n      <TriggerProvider renderInBody zIndex={10}>\n        <div css={actionEventHandlerWrapperStyle}>\n          <div css={actionEventHandlerStyle}>\n            {t(\"editor.action.panel.label.event_handler\")}\n          </div>\n          {action && (\n            <SelectedProvider\n              widgetType={action.actionType}\n              widgetDisplayName={action.displayName}\n              widgetParentDisplayName=\"\"\n              widgetProps={action.content || {}}\n              handleUpdateDsl={handleUpdateDsl}\n              handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n              handleUpdateOtherMultiAttrDSL={handleUpdateOtherMultiAttrDSL}\n              widgetOrAction=\"ACTION\"\n            >\n              <RenderPanelSetter\n                config={actionSuccessEventHandlerConfig}\n                displayName={action.displayName}\n                parentAttrName=\"\"\n              />\n              <RenderPanelSetter\n                config={actionFailedEventHandlerConfig}\n                displayName={action.displayName}\n                parentAttrName=\"\"\n              />\n            </SelectedProvider>\n          )}\n        </div>\n      </TriggerProvider>\n    </Suspense>\n  )\n}\n\nActionEventHandler.displayName = \"ActionEventHandler\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionEventHandler/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const actionEventHandlerStyle = css`\n  border-top: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  height: 39px;\n  padding-top: 16px;\n  padding-left: 16px;\n  font-size: 14px;\n  font-weight: 500;\n  text-align: left;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const actionEventHandlerWrapperStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionMockPanel/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch } from \"react-redux\"\nimport { Checkbox, Space } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { TransformerComponent } from \"../TransformerComponent\"\nimport { ActionMockPanelProps } from \"./interface\"\nimport {\n  mockDataContainerStyle,\n  mockDataTitleStyle,\n  mockPanelContainerStyle,\n} from \"./style\"\n\nconst ActionMockPanel: FC<ActionMockPanelProps> = (props) => {\n  const { mockData, enableForReleasedApp } = props\n\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n\n  const handleOnChangeMockData = (value: string) => {\n    dispatch(\n      configActions.updateCachedActionMockConfigReducer({\n        mockData: value,\n      }),\n    )\n  }\n\n  const handleOnChangeEnableForReleasedApp = (checked: boolean) => {\n    dispatch(\n      configActions.updateCachedActionMockConfigReducer({\n        enableForReleasedApp: checked,\n      }),\n    )\n  }\n\n  return (\n    <>\n      <div css={mockPanelContainerStyle}>\n        <div css={mockDataContainerStyle}>\n          <span css={mockDataTitleStyle}>\n            {t(\"editor.action.panel.option.mock.json\")}\n          </span>\n          <CodeEditor\n            value={mockData}\n            showLineNumbers\n            canShowCompleteInfo\n            height=\"88px\"\n            lang={CODE_LANG.JAVASCRIPT}\n            codeType={CODE_TYPE.NO_METHOD_FUNCTION}\n            onChange={handleOnChangeMockData}\n          />\n        </div>\n        <Checkbox\n          checked={enableForReleasedApp}\n          colorScheme=\"techPurple\"\n          onChange={handleOnChangeEnableForReleasedApp}\n        >\n          {t(\"editor.action.panel.option.mock.on_deploy\")}\n        </Checkbox>\n      </div>\n      <TransformerComponent fullWidth />\n      <Space w=\"100%\" h=\"8px\" disp=\"block\" />\n    </>\n  )\n}\n\nexport default memo(ActionMockPanel)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionMockPanel/interface.ts",
    "content": "export interface ActionMockPanelProps {\n  mockData: string\n  enableForReleasedApp: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionMockPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const mockDataContainerStyle = css`\n  display: flex;\n  padding: 8px 0;\n  flex-direction: column;\n  gap: 10px;\n`\n\nexport const mockDataTitleStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n`\n\nexport const mockPanelContainerStyle = css`\n  padding: 8px 16px;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionResult/index.tsx",
    "content": "import { FC, useCallback, useRef, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { ActionResultProps } from \"@/page/App/components/Actions/ActionPanel/ActionResult/interface\"\nimport {\n  actionResultContainerStyle,\n  applyActionContentContainerStyle,\n  customerCodeStyle,\n} from \"@/page/App/components/Actions/ActionPanel/ActionResult/style\"\nimport { DragBar } from \"@/page/App/components/Actions/DragBar\"\nimport { getSelectedAction } from \"@/redux/config/configSelector\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { AdvancedResultHeader, RESULT_SHOW_TYPE } from \"./restApiHeader\"\nimport { getDisplayResult } from \"./utils\"\n\nexport const ActionResult: FC<ActionResultProps> = (props) => {\n  const { onClose, visible } = props\n\n  const resizeRef = useRef<HTMLDivElement>(null)\n\n  const alertRef = useRef<HTMLDivElement>(null)\n\n  const [showType, setShowType] = useState<RESULT_SHOW_TYPE>(\n    RESULT_SHOW_TYPE.RESPONSE,\n  )\n\n  const selectedAction = useSelector(getSelectedAction)! ?? {}\n\n  const currentActionExecutionResult = useSelector<\n    RootState,\n    Record<string, any> | undefined\n  >((rootState) => {\n    const executionResult = getExecutionResult(rootState)\n    if (selectedAction.displayName) {\n      return executionResult[selectedAction.displayName]\n    }\n  })\n\n  const { t } = useTranslation()\n\n  const renderResult =\n    visible &&\n    (currentActionExecutionResult?.data !== undefined ||\n      currentActionExecutionResult?.runResult !== undefined)\n\n  const isError = currentActionExecutionResult?.runResult?.error\n  const result = currentActionExecutionResult?.data\n  const rawResult = currentActionExecutionResult?.rawData\n  const responseHeader = currentActionExecutionResult?.responseHeaders\n\n  const runningTimes =\n    (currentActionExecutionResult?.endTime ?? 0) -\n    (currentActionExecutionResult?.startTime ?? 0)\n\n  const [codeMirrorHeight, setCodeMirrorHeight] = useState(260)\n\n  const handleResultTabsClick = useCallback((activeKey: RESULT_SHOW_TYPE) => {\n    return () => {\n      setShowType(activeKey)\n    }\n  }, [])\n\n  const finalResult = {\n    result,\n    rawResult,\n    responseHeader,\n  }\n\n  const advancedApiResultTabs = [\n    {\n      title: t(\"editor.action.panel.result.restapi.response\"),\n      name: RESULT_SHOW_TYPE.RESPONSE,\n      shown: !!result,\n    },\n    {\n      title: t(\"editor.action.panel.result.restapi.rawdata\"),\n      name: RESULT_SHOW_TYPE.RAW_DATA,\n      shown: !!rawResult,\n    },\n    {\n      title: t(\"editor.action.panel.result.restapi.headers\"),\n      name: RESULT_SHOW_TYPE.HEADERS,\n      shown: !!responseHeader,\n    },\n  ]\n\n  const displayData = getDisplayResult(showType, finalResult)\n\n  return (\n    <div css={actionResultContainerStyle}>\n      <div css={applyActionContentContainerStyle(renderResult)} ref={resizeRef}>\n        <DragBar\n          minHeight={300}\n          resizeRef={resizeRef}\n          onChange={() => {\n            setCodeMirrorHeight(\n              resizeRef.current!.offsetHeight - alertRef.current!.offsetHeight,\n            )\n          }}\n        />\n\n        <AdvancedResultHeader\n          showType={showType}\n          runningTimes={runningTimes}\n          onClose={onClose}\n          handleResultTabsClick={handleResultTabsClick}\n          ref={alertRef}\n          statusCode={responseHeader?.statusCode}\n          statusText={responseHeader?.statusText}\n          tabsConfig={advancedApiResultTabs}\n          isError={isError}\n        />\n\n        <CodeEditor\n          height={codeMirrorHeight + \"px\"}\n          wrapperCss={customerCodeStyle}\n          showLineNumbers\n          editable={false}\n          value={\n            isError\n              ? currentActionExecutionResult?.runResult?.message\n              : JSON.stringify(displayData, undefined, 2)\n          }\n          lang={CODE_LANG.JSON}\n        />\n      </div>\n    </div>\n  )\n}\n\nActionResult.displayName = \"ActionResult\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionResult/interface.ts",
    "content": "export interface ActionResultProps {\n  visible: boolean\n  onClose: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionResult/restApiHeader.tsx",
    "content": "import { MouseEventHandler, forwardRef } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  CloseIcon,\n  SuccessCircleIcon,\n  WarningCircleIcon,\n  getColor,\n} from \"@illa-design/react\"\nimport {\n  alertInfoContainerStyle,\n  alertInfoStyle,\n  alertTabsContainerStyle,\n  alertTabsItemStyle,\n  alertTextStyle,\n  applyStatusCodeStyle,\n  getActiveStyle,\n  restApiAlertBarStyle,\n  tabsContentStyle,\n  timestampStyle,\n} from \"@/page/App/components/Actions/ActionPanel/ActionResult/style\"\n\nexport enum RESULT_SHOW_TYPE {\n  \"RESPONSE\" = \"response\",\n  \"HEADERS\" = \"headers\",\n  \"RAW_DATA\" = \"rawData\",\n}\n\ninterface TabsConfig {\n  title: string\n  name: RESULT_SHOW_TYPE\n  shown: boolean\n}\n\ninterface AdvancedResultHeaderProps {\n  showType: RESULT_SHOW_TYPE\n  handleResultTabsClick: (\n    activeType: RESULT_SHOW_TYPE,\n  ) => MouseEventHandler<HTMLDivElement>\n  statusCode?: number\n  statusText?: string\n  runningTimes: number\n  onClose: MouseEventHandler<SVGElement>\n  tabsConfig: TabsConfig[]\n  isError: boolean\n}\n\nexport const AdvancedResultHeader = forwardRef<\n  HTMLDivElement,\n  AdvancedResultHeaderProps\n>((props, ref) => {\n  const {\n    handleResultTabsClick,\n    showType,\n    statusCode,\n    runningTimes,\n    tabsConfig,\n    onClose,\n    isError,\n  } = props\n\n  const canShownTabs = tabsConfig.filter((info) => info.shown)\n\n  const { t } = useTranslation()\n  return (\n    <div ref={ref} css={restApiAlertBarStyle}>\n      {canShownTabs.length > 1 ? (\n        <>\n          <div css={alertTabsContainerStyle}>\n            {canShownTabs.map((info) => (\n              <div\n                key={info.name}\n                css={[\n                  alertTabsItemStyle,\n                  getActiveStyle(showType === info.name),\n                ]}\n                data-key={info.name}\n                onClick={handleResultTabsClick(info.name)}\n              >\n                <div css={tabsContentStyle}>{info.title}</div>\n              </div>\n            ))}\n          </div>\n          <div css={alertInfoContainerStyle}>\n            {statusCode && (\n              <div css={alertInfoStyle}>\n                {t(\"editor.action.panel.result.restapi.status\")}\n                <span css={applyStatusCodeStyle(statusCode)}>{statusCode}</span>\n              </div>\n            )}\n            <div css={alertInfoStyle}>\n              Times\n              <span css={timestampStyle}>{`${runningTimes}ms`}</span>\n            </div>\n          </div>\n        </>\n      ) : (\n        <>\n          {isError ? (\n            <WarningCircleIcon c={getColor(\"red\", \"03\")} />\n          ) : (\n            <SuccessCircleIcon c={getColor(\"green\", \"03\")} />\n          )}\n          <span css={alertTextStyle}>\n            {isError\n              ? t(\"editor.action.panel.status.ran_failed\")\n              : t(\"editor.action.panel.status.ran_successfully\")}\n          </span>\n        </>\n      )}\n      <CloseIcon\n        cur=\"pointer\"\n        c={getColor(\"grayBlue\", \"05\")}\n        onClick={onClose}\n      />\n    </div>\n  )\n})\n\nAdvancedResultHeader.displayName = \"RestAPIHeader\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionResult/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const actionResultContainerStyle = css`\n  padding-top: 120px;\n  position: absolute;\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  pointer-events: none;\n  justify-content: end;\n  height: 100%;\n`\n\nexport function applyActionContentContainerStyle(\n  renderResult: boolean,\n): SerializedStyles {\n  return css`\n    visibility: ${renderResult ? \"visible\" : \"hidden\"};\n    position: relative;\n    pointer-events: auto;\n    z-index: 10;\n  `\n}\n\nexport const alertBarStyle = css`\n  width: 100%;\n  background: ${getColor(\"grayBlue\", \"09\")};\n  height: 40px;\n  display: flex;\n  flex-direction: row;\n  padding: 0 16px;\n  align-items: center;\n`\n\nexport const restApiAlertBarStyle = css`\n  width: 100%;\n  background: ${getColor(\"grayBlue\", \"09\")};\n  height: 48px;\n  padding: 8px 16px;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  position: relative;\n`\n\nexport const alertTabsContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: flex-start;\n  gap: 8px;\n  height: 32px;\n`\n\nexport const alertTabsItemStyle = css`\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  padding: 0 8px;\n  gap: 10px;\n  cursor: pointer;\n  width: 82px;\n  height: 32px;\n  font-size: 14px;\n`\n\nexport const tabsContentStyle = css`\n  line-height: 22px;\n`\n\nexport const getActiveStyle = (active: boolean): SerializedStyles => {\n  if (active) {\n    return css`\n      box-shadow: inset 0px -2px 0px ${getColor(\"grayBlue\", \"02\")};\n    `\n  }\n  return css``\n}\n\nexport const alertInfoContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  padding: 0;\n  gap: 24px;\n  height: 24px;\n  position: absolute;\n  right: 40px;\n`\n\nexport const alertInfoStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  gap: 4px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 14px;\n  line-height: 22px;\n`\n\nexport const applyStatusCodeStyle = (statusCode: number) => css`\n  font-weight: 500;\n  font-size: 14px;\n\n  color: ${statusCode >= 400 ? getColor(\"red\", \"03\") : getColor(\"green\", \"03\")};\n`\n\nexport const timestampStyle = css`\n  font-weight: 500;\n  font-size: 14px;\n\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const alertTextStyle = css`\n  font-weight: 500;\n  flex-grow: 1;\n  font-size: 14px;\n  margin-left: 8px;\n`\n\nexport const customerCodeStyle = css`\n  border: none;\n  border-radius: 0;\n  background-color: ${getColor(\"white\", \"01\")};\n\n  .cm-editor.ͼ1 {\n    border: none;\n    border-radius: 0;\n\n    & > .cm-scroller > .cm-gutters {\n      border-radius: 0;\n    }\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionResult/utils.ts",
    "content": "import { RESULT_SHOW_TYPE } from \"./restApiHeader\"\n\nexport interface IShowResult {\n  result?: unknown\n  rawResult?: unknown\n  responseHeader?: unknown\n}\n\nexport const getDisplayResult = (\n  showType: RESULT_SHOW_TYPE,\n  result: IShowResult,\n) => {\n  switch (showType) {\n    case RESULT_SHOW_TYPE.HEADERS: {\n      return result.responseHeader\n    }\n    case RESULT_SHOW_TYPE.RAW_DATA: {\n      return result.rawResult\n    }\n    case RESULT_SHOW_TYPE.RESPONSE:\n    default: {\n      return result.result\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionTitleBar/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport {\n  ElasticSearchBodyContentType,\n  ElasticSearchIDEditorType,\n  ElasticSearchQueryContentType,\n  getDocLink,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionContent,\n  ActionItem,\n  ElasticSearchAction,\n  GlobalDataActionContent,\n  SMPTAction,\n} from \"@illa-public/public-types\"\nimport { isEqual } from \"lodash-es\"\nimport {\n  FC,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useState,\n} from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Link } from \"react-router-dom\"\nimport {\n  Button,\n  DocsIcon,\n  DropList,\n  DropListItem,\n  Dropdown,\n  MoreIcon,\n  PlayFillIcon,\n  SuccessCircleIcon,\n  UpIcon,\n  WarningCircleIcon,\n  useMessage,\n} from \"@illa-design/react\"\nimport { EditableText } from \"@/components/EditableText\"\nimport { SimpleTabs } from \"@/components/Tabs\"\nimport { ACTION_PANEL_TABS } from \"@/components/Tabs/constant\"\nimport i18n from \"@/i18n/config\"\nimport { isFileOversize } from \"@/page/App/components/Actions/ActionPanel/utils/calculateFileSize\"\nimport { onCopyActionItem } from \"@/page/App/components/Actions/api\"\nimport {\n  getCachedAction,\n  getIsILLAGuideMode,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { fetchUpdateAction } from \"@/services/action\"\nimport { RootState } from \"@/store\"\nimport { runOriginAction } from \"@/utils/action/runAction\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ShortCutContext } from \"@/utils/shortcut/shortcutProvider\"\nimport { SQLModeTipContext } from \"../../Context/SqlModeTipContext\"\nimport { isSafeModeAction } from \"../utils/safeModeTip\"\nimport { ActionTitleBarProps } from \"./interface\"\nimport {\n  actionFailBlockStyle,\n  actionSuccessBlockStyle,\n  actionTextStyle,\n  actionTitleBarStyle,\n  applyOpenStateStyle,\n  editableTitleBarWrapperStyle,\n  runResultAndRunContainerStyle,\n  tabsContainerStyle,\n} from \"./style\"\n\nconst Item = DropListItem\nexport type RunMode = \"save\" | \"run\" | \"test_run\" | \"save_and_run\"\nconst FILE_SIZE_LIMIT_TYPE = [\"s3\", \"smtp\"]\n\nconst getCanRunAction = (cachedAction: ActionItem<ActionContent> | null) => {\n  if (\n    !cachedAction ||\n    !FILE_SIZE_LIMIT_TYPE.includes(cachedAction.actionType)\n  ) {\n    return [true, \"\"]\n  }\n  switch (cachedAction.actionType) {\n    case \"smtp\":\n      const smtpContent = cachedAction.content as SMPTAction\n      return [\n        !isFileOversize(smtpContent?.attachment || \"\", \"smtp\"),\n        i18n.t(\"editor.action.panel.error.max_file\"),\n      ]\n  }\n  return [true, \"\"]\n}\n\nconst getActionFilteredContent = (cachedAction: ActionItem<ActionContent>) => {\n  let cachedActionValue: ActionItem<ActionContent> | null = cachedAction\n  if (!cachedActionValue) {\n    return cachedActionValue\n  }\n  switch (cachedAction?.actionType) {\n    case \"elasticsearch\":\n      let content = cachedAction.content as ElasticSearchAction\n      if (!ElasticSearchIDEditorType.includes(content.operation)) {\n        const { id: _id = \"\", ...otherContent } = content\n        cachedActionValue = {\n          ...cachedAction,\n          content: { ...otherContent },\n        }\n        content = otherContent\n      }\n      if (!ElasticSearchBodyContentType.includes(content.operation)) {\n        const { body: _body = \"\", ...otherContent } = content\n        cachedActionValue = {\n          ...cachedActionValue,\n          content: { ...otherContent },\n        }\n        content = otherContent\n      }\n      if (!ElasticSearchQueryContentType.includes(content.operation)) {\n        const { query: _query = \"\", ...otherContent } = content\n        cachedActionValue = {\n          ...cachedActionValue,\n          content: { ...otherContent },\n        }\n      }\n      break\n    case \"smtp\":\n      const smtpContent = cachedAction.content as SMPTAction\n      const { to, cc, bcc, attachment, ...otherContent } = smtpContent\n      cachedActionValue = {\n        ...cachedAction,\n        content: {\n          ...otherContent,\n          // if to, cc, bcc or attachment is empty, remove it from the content\n          ...(to && { to }),\n          ...(cc && { cc }),\n          ...(bcc && { bcc }),\n          ...(attachment && { attachment }),\n        },\n      }\n      break\n  }\n  return cachedActionValue\n}\n\nexport const ActionTitleBar: FC<ActionTitleBarProps> = (props) => {\n  const { onResultVisibleChange, openState, activeTab, handleChangeTab } = props\n\n  const message = useMessage()\n  const [saveLoading, setSaveLoading] = useState(false)\n  const shortcut = useContext(ShortCutContext)\n  const { setShowSQLModeTip } = useContext(SQLModeTipContext)\n\n  const selectedAction = useSelector(getSelectedAction)! ?? {}\n  const cachedAction = useSelector(getCachedAction)!\n  const docLink = getDocLink(\"action\", cachedAction.actionType)\n  const selectedActionExecutionResult = useSelector<\n    RootState,\n    Record<string, any>\n  >((rootState) => {\n    const executionResult = getExecutionResult(rootState)\n    return executionResult[selectedAction.displayName] || {}\n  })\n  const isRunning = !!selectedActionExecutionResult.isRunning\n\n  const isChanged = !isEqual(selectedAction, cachedAction)\n\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n  const [canRunAction, canNotRunMessage] = getCanRunAction(cachedAction)\n\n  const executionResult = useSelector(getExecutionResult)\n  const isGuideOpen = useSelector(getIsILLAGuideMode)\n\n  const renderResult =\n    executionResult[selectedAction.displayName]?.data !== undefined ||\n    executionResult[selectedAction.displayName]?.runResult !== undefined\n\n  const runError = executionResult[selectedAction.displayName]?.runResult?.error\n\n  const getRunMode = () => {\n    if (isGuideOpen) {\n      if (isChanged) {\n        return \"save\"\n      }\n      return \"test_run\"\n    }\n    if (cachedAction != undefined && isChanged) {\n      if (cachedAction.triggerMode === \"manually\") {\n        return \"save\"\n      } else if (cachedAction.triggerMode === \"automate\") {\n        return \"save_and_run\"\n      } else {\n        return \"save\"\n      }\n    } else {\n      return \"run\"\n    }\n  }\n\n  const runMode = getRunMode()\n\n  const innerTabItems = useMemo(() => {\n    if (\n      selectedAction.actionType === \"transformer\" ||\n      selectedAction.actionType === \"globalData\"\n    ) {\n      return [ACTION_PANEL_TABS[0]]\n    }\n    return ACTION_PANEL_TABS\n  }, [selectedAction.actionType])\n\n  useEffect(() => {\n    if (\n      selectedAction.actionType === \"transformer\" ||\n      selectedAction.actionType === \"globalData\"\n    ) {\n      handleChangeTab(\"general\")\n    }\n  }, [handleChangeTab, selectedAction.actionType])\n\n  useEffect(() => {\n    switch (runMode) {\n      case \"save\": {\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n          element: \"action_edit_save\",\n          parameter1: cachedAction.actionType,\n        })\n        break\n      }\n      case \"run\": {\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n          element: \"action_edit_run\",\n          parameter1: cachedAction.actionType,\n        })\n        break\n      }\n      case \"save_and_run\": {\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n          element: \"action_edit_save_run\",\n          parameter1: cachedAction.actionType,\n        })\n        break\n      }\n    }\n  }, [cachedAction.actionType, runMode])\n\n  const runCachedAction = useCallback(\n    async (cachedActionValue: ActionItem<ActionContent>) => {\n      if (cachedActionValue) {\n        try {\n          await runOriginAction(cachedActionValue)\n        } catch (e) {\n          isSafeModeAction(cachedActionValue.actionType) &&\n            setShowSQLModeTip(cachedActionValue.actionID, true)\n        } finally {\n          onResultVisibleChange(true)\n        }\n      }\n    },\n    [onResultVisibleChange, setShowSQLModeTip],\n  )\n\n  const updateAndRunCachedAction = useCallback(\n    (cachedActionValue: ActionItem<ActionContent>) => {\n      if (cachedActionValue) {\n        dispatch(actionActions.updateActionItemReducer(cachedActionValue))\n        runCachedAction(cachedActionValue)\n      }\n    },\n    [dispatch, runCachedAction],\n  )\n\n  const handleActionOperation = useCallback(async () => {\n    let cachedActionValue: ActionItem<ActionContent> =\n      getActionFilteredContent(cachedAction)\n\n    switch (runMode) {\n      case \"test_run\":\n        if (!canRunAction) {\n          message.error({\n            content: canNotRunMessage,\n          })\n          return\n        }\n        updateAndRunCachedAction(cachedActionValue)\n        break\n      case \"run\":\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n          element: \"action_edit_run\",\n          parameter1: cachedAction.actionType,\n          parameter2: cachedAction,\n        })\n        if (!canRunAction) {\n          message.error({\n            content: canNotRunMessage,\n          })\n          return\n        }\n        runCachedAction(cachedActionValue)\n        break\n      case \"save\":\n        if (cachedAction.actionType === \"globalData\") {\n          dispatch(\n            componentsActions.setGlobalStateReducer({\n              key: cachedAction.displayName,\n              value: (cachedAction.content as GlobalDataActionContent)\n                .initialValue,\n              oldKey: cachedAction.displayName,\n            }),\n          )\n          return\n        }\n        if (isGuideOpen) {\n          cachedActionValue &&\n            dispatch(actionActions.updateActionItemReducer(cachedActionValue))\n          return\n        }\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n          element: \"action_edit_save\",\n          parameter1: cachedAction.actionType,\n          parameter2: cachedAction,\n        })\n        setSaveLoading(true)\n        try {\n          await fetchUpdateAction(cachedActionValue)\n          if (cachedActionValue) {\n            dispatch(actionActions.updateActionItemReducer(cachedActionValue))\n          }\n        } catch (e) {\n          message.error({\n            content: t(\"create_fail\"),\n          })\n        }\n        setSaveLoading(false)\n\n        break\n      case \"save_and_run\":\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n          element: \"action_edit_save_run\",\n          parameter1: cachedAction.actionType,\n          parameter2: cachedAction,\n        })\n        if (!canRunAction) {\n          message.error({\n            content: canNotRunMessage,\n          })\n          return\n        }\n        setSaveLoading(true)\n        try {\n          await fetchUpdateAction(cachedActionValue)\n          updateAndRunCachedAction(cachedActionValue)\n        } catch (e) {\n          message.error({\n            content: t(\"editor.action.panel.btn.save_fail\"),\n          })\n        }\n        setSaveLoading(false)\n        break\n    }\n  }, [\n    cachedAction,\n    canNotRunMessage,\n    canRunAction,\n    dispatch,\n    isGuideOpen,\n    message,\n    runCachedAction,\n    runMode,\n    t,\n    updateAndRunCachedAction,\n  ])\n\n  const renderButton = useMemo(() => {\n    return runMode === \"run\" || runMode === \"test_run\"\n      ? cachedAction?.actionType !== \"transformer\" &&\n          cachedAction?.actionType !== \"globalData\"\n      : true\n  }, [cachedAction?.actionType, runMode])\n\n  if (cachedAction === undefined) {\n    return <></>\n  }\n\n  const successBlock = (\n    <div\n      css={actionSuccessBlockStyle}\n      onClick={() => {\n        onResultVisibleChange(!openState)\n      }}\n    >\n      <SuccessCircleIcon fs=\"16px\" size=\"16px\" />\n      <span css={actionTextStyle}>\n        {t(\"editor.action.panel.status.ran_successfully\")}\n      </span>\n      <UpIcon css={applyOpenStateStyle(openState)} />\n    </div>\n  )\n\n  const failBlock = (\n    <div\n      css={actionFailBlockStyle}\n      onClick={() => {\n        onResultVisibleChange(!openState)\n      }}\n    >\n      <WarningCircleIcon fs=\"16px\" size=\"16px\" />\n      <span css={actionTextStyle}>\n        {t(\"editor.action.panel.status.ran_failed\")}\n      </span>\n      <UpIcon css={applyOpenStateStyle(openState)} />\n    </div>\n  )\n\n  return (\n    <>\n      <div css={actionTitleBarStyle}>\n        <SimpleTabs\n          items={innerTabItems}\n          activeKey={activeTab}\n          handleClickChangeTab={handleChangeTab}\n          containerStyle={tabsContainerStyle}\n        />\n        <div css={editableTitleBarWrapperStyle}>\n          <EditableText\n            key={selectedAction.displayName}\n            displayName={selectedAction.displayName}\n            updateDisplayNameByBlur={async (value) => {\n              const newAction = {\n                ...selectedAction,\n                displayName: value,\n              }\n              if (selectedAction.actionType === \"globalData\") {\n                if (DisplayNameGenerator.isAlreadyGenerate(value)) {\n                  message.error({\n                    content: t(\"editor.action.panel.error.duplicated\"),\n                  })\n                  return\n                }\n                DisplayNameGenerator.addDisplayNames([value])\n                DisplayNameGenerator.removeDisplayName(\n                  selectedAction.displayName,\n                )\n                dispatch(\n                  componentsActions.setGlobalStateReducer({\n                    key: value,\n                    value: (selectedAction.content as GlobalDataActionContent)\n                      .initialValue,\n                    oldKey: selectedAction.displayName,\n                  }),\n                )\n                return\n              }\n              if (isGuideOpen) {\n                dispatch(\n                  actionActions.updateActionDisplayNameReducer({\n                    newDisplayName: value,\n                    oldDisplayName: selectedAction.displayName,\n                    actionID: newAction.actionID,\n                  }),\n                )\n\n                return\n              }\n              setSaveLoading(true)\n              try {\n                await fetchUpdateAction(newAction)\n                dispatch(\n                  actionActions.updateActionDisplayNameReducer({\n                    newDisplayName: value,\n                    oldDisplayName: selectedAction.displayName,\n                    actionID: newAction.actionID,\n                  }),\n                )\n              } catch (e) {\n                message.error({\n                  content: t(\"change_fail\"),\n                })\n              }\n              setSaveLoading(false)\n            }}\n            onClick={() => {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.RENAME, {\n                element: \"action_rename\",\n                parameter1: selectedAction.actionType,\n                parameter2: \"hover\",\n              })\n            }}\n          />\n        </div>\n        <div css={runResultAndRunContainerStyle}>\n          {renderResult && (runError ? failBlock : successBlock)}\n          {docLink && (\n            <Link to={docLink} target=\"_blank\">\n              <Button\n                colorScheme=\"grayBlue\"\n                leftIcon={<DocsIcon size=\"14px\" />}\n              />\n            </Link>\n          )}\n          <Dropdown\n            position=\"bottom-end\"\n            trigger=\"click\"\n            dropList={\n              <DropList w=\"184px\">\n                <Item\n                  value=\"duplicate\"\n                  key=\"duplicate\"\n                  title={t(\"editor.action.action_list.contextMenu.duplicate\")}\n                  onClick={() => {\n                    onCopyActionItem(selectedAction)\n                  }}\n                />\n                <Item\n                  key=\"delete\"\n                  value=\"delete\"\n                  title={t(\"editor.action.action_list.contextMenu.delete\")}\n                  deleted\n                  onClick={() => {\n                    shortcut.showDeleteDialog(\n                      [selectedAction.displayName],\n                      \"action\",\n                    )\n                  }}\n                />\n              </DropList>\n            }\n          >\n            <Button\n              colorScheme=\"grayBlue\"\n              leftIcon={<MoreIcon size=\"14px\" />}\n            />\n          </Dropdown>\n          {renderButton && (\n            <Button\n              pos=\"relative\"\n              className={`${cachedAction.displayName}-run`}\n              colorScheme=\"techPurple\"\n              variant={isChanged ? \"fill\" : \"light\"}\n              size=\"medium\"\n              loading={isRunning || saveLoading}\n              leftIcon={<PlayFillIcon />}\n              onClick={handleActionOperation}\n            >\n              {t(`editor.action.panel.btn.${runMode}`)}\n            </Button>\n          )}\n        </div>\n      </div>\n    </>\n  )\n}\n\nActionTitleBar.displayName = \"ActionTitleBar\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionTitleBar/interface.ts",
    "content": "export interface ActionTitleBarProps {\n  onResultVisibleChange: (visible: boolean) => void\n  openState: boolean\n  activeTab: string\n  handleChangeTab: (activeKey: string) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ActionTitleBar/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const actionTitleBarStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  padding: 0 16px;\n  border-bottom: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  min-height: 48px;\n  justify-content: space-between;\n  position: relative;\n`\n\nexport const editableTitleBarWrapperStyle = css`\n  width: 280px;\n  position: absolute;\n  left: calc(50% - 140px);\n  .editable-text-container {\n    justify-content: center;\n    :hover {\n      .text-container {\n        padding-left: 0;\n      }\n    }\n  }\n  .input-container {\n    text-align: center;\n  }\n`\n\nexport const actionSuccessBlockStyle = css`\n  padding: 0 8px;\n  display: inline-flex;\n  flex-direction: row;\n  align-items: center;\n  height: 32px;\n  margin-right: 8px;\n  cursor: pointer;\n  background: ${getColor(\"green\", \"08\")};\n  color: ${getColor(\"green\", \"03\")};\n  border-radius: 8px;\n`\n\nexport const actionFailBlockStyle = css`\n  padding: 0 8px;\n  display: inline-flex;\n  flex-direction: row;\n  margin-right: 8px;\n  cursor: pointer;\n  align-items: center;\n  height: 32px;\n  background: ${getColor(\"orange\", \"08\")};\n  color: ${getColor(\"orange\", \"03\")};\n  border-radius: 8px;\n`\n\nexport const actionTextStyle = css`\n  font-weight: 500;\n  margin-left: 8px;\n  margin-right: 20px;\n  font-size: 14px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport function applyOpenStateStyle(openState: boolean): SerializedStyles {\n  const transform = openState\n    ? css`\n        transform: rotate(180deg);\n      `\n    : css`\n        transform: rotate(0deg);\n      `\n\n  return css`\n    font-size: 12px;\n    transition: transform 0.2s ease;\n    ${transform};\n  `\n}\n\nexport const tabsContainerStyle = css`\n  width: auto;\n  padding-left: 0;\n  padding-right: 0;\n`\n\nexport const runResultAndRunContainerStyle = css`\n  display: flex;\n  gap: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AirtablePanel/CreateRecordsPart/index.tsx",
    "content": "import {\n  AirtableAction,\n  AirtableActionConfigType,\n  AirtableCreateRecord,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const CreateRecordsPart: FC = () => {\n  const { t } = useTranslation()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    AirtableAction<AirtableActionConfigType>\n  >\n\n  const config = cachedAction.content.config as AirtableCreateRecord\n\n  const dispatch = useDispatch()\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.label.airtable.records\")}\n      value={config.records}\n      lineNumbers={true}\n      onChange={(value) => {\n        dispatch(\n          configActions.updateCachedAction({\n            ...cachedAction,\n            content: {\n              ...cachedAction.content,\n              config: {\n                ...config,\n                records: value,\n              },\n            },\n          }),\n        )\n      }}\n      style={{ height: \"188px\" }}\n      expectedType={VALIDATION_TYPES.ARRAY}\n      mode={CODE_LANG.JAVASCRIPT}\n      placeholder={\n        '{{\\n  [\\n    {\"fields\": {\"name\":\"mongo\", \"price\":\"$3.5\"}},\\n    {\"fields\":  {\"name\":\"apple\", \"price\":\"$2.7\"}}\\n  ]\\n}}'\n      }\n      codeType={CODE_TYPE.EXPRESSION}\n      canShowCompleteInfo\n    />\n  )\n}\n\nCreateRecordsPart.displayName = \"CreateRecordsPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AirtablePanel/DeleteMultipleRecordsPart/index.tsx",
    "content": "import {\n  AirtableAction,\n  AirtableActionConfigType,\n  AirtableDeleteMultipleRecords,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DeleteMultipleRecordsPart: FC = () => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    AirtableAction<AirtableActionConfigType>\n  >\n\n  const content =\n    cachedAction.content as AirtableAction<AirtableDeleteMultipleRecords>\n\n  const config = content.config as AirtableDeleteMultipleRecords\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.label.airtable.record_ids\")}\n      value={config.recordIDs}\n      placeholder={'{{[\"1\",\"2\",\"3\"]}}'}\n      onChange={(value) => {\n        dispatch(\n          configActions.updateCachedAction({\n            ...cachedAction,\n            content: {\n              ...cachedAction.content,\n              config: {\n                ...config,\n                recordIDs: value,\n              },\n            },\n          }),\n        )\n      }}\n      expectedType={VALIDATION_TYPES.ARRAY}\n      mode={CODE_LANG.JAVASCRIPT}\n      codeType={CODE_TYPE.EXPRESSION}\n      canShowCompleteInfo\n    />\n  )\n}\n\nDeleteMultipleRecordsPart.displayName = \"DeleteMultipleRecordsPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AirtablePanel/DeleteRecordPart/index.tsx",
    "content": "import {\n  AirtableAction,\n  AirtableActionConfigType,\n  AirtableDeleteRecord,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DeleteRecordPart: FC = () => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    AirtableAction<AirtableActionConfigType>\n  >\n\n  const content = cachedAction.content as AirtableAction<AirtableDeleteRecord>\n\n  const config = content.config as AirtableDeleteRecord\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.label.airtable.record_id\")}\n      value={config.recordID}\n      onChange={(value) => {\n        dispatch(\n          configActions.updateCachedAction({\n            ...cachedAction,\n            content: {\n              ...cachedAction.content,\n              config: {\n                ...config,\n                recordID: value,\n              },\n            },\n          }),\n        )\n      }}\n      expectedType={VALIDATION_TYPES.STRING}\n      mode={CODE_LANG.JAVASCRIPT}\n      codeType={CODE_TYPE.EXPRESSION}\n      canShowCompleteInfo\n    />\n  )\n}\n\nDeleteRecordPart.displayName = \"DeleteRecordPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AirtablePanel/GetRecordPart/index.tsx",
    "content": "import {\n  AirtableAction,\n  AirtableActionConfigType,\n  AirtableGetRecord,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const GetRecordPart: FC = () => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    AirtableAction<AirtableActionConfigType>\n  >\n\n  const content = cachedAction.content as AirtableAction<AirtableGetRecord>\n\n  const config = content.config as AirtableGetRecord\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.label.airtable.record_id\")}\n      value={config.recordID}\n      onChange={(value) => {\n        dispatch(\n          configActions.updateCachedAction({\n            ...cachedAction,\n            content: {\n              ...cachedAction.content,\n              config: {\n                ...config,\n                recordID: value,\n              },\n            },\n          }),\n        )\n      }}\n      expectedType={VALIDATION_TYPES.STRING}\n      mode={CODE_LANG.JAVASCRIPT}\n      codeType={CODE_TYPE.EXPRESSION}\n      canShowCompleteInfo\n    />\n  )\n}\n\nGetRecordPart.displayName = \"GetRecordPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AirtablePanel/ListRecordsPart/index.tsx",
    "content": "import {\n  AirtableAction,\n  AirtableActionConfigType,\n  AirtableListRecord,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { TextLink } from \"@illa-public/text-link\"\nimport { FC } from \"react\"\nimport { Trans, useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const ListRecordsPart: FC = () => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    AirtableAction<AirtableActionConfigType>\n  >\n\n  const content = cachedAction.content as AirtableAction<AirtableListRecord>\n\n  const config = content.config as AirtableListRecord\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.view\")}\n        value={config.view}\n        placeholder=\"Grid view\"\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  view: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.fields\")}\n        value={config.fields}\n        placeholder='{{[\"name\",\"assign\"]}}'\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  fields: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.ARRAY}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.filter_by_formula\")}\n        value={config.filterByFormula}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  filterByFormula: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        tips={\n          <Trans\n            i18nKey=\"editor.action.panel.label.tips.airtable.filter_by_formula\"\n            t={t}\n            components={[\n              <TextLink\n                key=\"text-link\"\n                onClick={() => {\n                  window.open(\n                    \"https://support.airtable.com/docs/formula-field-reference\",\n                    \"_blank\",\n                  )\n                }}\n              />,\n            ]}\n          />\n        }\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.sort\")}\n        value={config.sort}\n        placeholder={\n          '{{\\n  [\\n    {\"field\":\"column1\",\"direction\":\"asc\"},\\n    {\"field\":\"column2\",\"direction\":\"desc\"}\\n  ]\\n}}'\n        }\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  sort: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.ARRAY}\n        style={{ height: \"188px\" }}\n        lineNumbers={true}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.max_records\")}\n        value={config.maxRecords}\n        placeholder={\"{{1000}}\"}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  maxRecords: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.NUMBER}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.page_size\")}\n        value={config.pageSize}\n        placeholder={\"{{100}}\"}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  pageSize: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.NUMBER}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.offset\")}\n        value={config.offset}\n        placeholder={\"recxxxxxxxx\"}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  offset: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.cell_format\")}\n        value={config.cellFormat}\n        placeholder={\"json\"}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  cellFormat: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.time_zone\")}\n        value={config.timeZone}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  timeZone: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        tips={\n          <Trans\n            i18nKey=\"editor.action.panel.label.tips.airtable.time_zone\"\n            t={t}\n            components={[\n              <TextLink\n                key=\"text-link\"\n                onClick={() => {\n                  window.open(\n                    \"https://support.airtable.com/docs/supported-timezones-for-set-timezone\",\n                    \"_blank\",\n                  )\n                }}\n              />,\n            ]}\n          />\n        }\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.user_locales\")}\n        value={config.userLocale}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  userLocale: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        tips={\n          <Trans\n            i18nKey=\"editor.action.panel.label.tips.airtable.user_locales\"\n            t={t}\n            components={[\n              <TextLink\n                key=\"text-link\"\n                onClick={() => {\n                  window.open(\n                    \"https://support.airtable.com/docs/supported-locale-modifiers-for-set-locale\",\n                    \"_blank\",\n                  )\n                }}\n              />,\n            ]}\n          />\n        }\n        canShowCompleteInfo\n      />\n    </>\n  )\n}\n\nListRecordsPart.displayName = \"ListRecordsPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AirtablePanel/UpdateMultipleRecordsPart/index.tsx",
    "content": "import {\n  AirtableAction,\n  AirtableActionConfigType,\n  AirtableUpdateMultipleRecords,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const UpdateMultipleRecordsPart: FC = () => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    AirtableAction<AirtableActionConfigType>\n  >\n\n  const content =\n    cachedAction.content as AirtableAction<AirtableUpdateMultipleRecords>\n\n  const config = content.config as AirtableUpdateMultipleRecords\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.label.airtable.records\")}\n      value={config.records}\n      style={{ height: \"188px\" }}\n      onChange={(value) => {\n        dispatch(\n          configActions.updateCachedAction({\n            ...cachedAction,\n            content: {\n              ...cachedAction.content,\n              config: {\n                ...config,\n                records: value,\n              },\n            },\n          }),\n        )\n      }}\n      lineNumbers={true}\n      expectedType={VALIDATION_TYPES.ARRAY}\n      placeholder={\n        '{{\\n  [\\n    {\"id\":\"xxxxxx\",\"fields\":{\"name\":\"mongo\", \"price\":\"$3.5\"}},\\n    {\"id\":\"xxxxxx\",\"fields\":{\"name\":\"apple\", \"price\":\"$2.7\"}}\\n  ]\\n}}'\n      }\n      mode={CODE_LANG.JAVASCRIPT}\n      codeType={CODE_TYPE.EXPRESSION}\n      canShowCompleteInfo\n    />\n  )\n}\n\nUpdateMultipleRecordsPart.displayName = \"UpdateMultipleRecordsPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AirtablePanel/UpdateRecordPart/index.tsx",
    "content": "import {\n  AirtableAction,\n  AirtableActionConfigType,\n  AirtableUpdateRecord,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const UpdateRecordPart: FC = () => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    AirtableAction<AirtableActionConfigType>\n  >\n\n  const content = cachedAction.content as AirtableAction<AirtableUpdateRecord>\n\n  const config = content.config as AirtableUpdateRecord\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.record_id\")}\n        value={config.recordID}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  recordID: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.record\")}\n        value={config.record}\n        lineNumbers={true}\n        style={{ height: \"188px\" }}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                config: {\n                  ...config,\n                  record: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.OBJECT}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        placeholder={'{{{\"fields\":{\"name\":\"mongo\", \"price\":\"$3.5\"}}}}'}\n        canShowCompleteInfo\n      />\n    </>\n  )\n}\n\nUpdateRecordPart.displayName = \"UpdateRecordPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AirtablePanel/index.tsx",
    "content": "import {\n  AirtableCreateRecordInitial,\n  AirtableDeleteMultipleRecordInitial,\n  AirtableDeleteRecordInitial,\n  AirtableGetRecordInitial,\n  AirtableListRecordInitial,\n  AirtableUpdateMultipleRecordInitial,\n  AirtableUpdateRecordInitial,\n} from \"@illa-public/public-configs\"\nimport {\n  AirtableAction,\n  AirtableActionConfigType,\n  AirtableActionMethodsType,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { FC, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { CreateRecordsPart } from \"@/page/App/components/Actions/ActionPanel/AirtablePanel/CreateRecordsPart\"\nimport { DeleteMultipleRecordsPart } from \"@/page/App/components/Actions/ActionPanel/AirtablePanel/DeleteMultipleRecordsPart\"\nimport { DeleteRecordPart } from \"@/page/App/components/Actions/ActionPanel/AirtablePanel/DeleteRecordPart\"\nimport { GetRecordPart } from \"@/page/App/components/Actions/ActionPanel/AirtablePanel/GetRecordPart\"\nimport { ListRecordsPart } from \"@/page/App/components/Actions/ActionPanel/AirtablePanel/ListRecordsPart\"\nimport { UpdateMultipleRecordsPart } from \"@/page/App/components/Actions/ActionPanel/AirtablePanel/UpdateMultipleRecordsPart\"\nimport { UpdateRecordPart } from \"@/page/App/components/Actions/ActionPanel/AirtablePanel/UpdateRecordPart\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { actionItemContainer } from \"@/page/App/components/Actions/ActionPanel/style\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const AirtableMethodList = [\n  {\n    label: \"List Records\",\n    value: \"list\",\n  },\n  {\n    label: \"Get Record\",\n    value: \"get\",\n  },\n  {\n    label: \"Create Records\",\n    value: \"create\",\n  },\n  {\n    label: \"Update Record\",\n    value: \"update\",\n  },\n  {\n    label: \"Update Multiple Records\",\n    value: \"bulkUpdate\",\n  },\n  {\n    label: \"Delete Record\",\n    value: \"delete\",\n  },\n  {\n    label: \"Delete Multiple Records\",\n    value: \"bulkDelete\",\n  },\n]\n\nconst AirtablePanel: FC = () => {\n  const { t } = useTranslation()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    AirtableAction<AirtableActionConfigType>\n  >\n\n  const selectedAction = useSelector(getSelectedAction) as ActionItem<\n    AirtableAction<AirtableActionConfigType>\n  >\n\n  const dispatch = useDispatch()\n\n  let content = cachedAction.content as AirtableAction<AirtableActionConfigType>\n\n  const part = useMemo(() => {\n    switch (content.method) {\n      case \"list\":\n        return <ListRecordsPart />\n      case \"get\":\n        return <GetRecordPart />\n      case \"create\":\n        return <CreateRecordsPart />\n      case \"update\":\n        return <UpdateRecordPart />\n      case \"bulkUpdate\":\n        return <UpdateMultipleRecordsPart />\n      case \"bulkDelete\":\n        return <DeleteMultipleRecordsPart />\n      case \"delete\":\n        return <DeleteRecordPart />\n      default:\n        return <></>\n    }\n  }, [content.method])\n\n  return (\n    <div css={actionItemContainer}>\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.base_id\")}\n        value={content.baseConfig.baseId}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                baseConfig: {\n                  ...cachedAction.content.baseConfig,\n                  baseId: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        tips={t(\"editor.action.panel.label.tips.airtable.base_id\")}\n        canShowCompleteInfo\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.airtable.table_name\")}\n        value={content.baseConfig.tableName}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                baseConfig: {\n                  ...cachedAction.content.baseConfig,\n                  tableName: value,\n                },\n              },\n            }),\n          )\n        }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        canShowCompleteInfo\n      />\n      <SingleTypeComponent\n        componentType=\"select\"\n        showSearch={true}\n        value={content.method}\n        onSelectedValueChange={(value) => {\n          let config = selectedAction.content.config\n          if (selectedAction.content.method !== value) {\n            switch (value) {\n              case \"list\":\n                config = AirtableListRecordInitial\n                break\n              case \"get\":\n                config = AirtableGetRecordInitial\n                break\n              case \"create\":\n                config = AirtableCreateRecordInitial\n                break\n              case \"update\":\n                config = AirtableUpdateRecordInitial\n                break\n              case \"bulkUpdate\":\n                config = AirtableUpdateMultipleRecordInitial\n                break\n              case \"bulkDelete\":\n                config = AirtableDeleteMultipleRecordInitial\n                break\n              case \"delete\":\n                config = AirtableDeleteRecordInitial\n                break\n              default:\n                break\n            }\n          }\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                method: value as AirtableActionMethodsType,\n                config: config,\n              },\n            }),\n          )\n        }}\n        options={AirtableMethodList}\n        title={t(\"editor.action.panel.mongodb.action_type\")}\n      />\n      {part}\n      <TransformerComponent />\n    </div>\n  )\n}\n\nAirtablePanel.displayName = \"AirtablePanel\"\nexport default AirtablePanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AppwritePanel/DocumentSubPanel/index.tsx",
    "content": "import { AppwriteDocumentOperations } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { AppwriteSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/AppwritePanel/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DocumentSubPanel: FC<AppwriteSubPanelProps> = (props) => {\n  const { handleValueChange, withDataEditor, collectionIds } = props\n  const params = props.params as AppwriteDocumentOperations\n  const { t } = useTranslation()\n  return (\n    <>\n      <SingleTypeComponent\n        componentType=\"select\"\n        onChange={handleValueChange(\"collectionID\")}\n        value={params.collectionID}\n        title={t(\"editor.action.form.label.appwrite.collectionid\")}\n        placeholder={t(\"editor.action.form.placeholder.appwrite.collectionid\")}\n        options={collectionIds}\n      />\n      <InputEditor\n        onChange={handleValueChange(\"documentID\")}\n        value={params.documentID}\n        title={t(\"editor.action.form.label.appwrite.documentid\")}\n      />\n      {withDataEditor && (\n        <InputEditor\n          value={params.data}\n          onChange={handleValueChange(\"data\")}\n          lineNumbers\n          expectedType={VALIDATION_TYPES.OBJECT}\n          style={{ height: \"88px\" }}\n          title={t(\"editor.action.form.label.appwrite.data\")}\n          placeholder={t(\"editor.action.form.placeholder.appwrite.data\")}\n        />\n      )}\n    </>\n  )\n}\nDocumentSubPanel.displayName = \"DocumentSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AppwritePanel/ListDocuments/index.tsx",
    "content": "import { AppwriteListDocuments, Params } from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Select } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { RecordEditor } from \"@/components/RecordEditor\"\nimport { AppwriteSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/AppwritePanel/interface\"\nimport {\n  codeMirrorWrapperLabelStyle,\n  codeMirrorWrapperValueStyle,\n} from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionRecordEditor/style\"\nimport { actionItemRecordEditorStyle } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/style\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst useListDocumentsFilterOptions = () => {\n  const { t } = useTranslation()\n\n  return [\n    {\n      label: t(\"editor.action.form.option.appwrite.filter.equal\"),\n      value: \"equal\",\n    },\n    {\n      label: t(\"editor.action.form.option.appwrite.filter.notequal\"),\n      value: \"notEqual\",\n    },\n    {\n      label: t(\"editor.action.form.option.appwrite.filter.lessthan\"),\n      value: \"lessThan\",\n    },\n    {\n      label: t(\"editor.action.form.option.appwrite.filter.lessthanEqual\"),\n      value: \"lessThanEqual\",\n    },\n    {\n      label: t(\"editor.action.form.option.appwrite.filter.greaterthan\"),\n      value: \"greaterThan\",\n    },\n    {\n      label: t(\"editor.action.form.option.appwrite.filter.greaterthanequal\"),\n      value: \"greaterThanEqual\",\n    },\n  ]\n}\n\nconst useListDocumentsOrderOptions = () => {\n  const { t } = useTranslation()\n\n  return [\n    {\n      label: t(\"editor.action.form.option.appwrite.order.asc\"),\n      value: \"asc\",\n    },\n    {\n      label: t(\"editor.action.form.option.appwrite.order.desc\"),\n      value: \"desc\",\n    },\n  ]\n}\n\nexport const ListDocumentsSubPanel: FC<AppwriteSubPanelProps> = (props) => {\n  const { handleValueChange, collectionIds } = props\n  const params = props.params as AppwriteListDocuments\n  const { t } = useTranslation()\n\n  const listDocumentsFilterOptions = useListDocumentsFilterOptions()\n  const listDocumentsOrderOptions = useListDocumentsOrderOptions()\n\n  const handleOnAddKeys = useCallback(\n    (name?: string) => {\n      if (!(name && params.hasOwnProperty(name))) {\n        return\n      }\n      const oldList = params[name as keyof typeof params] as Params[]\n      const newListItem: Params =\n        name === \"filter\"\n          ? {\n              key: \"\",\n              operator: \"\",\n              value: \"\",\n            }\n          : { key: \"\", value: \"\" }\n\n      let newList = [...oldList, newListItem]\n      handleValueChange(name)(newList)\n    },\n    [handleValueChange, params],\n  )\n\n  const handleOnDeleteKeys = useCallback(\n    (index: number, record: Params, name?: string) => {\n      if (!(name && params.hasOwnProperty(name))) {\n        return\n      }\n      const oldList = params[name as keyof typeof params] as Params[]\n      let newRecords = [...oldList]\n      const newListItem: Params =\n        name === \"filter\"\n          ? { key: \"\", operator: \"\", value: \"\" }\n          : { key: \"\", value: \"\" }\n\n      newRecords.splice(index, 1)\n      if (newRecords.length === 0) {\n        newRecords = [newListItem]\n      }\n      handleValueChange(name)(newRecords)\n    },\n    [handleValueChange, params],\n  )\n\n  const handleOnChangeKeyOrValue = useCallback(\n    (\n      index: number,\n      key: string,\n      value: string,\n      name?: string,\n      operator?: string,\n    ) => {\n      if (!(name && params.hasOwnProperty(name))) {\n        return\n      }\n      const oldList = params[name as keyof typeof params] as Params[]\n      let newList = [...oldList]\n      const newListItem: Params = operator\n        ? {\n            key,\n            value,\n            operator,\n          }\n        : { key, value }\n      newList[index] = newListItem\n      handleValueChange(name)(newList)\n    },\n    [handleValueChange, params],\n  )\n\n  return (\n    <>\n      <SingleTypeComponent\n        componentType=\"select\"\n        onChange={handleValueChange(\"collectionID\")}\n        value={params.collectionID}\n        title={t(\"editor.action.form.label.appwrite.collectionid\")}\n        placeholder={t(\"editor.action.form.placeholder.appwrite.collectionid\")}\n        options={collectionIds}\n      />\n      <RecordEditor\n        label={t(\"editor.action.form.label.appwrite.filter\")}\n        records={params.filter}\n        customRender={(record, index) => (\n          <>\n            <div css={actionItemRecordEditorStyle}>\n              <CodeEditor\n                value={record.key}\n                singleLine\n                onChange={(val) => {\n                  handleOnChangeKeyOrValue(\n                    index,\n                    val,\n                    record.value,\n                    \"filter\",\n                    record.operator,\n                  )\n                }}\n                wrapperCss={codeMirrorWrapperLabelStyle}\n                expectValueType={VALIDATION_TYPES.STRING}\n                lang={CODE_LANG.JAVASCRIPT}\n                codeType={CODE_TYPE.EXPRESSION}\n                canShowCompleteInfo\n                placeholder={t(\n                  \"editor.action.form.placeholder.appwrite.filter.attribute\",\n                )}\n              />\n            </div>\n            <Select\n              colorScheme=\"techPurple\"\n              showSearch={true}\n              defaultValue={record.operator}\n              value={record.operator}\n              w=\"0\"\n              ml=\"-0.5px\"\n              mr=\"-0.5px\"\n              bdRadius=\"0\"\n              flexGrow=\"1\"\n              onChange={(val) =>\n                handleOnChangeKeyOrValue(\n                  index,\n                  record.key,\n                  record.value,\n                  \"filter\",\n                  val as string,\n                )\n              }\n              options={listDocumentsFilterOptions}\n            />\n            <div css={actionItemRecordEditorStyle}>\n              <CodeEditor\n                singleLine\n                value={record.value}\n                onChange={(val) => {\n                  handleOnChangeKeyOrValue(\n                    index,\n                    record.key,\n                    val,\n                    \"filter\",\n                    record.operator,\n                  )\n                }}\n                wrapperCss={codeMirrorWrapperValueStyle}\n                expectValueType={VALIDATION_TYPES.STRING}\n                lang={CODE_LANG.JAVASCRIPT}\n                codeType={CODE_TYPE.EXPRESSION}\n                canShowCompleteInfo\n                placeholder={t(\n                  \"editor.action.form.placeholder.appwrite.filter.value\",\n                )}\n              />\n            </div>\n          </>\n        )}\n        name=\"filter\"\n        onAdd={handleOnAddKeys}\n        onDelete={handleOnDeleteKeys}\n        onChangeKey={() => {}}\n        onChangeValue={() => {}}\n      />\n      <RecordEditor\n        label={t(\"editor.action.form.label.appwrite.order\")}\n        records={params.orderBy}\n        customRender={(record, index) => (\n          <>\n            <div css={actionItemRecordEditorStyle}>\n              <CodeEditor\n                value={record.key}\n                singleLine\n                onChange={(val) => {\n                  handleOnChangeKeyOrValue(index, val, record.value, \"orderBy\")\n                }}\n                wrapperCss={codeMirrorWrapperLabelStyle}\n                expectValueType={VALIDATION_TYPES.STRING}\n                lang={CODE_LANG.JAVASCRIPT}\n                codeType={CODE_TYPE.EXPRESSION}\n                canShowCompleteInfo\n                placeholder={t(\"editor.action.form.placeholder.appwrite.order\")}\n              />\n            </div>\n            <Select\n              colorScheme=\"techPurple\"\n              showSearch={true}\n              defaultValue={record.value}\n              value={record.value}\n              w=\"0\"\n              bdRadius=\"0\"\n              flexGrow=\"1\"\n              onChange={(val) =>\n                handleOnChangeKeyOrValue(\n                  index,\n                  record.key,\n                  val as string,\n                  \"orderBy\",\n                )\n              }\n              options={listDocumentsOrderOptions}\n            />\n          </>\n        )}\n        name=\"orderBy\"\n        onAdd={handleOnAddKeys}\n        onDelete={handleOnDeleteKeys}\n        onChangeKey={() => {}}\n        onChangeValue={() => {}}\n      />\n      <InputEditor\n        onChange={handleValueChange(\"limit\")}\n        value={params.limit}\n        expectedType={VALIDATION_TYPES.NUMBER}\n        title={t(\"editor.action.form.label.appwrite.limit\")}\n      />\n    </>\n  )\n}\nListDocumentsSubPanel.displayName = \"ListDocumentsSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AppwritePanel/index.tsx",
    "content": "import {\n  AppwriteDocumentOperationsInitial,\n  AppwriteListDocumentsInitial,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  AppwriteAction,\n  AppwriteActionMethodsType,\n  AppwriteActionTypes,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback, useEffect, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { DocumentSubPanel } from \"@/page/App/components/Actions/ActionPanel/AppwritePanel/DocumentSubPanel\"\nimport { ListDocumentsSubPanel } from \"@/page/App/components/Actions/ActionPanel/AppwritePanel/ListDocuments\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { actionItemContainer } from \"@/page/App/components/Actions/ActionPanel/style\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { fetchResourceMeta } from \"@/services/resource\"\n\nconst AppwriteSubComponentMap = {\n  get: DocumentSubPanel,\n  create: DocumentSubPanel,\n  update: DocumentSubPanel,\n  delete: DocumentSubPanel,\n  list: ListDocumentsSubPanel,\n}\n\nexport const AppwriteActionMethodsOptions: {\n  label: string\n  value: AppwriteActionMethodsType\n}[] = [\n  {\n    label: \"Create a document\",\n    value: \"create\",\n  },\n  {\n    label: \"Get a document\",\n    value: \"get\",\n  },\n  {\n    label: \"Update a document\",\n    value: \"update\",\n  },\n  {\n    label: \"Delete a document\",\n    value: \"delete\",\n  },\n  {\n    label: \"List documents\",\n    value: \"list\",\n  },\n]\n\nconst AppwritePanel: FC = () => {\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    AppwriteAction<AppwriteActionTypes>\n  >\n  const selectedAction = useSelector(getSelectedAction) as ActionItem<\n    AppwriteAction<AppwriteActionTypes>\n  >\n  const content = cachedAction.content\n  const selectedContent = selectedAction.content\n  const dispatch = useDispatch()\n  const [collectionIds, setCollectionIds] = useState<string[]>([])\n\n  useEffect(() => {\n    if (cachedAction.resourceID == undefined) return\n    fetchResourceMeta(cachedAction.resourceID).then(({ data }) => {\n      const ids = ((data.Schema?.collections as []) ?? []).map(\n        (item: { id: string }) => item.id,\n      )\n      setCollectionIds(ids)\n    })\n  }, [cachedAction.resourceID])\n\n  const handleMethodValueChange = useCallback(\n    (value: AppwriteActionMethodsType) => {\n      const newContent =\n        selectedContent.method === value\n          ? selectedContent\n          : {\n              opts:\n                value === \"list\"\n                  ? AppwriteListDocumentsInitial\n                  : AppwriteDocumentOperationsInitial,\n              method: value,\n            }\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: newContent,\n        }),\n      )\n    },\n    [cachedAction, dispatch, selectedContent],\n  )\n\n  const handleValueChange = useCallback(\n    (param: string) => (value: string | Record<string, string>[]) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            opts: {\n              ...content.opts,\n              [param]: value,\n            },\n          },\n        }),\n      )\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  const Component = AppwriteSubComponentMap[content.method]\n  const withDataEditor = ![\"get\", \"delete\"].includes(content.method)\n\n  return (\n    <div css={actionItemContainer}>\n      <SingleTypeComponent\n        componentType=\"select\"\n        onChange={handleMethodValueChange}\n        value={content.method}\n        options={AppwriteActionMethodsOptions}\n        title={\"Method\"}\n      />\n      <Component\n        key={content.method}\n        handleValueChange={handleValueChange}\n        withDataEditor={withDataEditor}\n        params={content.opts}\n        collectionIds={collectionIds}\n      />\n      <TransformerComponent />\n    </div>\n  )\n}\nAppwritePanel.displayName = \"AppwritePanel\"\nexport default AppwritePanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/AppwritePanel/interface.ts",
    "content": "import { AppwriteActionTypes, Params } from \"@illa-public/public-types\"\n\nexport interface AppwriteSubPanelProps {\n  params: AppwriteActionTypes\n  withDataEditor?: boolean\n  collectionIds: string[]\n  handleValueChange: (param: string) => (value: string | Params[]) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/CouchDBPanel/CreateRecordSubPanel/index.tsx",
    "content": "import { CouchDBCreateRecord } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { CouchDBSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/interface\"\nimport { CreateRecordInfo } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/values\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const CreateRecordSubPanel: FC<CouchDBSubPanelProps> = (props) => {\n  const { onInputValueChange } = props\n  const opts = props.opts as CouchDBCreateRecord\n  return (\n    <>\n      {CreateRecordInfo.map((info) => {\n        const {\n          title,\n          name,\n          expectedType,\n          lineNumbers,\n          style = {},\n          placeholder,\n        } = info\n        const value = opts[name[1] as keyof CouchDBCreateRecord]\n        return (\n          <InputEditor\n            key={name.join(\"-\")}\n            title={title}\n            expectedType={expectedType}\n            value={value as string}\n            onChange={onInputValueChange(name)}\n            lineNumbers={!!lineNumbers}\n            placeholder={placeholder}\n            style={style}\n          />\n        )\n      })}\n    </>\n  )\n}\nCreateRecordSubPanel.displayName = \"CreateRecordSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/CouchDBPanel/DeleteRecordSubPanel/index.tsx",
    "content": "import { CouchDBDeleteRecord } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { CouchDBSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/interface\"\nimport { DeleteRecordInfo } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/values\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const DeleteRecordSubPanel: FC<CouchDBSubPanelProps> = (props) => {\n  const { onInputValueChange } = props\n  const opts = props.opts as CouchDBDeleteRecord\n\n  return (\n    <>\n      {DeleteRecordInfo.map((info) => {\n        const { title, name, expectedType, lineNumbers, style = {} } = info\n        const value = opts[name[1] as keyof CouchDBDeleteRecord]\n        return (\n          <InputEditor\n            key={name.join(\"-\")}\n            title={title}\n            expectedType={expectedType}\n            value={value as string}\n            onChange={onInputValueChange(name)}\n            lineNumbers={!!lineNumbers}\n            style={style}\n          />\n        )\n      })}\n    </>\n  )\n}\nDeleteRecordSubPanel.displayName = \"DeleteRecordSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/CouchDBPanel/FindRecordSubPanel/index.tsx",
    "content": "import { CouchDBFindRecord } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { CouchDBSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/interface\"\nimport { FindRecordInfo } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/values\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const FindRecordSubPanel: FC<CouchDBSubPanelProps> = (props) => {\n  const { onInputValueChange } = props\n  const opts = props.opts as CouchDBFindRecord\n\n  return (\n    <>\n      {FindRecordInfo.map((info) => {\n        const { title, name, expectedType, lineNumbers, style, placeholder } =\n          info\n        const value = opts[name[1] as keyof CouchDBFindRecord]\n        return (\n          <InputEditor\n            key={name.join(\"-\")}\n            title={title}\n            expectedType={expectedType}\n            value={value as string}\n            onChange={onInputValueChange(name)}\n            lineNumbers={!!lineNumbers}\n            placeholder={placeholder}\n            style={style}\n          />\n        )\n      })}\n    </>\n  )\n}\nFindRecordSubPanel.displayName = \"FindRecordSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/CouchDBPanel/GetViewSubPanel/index.tsx",
    "content": "import { CouchDBGetView } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { CouchDBSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/interface\"\nimport { GetViewRecordsInfo } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/values\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { SingleComponentType } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const GetViewSubPanel: FC<CouchDBSubPanelProps> = (props) => {\n  const { onInputValueChange, onBooleanValueChange } = props\n  const opts = props.opts as CouchDBGetView\n\n  return (\n    <>\n      {GetViewRecordsInfo.map((info) => {\n        const {\n          title,\n          type,\n          name,\n          expectedType,\n          lineNumbers = false,\n          style = {},\n          content = \"\",\n        } = info\n        const value = opts[name[1] as keyof CouchDBGetView]\n        if (type === \"editor\") {\n          return (\n            <InputEditor\n              key={name.join(\"-\")}\n              title={title}\n              expectedType={expectedType}\n              value={value as string}\n              onChange={onInputValueChange(name)}\n              lineNumbers={lineNumbers}\n              style={style}\n            />\n          )\n        }\n        return (\n          <SingleTypeComponent\n            key={name.join(\"-\")}\n            title={title}\n            componentType={type as SingleComponentType}\n            onBooleanValueChange={onBooleanValueChange(name)}\n            value={value}\n            switchContent={content}\n          />\n        )\n      })}\n    </>\n  )\n}\nGetViewSubPanel.displayName = \"GetViewSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/CouchDBPanel/ListRecordsSubPanel/index.tsx",
    "content": "import { CouchDBListRecords } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { CouchDBSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/interface\"\nimport { ListRecordsInfo } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/values\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { SingleComponentType } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const ListRecordsSubPanel: FC<CouchDBSubPanelProps> = (props) => {\n  const { onBooleanValueChange, onInputValueChange } = props\n  const opts = props.opts as CouchDBListRecords\n\n  return (\n    <>\n      {ListRecordsInfo.map((info) => {\n        const { title, type, name, expectedType, content = \"\" } = info\n        const value = opts[name[1] as keyof CouchDBListRecords]\n        if (type === \"editor\") {\n          return (\n            <InputEditor\n              key={name.join(\"-\")}\n              title={title}\n              expectedType={expectedType}\n              value={value as string}\n              onChange={onInputValueChange(name)}\n            />\n          )\n        }\n        return (\n          <SingleTypeComponent\n            key={name.join(\"-\")}\n            title={title}\n            componentType={type as SingleComponentType}\n            onBooleanValueChange={onBooleanValueChange(name)}\n            value={value}\n            switchContent={content}\n          />\n        )\n      })}\n    </>\n  )\n}\nListRecordsSubPanel.displayName = \"ListRecordsSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/CouchDBPanel/RetrieveRecordSubPanel/index.tsx",
    "content": "import { CouchDBRetrieveRecord } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { CouchDBSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/interface\"\nimport { RetrieveRecordInfo } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/values\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const RetrieveRecordSubPanel: FC<CouchDBSubPanelProps> = (props) => {\n  const { onInputValueChange } = props\n  const opts = props.opts as CouchDBRetrieveRecord\n\n  return (\n    <>\n      {RetrieveRecordInfo.map((info) => {\n        const { title, name, expectedType, lineNumbers, style = {} } = info\n        const value = opts[name[1] as keyof CouchDBRetrieveRecord]\n        return (\n          <InputEditor\n            key={name.join(\"-\")}\n            title={title}\n            expectedType={expectedType}\n            value={value as string}\n            onChange={onInputValueChange(name)}\n            lineNumbers={!!lineNumbers}\n            style={style}\n          />\n        )\n      })}\n    </>\n  )\n}\nRetrieveRecordSubPanel.displayName = \"RetrieveRecordSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/CouchDBPanel/UpdateRecordSubPanel/index.tsx",
    "content": "import { CouchDBUpdateRecord } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { CouchDBSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/interface\"\nimport { UpdateRecordInfo } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/values\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const UpdateRecordSubPanel: FC<CouchDBSubPanelProps> = (props) => {\n  const { onInputValueChange } = props\n  const opts = props.opts as CouchDBUpdateRecord\n\n  return (\n    <>\n      {UpdateRecordInfo.map((info) => {\n        const {\n          title,\n          name,\n          expectedType,\n          lineNumbers,\n          style = {},\n          placeholder,\n        } = info\n        const value = opts[name[1] as keyof CouchDBUpdateRecord]\n        return (\n          <InputEditor\n            key={name.join(\"-\")}\n            title={title}\n            expectedType={expectedType}\n            value={value as string}\n            onChange={onInputValueChange(name)}\n            lineNumbers={!!lineNumbers}\n            placeholder={placeholder}\n            style={style}\n          />\n        )\n      })}\n    </>\n  )\n}\nUpdateRecordSubPanel.displayName = \"UpdateRecordSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/CouchDBPanel/index.tsx",
    "content": "import {\n  ActionItem,\n  CouchDBAction,\n  CouchDBActionMethods,\n  CouchDBOptionsType,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback, useEffect, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { SelectValue } from \"@illa-design/react\"\nimport { CreateRecordSubPanel } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/CreateRecordSubPanel\"\nimport { DeleteRecordSubPanel } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/DeleteRecordSubPanel\"\nimport { FindRecordSubPanel } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/FindRecordSubPanel\"\nimport { GetViewSubPanel } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/GetViewSubPanel\"\nimport { ListRecordsSubPanel } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/ListRecordsSubPanel\"\nimport { RetrieveRecordSubPanel } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/RetrieveRecordSubPanel\"\nimport { UpdateRecordSubPanel } from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/UpdateRecordSubPanel\"\nimport {\n  CouchDBMethodsInitialValueMap,\n  CouchDBPanelMethodOptions,\n} from \"@/page/App/components/Actions/ActionPanel/CouchDBPanel/values\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { actionItemContainer } from \"@/page/App/components/Actions/ActionPanel/style\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { fetchResourceMeta } from \"@/services/resource\"\n\ntype CouchDBPanelType = ActionItem<CouchDBAction<CouchDBOptionsType>>\n\nconst MethodSubPanelMap = {\n  listRecords: ListRecordsSubPanel,\n  retrieveRecord: RetrieveRecordSubPanel,\n  createRecord: CreateRecordSubPanel,\n  updateRecord: UpdateRecordSubPanel,\n  deleteRecord: DeleteRecordSubPanel,\n  find: FindRecordSubPanel,\n  getView: GetViewSubPanel,\n}\nconst updateActionContent = <T extends Record<string, unknown>>(\n  obj: T,\n  path: string[],\n  value: string | boolean,\n) => {\n  if (path.length === 1) {\n    const key = path[0]\n    return { ...obj, [key]: value } as T\n  }\n  const [currentKey, ...restKeys] = path\n  const currentObj = obj[currentKey] as Record<string, unknown>\n  const updatedObj = updateActionContent(currentObj, restKeys, value) as T\n\n  return { ...obj, [currentKey]: updatedObj } as T\n}\n\nconst CouchDBPanel: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const selectedAction = useSelector(getSelectedAction) as CouchDBPanelType\n  const cachedAction = useSelector(getCachedAction) as CouchDBPanelType\n  const content = cachedAction.content\n  const selectedContent = selectedAction.content\n  const [selectOptions, setSelectOptions] = useState<string[]>([])\n\n  useEffect(() => {\n    if (cachedAction.resourceID == undefined) return\n    fetchResourceMeta(cachedAction.resourceID).then(({ data }) => {\n      const { Schema } = data\n      setSelectOptions((Schema?.databases ?? []) as string[])\n    })\n  }, [cachedAction.resourceID])\n\n  const handleValueChange = useCallback(\n    (value: string | boolean, name: string[]) => {\n      const isMethod = name[0] === \"method\"\n      let newContent: CouchDBAction<CouchDBOptionsType> = { ...content }\n      if (isMethod) {\n        if (selectedContent.method === value) {\n          newContent = { ...selectedContent }\n        } else {\n          newContent = {\n            ...content,\n            method: value as CouchDBActionMethods,\n            opts: CouchDBMethodsInitialValueMap[value as string],\n          }\n        }\n      } else {\n        newContent = updateActionContent({ ...newContent }, name, value)\n      }\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: newContent,\n        }),\n      )\n    },\n    [cachedAction, content, dispatch, selectedContent],\n  )\n\n  const handleSelectedValueChange = useCallback(\n    (name: string | string[]) => (value: SelectValue) => {\n      handleValueChange(value as string, ([] as string[]).concat(name))\n    },\n    [handleValueChange],\n  )\n\n  const handleBooleanValueChange = useCallback(\n    (name: string | string[]) => (value: boolean) => {\n      handleValueChange(value, ([] as string[]).concat(name))\n    },\n    [handleValueChange],\n  )\n\n  const SubPanel = MethodSubPanelMap[content.method]\n\n  return (\n    <div css={actionItemContainer}>\n      <SingleTypeComponent\n        title={t(\"editor.action.panel.label.couchdb.database\")}\n        componentType=\"select\"\n        onSelectedValueChange={handleSelectedValueChange(\"database\")}\n        value={content.database}\n        options={selectOptions}\n        placeholder={t(\n          \"editor.action.panel.label.placeholder.couchdb.database\",\n        )}\n      />\n      <SingleTypeComponent\n        title={t(\"editor.action.panel.label.couchdb.action_type\")}\n        componentType=\"select\"\n        onSelectedValueChange={handleSelectedValueChange(\"method\")}\n        value={content.method}\n        options={CouchDBPanelMethodOptions}\n      />\n      <SubPanel\n        onInputValueChange={handleSelectedValueChange}\n        onBooleanValueChange={handleBooleanValueChange}\n        opts={content.opts}\n      />\n      <TransformerComponent />\n    </div>\n  )\n}\nCouchDBPanel.displayName = \"CouchDBPanel\"\nexport default CouchDBPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/CouchDBPanel/interface.ts",
    "content": "import { CouchDBOptionsType } from \"@illa-public/public-types\"\nimport { SelectValue } from \"@illa-design/react\"\n\nexport interface CouchDBSubPanelProps {\n  onInputValueChange: (name: string | string[]) => (value: SelectValue) => void\n  onBooleanValueChange: (name: string | string[]) => (value: boolean) => void\n  opts: CouchDBOptionsType\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/CouchDBPanel/values.ts",
    "content": "import {\n  CouchDBCreateRecordInitial,\n  CouchDBDeleteRecordInitial,\n  CouchDBFindRecordInitial,\n  CouchDBGetViewInitial,\n  CouchDBListRecordsInitial,\n  CouchDBRetrieveRecordInitial,\n  CouchDBUpdateRecordInitial,\n} from \"@illa-public/public-configs\"\nimport { CouchDBOptionsType } from \"@illa-public/public-types\"\nimport i18n from \"@/i18n/config\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const CouchDBPanelMethodOptions = [\n  {\n    label: i18n.t(\"editor.action.panel.label.option.couchdb.action_type.list\"),\n    value: \"listRecords\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.panel.label.option.couchdb.action_type.retrieve\",\n    ),\n    value: \"retrieveRecord\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.panel.label.option.couchdb.action_type.create\",\n    ),\n    value: \"createRecord\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.panel.label.option.couchdb.action_type.update\",\n    ),\n    value: \"updateRecord\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.panel.label.option.couchdb.action_type.delete\",\n    ),\n    value: \"deleteRecord\",\n  },\n  {\n    label: i18n.t(\"editor.action.panel.label.option.couchdb.action_type.find\"),\n    value: \"find\",\n  },\n  {\n    label: i18n.t(\"editor.action.panel.label.option.couchdb.action_type.get\"),\n    value: \"getView\",\n  },\n]\n\nexport const ListRecordsInfo = [\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.skip\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.NUMBER,\n    name: [\"opts\", \"skip\"],\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.limit\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.NUMBER,\n    name: [\"opts\", \"limit\"],\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.include\"),\n    type: \"switch\",\n    name: [\"opts\", \"includeDocs\"],\n    content: i18n.t(\n      \"editor.action.panel.label.option.couchdb.include_doc_option\",\n    ),\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.des\"),\n    type: \"switch\",\n    name: [\"opts\", \"descendingOrder\"],\n    content: i18n.t(\"editor.action.panel.label.option.couchdb.des_option\"),\n  },\n]\n\nexport const RetrieveRecordInfo = [\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.id\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.STRING,\n    name: [\"opts\", \"_id\"],\n    lineNumbers: true,\n    style: {\n      maxHeight: \"88px\",\n    },\n  },\n]\n\nexport const CreateRecordInfo = [\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.record\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n    name: [\"opts\", \"record\"],\n    lineNumbers: true,\n    placeholder: i18n.t(\"editor.action.panel.label.placeholder.couchdb.record\"),\n    style: {\n      height: \"88px\",\n    },\n  },\n]\n\nexport const UpdateRecordInfo = [\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.id\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.STRING,\n    name: [\"opts\", \"_id\"],\n    lineNumbers: true,\n    style: {\n      maxHeight: \"88px\",\n    },\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.rev\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.STRING,\n    name: [\"opts\", \"_rev\"],\n    lineNumbers: true,\n    style: {\n      maxHeight: \"88px\",\n    },\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.record\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n    name: [\"opts\", \"record\"],\n    lineNumbers: true,\n    placeholder: i18n.t(\"editor.action.panel.label.placeholder.couchdb.record\"),\n    style: {\n      height: \"88px\",\n    },\n  },\n]\n\nexport const DeleteRecordInfo = [\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.id\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.STRING,\n    name: [\"opts\", \"_id\"],\n    lineNumbers: true,\n    style: {\n      maxHeight: \"88px\",\n    },\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.rev\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.STRING,\n    name: [\"opts\", \"_rev\"],\n    lineNumbers: true,\n    style: {\n      maxHeight: \"88px\",\n    },\n  },\n]\n\nexport const FindRecordInfo = [\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.mangoquery\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n    name: [\"opts\", \"mangoQuery\"],\n    lineNumbers: true,\n    placeholder: i18n.t(\n      \"editor.action.panel.label.placeholder.couchdb.mangoquery\",\n    ),\n    style: {\n      height: \"88px\",\n    },\n  },\n]\n\nexport const GetViewRecordsInfo = [\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.ViewURL\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.STRING,\n    name: [\"opts\", \"viewurl\"],\n    lineNumbers: true,\n    style: {\n      maxHeight: \"88px\",\n    },\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.StartKey\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.STRING,\n    name: [\"opts\", \"startkey\"],\n    lineNumbers: true,\n    style: {\n      maxHeight: \"88px\",\n    },\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.EndKey\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.STRING,\n    name: [\"opts\", \"endkey\"],\n    lineNumbers: true,\n    style: {\n      maxHeight: \"88px\",\n    },\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.skip\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.NUMBER,\n    name: [\"opts\", \"skip\"],\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.limit\"),\n    type: \"editor\",\n    expectedType: VALIDATION_TYPES.NUMBER,\n    name: [\"opts\", \"limit\"],\n  },\n  {\n    title: i18n.t(\"editor.action.panel.label.option.couchdb.include\"),\n    type: \"switch\",\n    name: [\"opts\", \"includeDocs\"],\n    content: i18n.t(\n      \"editor.action.panel.label.option.couchdb.include_doc_option\",\n    ),\n  },\n]\n\nexport const CouchDBMethodsInitialValueMap: Record<string, CouchDBOptionsType> =\n  {\n    listRecords: CouchDBListRecordsInitial,\n    retrieveRecord: CouchDBRetrieveRecordInitial,\n    createRecord: CouchDBCreateRecordInitial,\n    updateRecord: CouchDBUpdateRecordInitial,\n    deleteRecord: CouchDBDeleteRecordInitial,\n    find: CouchDBFindRecordInitial,\n    getView: CouchDBGetViewInitial,\n  }\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/DynamoDBPanel/DeleteItemPanel/index.tsx",
    "content": "import { DynamoDeleteItemStructParams } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport {\n  DynamoDBPanelItemsInfo,\n  DynamoDBSubPanelProps,\n} from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/interface\"\nimport { deleteItemPanelItems } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/items\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const DeleteItemPanel: FC<DynamoDBSubPanelProps> = (props) => {\n  const structParams = props.structParams as DynamoDeleteItemStructParams\n  const { handleValueChange } = props\n\n  return (\n    <>\n      {deleteItemPanelItems.map((info: DynamoDBPanelItemsInfo) => {\n        const { title, name, expectedType } = info\n        return (\n          <InputEditor\n            key={name}\n            lineNumbers\n            style={{ maxHeight: \"88px\" }}\n            value={structParams[name as keyof DynamoDeleteItemStructParams]}\n            onChange={(value) => handleValueChange(value, name)}\n            expectedType={expectedType}\n            title={title}\n          />\n        )\n      })}\n    </>\n  )\n}\nDeleteItemPanel.displayName = \"DeleteItemPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/DynamoDBPanel/GetItemPanel/index.tsx",
    "content": "import { DynamoGetItemStructParams } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport {\n  DynamoDBPanelItemsInfo,\n  DynamoDBSubPanelProps,\n} from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/interface\"\nimport { getItemPanelItems } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/items\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const GetItemPanel: FC<DynamoDBSubPanelProps> = (props) => {\n  const structParams = props.structParams as DynamoGetItemStructParams\n  const { handleValueChange } = props\n\n  return (\n    <>\n      {getItemPanelItems.map((info: DynamoDBPanelItemsInfo) => {\n        const { title, name, expectedType } = info\n        return (\n          <InputEditor\n            key={name}\n            lineNumbers\n            style={{ maxHeight: \"88px\" }}\n            value={structParams[name as keyof DynamoGetItemStructParams]}\n            onChange={(value) => handleValueChange(value, name)}\n            expectedType={expectedType}\n            title={title}\n          />\n        )\n      })}\n    </>\n  )\n}\n\nGetItemPanel.displayName = \"GetItemPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/DynamoDBPanel/PutItemPanel/index.tsx",
    "content": "import { DynamoPutItemStructParams } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport {\n  DynamoDBPanelItemsInfo,\n  DynamoDBSubPanelProps,\n} from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/interface\"\nimport { putItemPanelItems } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/items\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const PutItemPanel: FC<DynamoDBSubPanelProps> = (props) => {\n  const structParams = props.structParams as DynamoPutItemStructParams\n  const { handleValueChange } = props\n\n  return (\n    <>\n      {putItemPanelItems.map((info: DynamoDBPanelItemsInfo) => {\n        const { title, name, expectedType } = info\n        return (\n          <InputEditor\n            key={name}\n            lineNumbers\n            style={{ maxHeight: \"88px\" }}\n            value={structParams[name as keyof DynamoPutItemStructParams]}\n            onChange={(value) => handleValueChange(value, name)}\n            expectedType={expectedType}\n            title={title}\n          />\n        )\n      })}\n    </>\n  )\n}\nPutItemPanel.displayName = \"PutItemPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/DynamoDBPanel/QueryPanel/index.tsx",
    "content": "import { DynamoQueryStructParams } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport {\n  DynamoDBPanelItemsInfo,\n  DynamoDBSubPanelProps,\n} from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/interface\"\nimport { queryPanelItems } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/items\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const QueryPanel: FC<DynamoDBSubPanelProps> = (props) => {\n  const { handleValueChange } = props\n  const structParams = props.structParams as DynamoQueryStructParams\n\n  return (\n    <>\n      {queryPanelItems.map((info: DynamoDBPanelItemsInfo) => {\n        const { title, name, expectedType } = info\n        return (\n          <InputEditor\n            key={name}\n            lineNumbers\n            style={{ maxHeight: \"88px\" }}\n            value={structParams[name as keyof DynamoQueryStructParams]}\n            onChange={(value) => handleValueChange(value, name)}\n            expectedType={expectedType}\n            title={title}\n          />\n        )\n      })}\n    </>\n  )\n}\nQueryPanel.displayName = \"QueryPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/DynamoDBPanel/ScanPanel/index.tsx",
    "content": "import { DynamoScanStructParams } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport {\n  DynamoDBPanelItemsInfo,\n  DynamoDBSubPanelProps,\n} from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/interface\"\nimport { scanPanelItems } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/items\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const ScanPanel: FC<DynamoDBSubPanelProps> = (props) => {\n  const structParams = props.structParams as DynamoScanStructParams\n  const { handleValueChange } = props\n\n  return (\n    <>\n      {scanPanelItems.map((info: DynamoDBPanelItemsInfo) => {\n        const { title, name, expectedType } = info\n        return (\n          <InputEditor\n            key={name}\n            lineNumbers\n            style={{ maxHeight: \"88px\" }}\n            value={structParams[name as keyof DynamoScanStructParams]}\n            onChange={(value) => handleValueChange(value, name)}\n            expectedType={expectedType}\n            title={title}\n          />\n        )\n      })}\n    </>\n  )\n}\nScanPanel.displayName = \"ScanPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/DynamoDBPanel/UpdateItemPanel/index.tsx",
    "content": "import { DynamoUpdateItemStructParams } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport {\n  DynamoDBPanelItemsInfo,\n  DynamoDBSubPanelProps,\n} from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/interface\"\nimport { updateItemPanelItems } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/items\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const UpdateItemPanel: FC<DynamoDBSubPanelProps> = (props) => {\n  const structParams = props.structParams as DynamoUpdateItemStructParams\n  const { handleValueChange } = props\n\n  return (\n    <>\n      {updateItemPanelItems.map((info: DynamoDBPanelItemsInfo) => {\n        const { title, name, expectedType } = info\n        return (\n          <InputEditor\n            key={name}\n            lineNumbers\n            style={{ maxHeight: \"88px\" }}\n            value={structParams[name as keyof DynamoUpdateItemStructParams]}\n            onChange={(value) => handleValueChange(value, name)}\n            expectedType={expectedType}\n            title={title}\n          />\n        )\n      })}\n    </>\n  )\n}\nUpdateItemPanel.displayName = \"UpdateItemPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/DynamoDBPanel/index.tsx",
    "content": "import { DynamoDBInitialMap } from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  DynamoActionMethods,\n  DynamoDBAction,\n  DynamoStructParams,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback, useEffect, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { DeleteItemPanel } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/DeleteItemPanel\"\nimport { GetItemPanel } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/GetItemPanel\"\nimport { PutItemPanel } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/PutItemPanel\"\nimport { QueryPanel } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/QueryPanel\"\nimport { ScanPanel } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/ScanPanel\"\nimport { UpdateItemPanel } from \"@/page/App/components/Actions/ActionPanel/DynamoDBPanel/UpdateItemPanel\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { actionItemContainer } from \"@/page/App/components/Actions/ActionPanel/style\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { fetchResourceMeta } from \"@/services/resource\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst DynamoActionMap = {\n  query: QueryPanel,\n  scan: ScanPanel,\n  getItem: GetItemPanel,\n  putItem: PutItemPanel,\n  updateItem: UpdateItemPanel,\n  deleteItem: DeleteItemPanel,\n}\n\nexport const dynamoDBSelectOptions = [\n  \"query\",\n  \"scan\",\n  \"getItem\",\n  \"putItem\",\n  \"updateItem\",\n  \"deleteItem\",\n]\n\nconst DynamoDBPanel: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const selectedAction = useSelector(getSelectedAction) as ActionItem<\n    DynamoDBAction<DynamoStructParams>\n  >\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    DynamoDBAction<DynamoStructParams>\n  >\n  const content = cachedAction.content\n  const { content: selectedContent } = selectedAction\n\n  const [sqlTable, setSqlTable] = useState<Record<string, unknown>>()\n\n  useEffect(() => {\n    if (cachedAction.resourceID == undefined) return\n    fetchResourceMeta(cachedAction.resourceID).then(({ data }) => {\n      setSqlTable(data?.Schema ?? {})\n    })\n  }, [cachedAction.resourceID])\n\n  const handleValueChange = useCallback(\n    (value: string | boolean, name: string) => {\n      let newContent: DynamoDBAction<DynamoStructParams>\n      if (name === \"method\") {\n        if (value === selectedContent.method) {\n          newContent = { ...selectedContent }\n        } else {\n          newContent = {\n            ...content,\n            method: value as DynamoActionMethods,\n            structParams: {\n              ...DynamoDBInitialMap[value as DynamoActionMethods],\n            },\n          }\n        }\n      } else {\n        newContent = {\n          ...content,\n          [name]: value,\n        }\n      }\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: newContent,\n        }),\n      )\n    },\n    [cachedAction, content, dispatch, selectedContent],\n  )\n\n  const handleStructParamsValueChange = useCallback(\n    (value: string, name: string) => {\n      const { structParams } = content\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            structParams: {\n              ...structParams,\n              [name]: value,\n            },\n          },\n        }),\n      )\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  const PanelComponent = DynamoActionMap[content.method] ?? QueryPanel\n\n  return (\n    <div css={actionItemContainer}>\n      <SingleTypeComponent\n        title={t(\"editor.action.panel.dynamo.label.method\")}\n        componentType=\"select\"\n        onChange={(value) => handleValueChange(value as string, \"method\")}\n        value={content.method}\n        options={dynamoDBSelectOptions}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.dynamo.label.table\")}\n        lineNumbers={false}\n        expectedType={VALIDATION_TYPES.STRING}\n        sqlScheme={sqlTable}\n        mode={CODE_LANG.SQL}\n        value={content.table}\n        onChange={(value) => handleValueChange(value as string, \"table\")}\n      />\n      <SingleTypeComponent\n        title=\"\"\n        componentType=\"checkbox\"\n        value={content.useJson}\n        onChange={(value) => handleValueChange(value as boolean, \"useJson\")}\n        options={dynamoDBSelectOptions}\n        checkoutTitle={t(\"editor.action.panel.dynamo.label.json_input\")}\n      />\n      {content.useJson ? (\n        <InputEditor\n          title={t(\"editor.action.panel.dynamo.label.parameters\")}\n          style={{ height: \"88px\" }}\n          lineNumbers={true}\n          expectedType={VALIDATION_TYPES.STRING}\n          value={content.parameters}\n          placeholder={t(\"editor.action.panel.dynamo.placeholder.parameters\")}\n          onChange={(value) => handleValueChange(value, \"parameters\")}\n        />\n      ) : (\n        <PanelComponent\n          structParams={content.structParams}\n          handleValueChange={handleStructParamsValueChange}\n        />\n      )}\n      <TransformerComponent />\n    </div>\n  )\n}\nDynamoDBPanel.displayName = \"DynamoDBPanel\"\nexport default DynamoDBPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/DynamoDBPanel/interface.ts",
    "content": "import { DynamoStructParams } from \"@illa-public/public-types\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface DynamoDBSubPanelProps {\n  structParams: DynamoStructParams\n  handleValueChange: (value: string, name: string) => void\n}\n\nexport interface DynamoDBPanelItemsInfo {\n  title: string\n  name: string\n  expectedType: VALIDATION_TYPES\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/DynamoDBPanel/items.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const deleteItemPanelItems = [\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.key\"),\n    name: \"key\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.condition_expression\"),\n    name: \"conditionExpression\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_name\"),\n    name: \"expressionAttributeNames\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_value\"),\n    name: \"expressionAttributeValues\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n]\n\nexport const getItemPanelItems = [\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.key\"),\n    name: \"key\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.projection_expression\"),\n    name: \"projectionExpression\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_name\"),\n    name: \"expressionAttributeNames\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n]\n\nexport const putItemPanelItems = [\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.item\"),\n    name: \"item\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.condition_expression\"),\n    name: \"conditionExpression\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_name\"),\n    name: \"expressionAttributeNames\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_value\"),\n    name: \"expressionAttributeValues\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n]\n\nexport const queryPanelItems = [\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.index\"),\n    name: \"indexName\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.key_condition\"),\n    name: \"keyConditionExpression\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.projection_expression\"),\n    name: \"projectionExpression\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.filter_expression\"),\n    name: \"filterExpression\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_name\"),\n    name: \"expressionAttributeNames\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_value\"),\n    name: \"expressionAttributeValues\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.limit\"),\n    name: \"limit\",\n    expectedType: VALIDATION_TYPES.NUMBER,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.select\"),\n    name: \"select\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n]\n\nexport const scanPanelItems = [\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.index\"),\n    name: \"indexName\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.projection_expression\"),\n    name: \"projectionExpression\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.filter_expression\"),\n    name: \"filterExpression\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_name\"),\n    name: \"expressionAttributeNames\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_value\"),\n    name: \"expressionAttributeValues\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.limit\"),\n    name: \"limit\",\n    expectedType: VALIDATION_TYPES.NUMBER,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.select\"),\n    name: \"select\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n]\n\nexport const updateItemPanelItems = [\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.key\"),\n    name: \"key\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.update_expression\"),\n    name: \"updateExpression\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.condition_expression\"),\n    name: \"conditionExpression\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_name\"),\n    name: \"expressionAttributeNames\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n  {\n    title: i18n.t(\"editor.action.panel.dynamo.label.attribute_value\"),\n    name: \"expressionAttributeValues\",\n    expectedType: VALIDATION_TYPES.OBJECT,\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ElasticSearchPanel/index.tsx",
    "content": "import {\n  ElasticSearchBodyContentType,\n  ElasticSearchIDEditorType,\n  ElasticSearchQueryContentType,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  ElasticSearchAction,\n  ElasticSearchActionRequestType,\n  ElasticSearchActionType,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { SelectValue } from \"@illa-design/react\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { actionItemContainer } from \"./style\"\n\nconst esActionOptions = [\n  {\n    label: ElasticSearchActionType.SEARCH,\n    value: ElasticSearchActionRequestType.SEARCH,\n  },\n  {\n    label: ElasticSearchActionType.GET_ONE,\n    value: ElasticSearchActionRequestType.GET_ONE,\n  },\n  {\n    label: ElasticSearchActionType.INSERT_ONE,\n    value: ElasticSearchActionRequestType.INSERT_ONE,\n  },\n  {\n    label: ElasticSearchActionType.UPDATE_ONE,\n    value: ElasticSearchActionRequestType.UPDATE_ONE,\n  },\n  {\n    label: ElasticSearchActionType.DELETE_ONE,\n    value: ElasticSearchActionRequestType.DELETE_ONE,\n  },\n]\n\nconst ElasticSearchPanel: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(\n    getCachedAction,\n  ) as ActionItem<ElasticSearchAction>\n\n  const selectedAction = useSelector(getSelectedAction)!!\n  let content = cachedAction.content as ElasticSearchAction\n\n  const isShowID = useMemo(\n    () => ElasticSearchIDEditorType.includes(cachedAction.content.operation),\n    [cachedAction.content],\n  )\n  const isBodyContent = useMemo(\n    () => ElasticSearchBodyContentType.includes(cachedAction.content.operation),\n    [cachedAction.content],\n  )\n  const isQueryContent = useMemo(\n    () =>\n      ElasticSearchQueryContentType.includes(cachedAction.content.operation),\n    [cachedAction.content],\n  )\n\n  const handleValueChange = useCallback(\n    (key: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            [key]: value,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch],\n  )\n\n  const handleSelectedValueChange = useCallback(\n    (value: SelectValue) => {\n      const content = {\n        operation: value,\n        index: cachedAction.content.index,\n      } as ElasticSearchAction\n      if (\n        cachedAction.resourceID === selectedAction.resourceID &&\n        (selectedAction.content as ElasticSearchAction).operation === value\n      ) {\n        if (isShowID) {\n          content[\"id\"] =\n            (selectedAction.content as ElasticSearchAction)?.id || \"\"\n        }\n        if (isBodyContent) {\n          content[\"body\"] =\n            (selectedAction.content as ElasticSearchAction)?.body || \"\"\n        }\n        if (isQueryContent) {\n          content[\"query\"] =\n            (selectedAction.content as ElasticSearchAction)?.query || \"\"\n        }\n      }\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content,\n        }),\n      )\n    },\n    [\n      cachedAction,\n      dispatch,\n      isBodyContent,\n      isQueryContent,\n      isShowID,\n      selectedAction.content,\n      selectedAction.resourceID,\n    ],\n  )\n\n  return (\n    <div css={actionItemContainer}>\n      <SingleTypeComponent\n        componentType=\"select\"\n        value={content.operation}\n        title={t(\"editor.action.panel.elastic.action_type\")}\n        options={esActionOptions}\n        onSelectedValueChange={handleSelectedValueChange}\n      />\n      {isBodyContent && (\n        <InputEditor\n          value={content.body ?? \"\"}\n          onChange={handleValueChange(\"body\")}\n          title={t(\"editor.action.panel.elastic.body\")}\n          lineNumbers\n          style={{ height: \"88px\" }}\n          expectedType={VALIDATION_TYPES.STRING}\n          mode={CODE_LANG.JAVASCRIPT}\n          codeType={CODE_TYPE.EXPRESSION}\n          canShowCompleteInfo\n        />\n      )}\n      {isQueryContent && (\n        <InputEditor\n          value={content.query ?? \"\"}\n          onChange={handleValueChange(\"query\")}\n          title={t(\"editor.action.panel.elastic.query\")}\n          lineNumbers\n          expectedType={VALIDATION_TYPES.STRING}\n          mode={CODE_LANG.JAVASCRIPT}\n          style={{ height: \"88px\" }}\n          codeType={CODE_TYPE.EXPRESSION}\n          canShowCompleteInfo\n        />\n      )}\n      <InputEditor\n        value={content.index}\n        onChange={handleValueChange(\"index\")}\n        title={t(\"editor.action.panel.elastic.index\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n      />\n      {isShowID && (\n        <InputEditor\n          value={content.id ?? \"\"}\n          onChange={handleValueChange(\"id\")}\n          title={t(\"editor.action.panel.elastic.id\")}\n          expectedType={VALIDATION_TYPES.STRING}\n          mode={CODE_LANG.JAVASCRIPT}\n          codeType={CODE_TYPE.EXPRESSION}\n          canShowCompleteInfo\n        />\n      )}\n      <TransformerComponent />\n    </div>\n  )\n}\n\nElasticSearchPanel.displayName = \"ElasticSearchPanel\"\nexport default ElasticSearchPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ElasticSearchPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const esItemStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 48px;\n  padding: 0 16px;\n`\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n\nexport const esItemLabelStyle = css`\n  min-width: 160px;\n  font-size: 14px;\n  font-weight: 500;\n  text-align: right;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/AppendDataToList/index.tsx",
    "content": "import { FirebaseSetData } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const AppendDataToListPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const { handleValueChange } = props\n  const options = props.options as FirebaseSetData\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.database_ref\")}\n        value={options.ref}\n        onChange={(value) => handleValueChange(value, \"ref\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.object_to_set\")}\n        value={options.object}\n        onChange={(value) => handleValueChange(value, \"object\")}\n        expectedType={VALIDATION_TYPES.OBJECT}\n      />\n    </>\n  )\n}\n\nAppendDataToListPart.displayName = \"AppendDataToListPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/CreateOneUser/index.tsx",
    "content": "import { FirebaseCreateUser } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const CreateOneUserPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseCreateUser\n  const { handleValueChange } = props\n\n  return (\n    <InputEditor\n      lineNumbers\n      style={{ height: \"88px\" }}\n      title={t(\"editor.action.panel.firebase.user_object\")}\n      value={options.object}\n      onChange={(value) => handleValueChange(value, \"object\")}\n      expectedType={VALIDATION_TYPES.OBJECT}\n    />\n  )\n}\n\nCreateOneUserPart.displayName = \"CreateOneUserPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/DeleteOneDocument/index.tsx",
    "content": "import {\n  FirebaseCollectionType,\n  FirebaseDeleteDocument,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CollectionInput } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionInput\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DeleteOneDocumentPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseDeleteDocument\n  const { handleValueChange } = props\n\n  return (\n    <>\n      <CollectionInput\n        handleValueChange={handleValueChange}\n        value={options.collection}\n        collectionType={options.collectionType as FirebaseCollectionType}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.document_id\")}\n        value={options.id}\n        onChange={(value) => handleValueChange(value, \"id\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n    </>\n  )\n}\n\nDeleteOneDocumentPart.displayName = \"DeleteOneDocumentPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/DeleteOneUser/index.tsx",
    "content": "import { FirebaseDeleteOneUser } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DeleteOneUserPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseDeleteOneUser\n  const { handleValueChange } = props\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.firebase.uid\")}\n      value={options.filter}\n      onChange={(value) => handleValueChange(value, \"filter\")}\n      expectedType={VALIDATION_TYPES.STRING}\n    />\n  )\n}\n\nDeleteOneUserPart.displayName = \"DeleteOneUserPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/FirebasePanel.tsx",
    "content": "import {\n  FirebaseInitialValue,\n  FirebaseServiceTypeInitialValue,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  FirebaseAction,\n  FirebaseActionTypeValue,\n  FirebaseAuthActionTypeValue,\n  FirebaseCheckboxParams,\n  FirebaseContentType,\n  FirebaseRealtimeActionTypeValue,\n  FirebaseServiceTypeValue,\n  FirebaseStoreActionTypeValue,\n  FirebaseWhere,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { SelectValue } from \"@illa-design/react\"\nimport { AppendDataToListPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/AppendDataToList\"\nimport { CreateOneUserPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/CreateOneUser\"\nimport { DeleteOneDocumentPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/DeleteOneDocument\"\nimport { DeleteOneUserPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/DeleteOneUser\"\nimport { GetCollectionsPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/GetCollections\"\nimport { GetDocumentByIDPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/GetDocumentByID\"\nimport { GetUserByEmailPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/GetUserByEmail\"\nimport { GetUserByIDPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/GetUserByID\"\nimport { GetUserByPhonePart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/GetUserByPhone\"\nimport { InsertDocumentPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/InsertDocument\"\nimport { ListUsersPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/ListUsers\"\nimport { QueryCollectionGroupPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/QueryCollectionGroup\"\nimport { QueryDatabasePart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/QueryDatabase\"\nimport { QueryFirebasePart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/QueryFirebase\"\nimport { SetDataPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/SetData\"\nimport { UpdateDataPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/UpdateData\"\nimport { UpdateDocumentPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/UpdateDocument\"\nimport { UpdateOneUserPart } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/UpdateOneUser\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { ActionTypeList, firebaseServiceTypeOptions } from \"./constants\"\nimport { actionItemContainer } from \"./style\"\n\nexport const FirebasePanel: FC = () => {\n  const { t } = useTranslation()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    FirebaseAction<FirebaseContentType>\n  >\n  const selectedAction = useSelector(getSelectedAction)!\n  const selectedContent =\n    selectedAction.content as FirebaseAction<FirebaseContentType>\n  const content = cachedAction.content as FirebaseAction<FirebaseContentType>\n  const options = content.options as FirebaseContentType\n  const dispatch = useDispatch()\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: SelectValue) => {\n      const valueString = value as string\n      switch (name) {\n        case \"operation\":\n          let options =\n            FirebaseInitialValue[valueString as FirebaseActionTypeValue]\n          if (\n            content.service === selectedContent.service &&\n            selectedContent.operation === valueString\n          ) {\n            options = selectedContent.options\n          }\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...cachedAction.content,\n                operation: valueString,\n                options,\n              },\n            }),\n          )\n          break\n        case \"service\":\n          const initialOptions =\n            FirebaseServiceTypeInitialValue[\n              valueString as FirebaseServiceTypeValue\n            ]\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                operation: \"\",\n                service: valueString as FirebaseServiceTypeValue,\n                options: initialOptions,\n              },\n            }),\n          )\n      }\n    },\n    [dispatch, cachedAction, content, selectedContent],\n  )\n\n  const handleOptionsValueChange = useCallback(\n    (\n      value: string | boolean | FirebaseWhere[] | FirebaseCheckboxParams,\n      name: string,\n    ) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            options: {\n              ...options,\n              [name]: value,\n            },\n          },\n        }),\n      )\n    },\n    [dispatch, cachedAction, options],\n  )\n\n  const renderInputBody = useMemo(() => {\n    const props = {\n      options: content.options,\n      handleValueChange: handleOptionsValueChange,\n    }\n    switch (content.operation) {\n      case FirebaseAuthActionTypeValue.GET_USER_BY_UID:\n        return <GetUserByIDPart {...props} />\n      case FirebaseAuthActionTypeValue.DELETE_ONE_USER:\n        return <DeleteOneUserPart {...props} />\n      case FirebaseAuthActionTypeValue.GET_USER_BY_EMAIL:\n        return <GetUserByEmailPart {...props} />\n      case FirebaseAuthActionTypeValue.GET_USER_BY_PHONE:\n        return <GetUserByPhonePart {...props} />\n      case FirebaseAuthActionTypeValue.CREATE_ONE_USER:\n        return <CreateOneUserPart {...props} />\n      case FirebaseAuthActionTypeValue.UPDATE_ONE_USER:\n        return <UpdateOneUserPart {...props} />\n      case FirebaseAuthActionTypeValue.LIST_USERS:\n        return <ListUsersPart {...props} />\n      case FirebaseStoreActionTypeValue.QUERY_FIREBASE:\n        return <QueryFirebasePart {...props} />\n      case FirebaseStoreActionTypeValue.INSERT_DOCUMENT:\n        return <InsertDocumentPart {...props} />\n      case FirebaseStoreActionTypeValue.UPDATE_DOCUMENT:\n        return <UpdateDocumentPart {...props} />\n      case FirebaseStoreActionTypeValue.GET_DOCUMENT_BY_ID:\n        return <GetDocumentByIDPart {...props} />\n      case FirebaseStoreActionTypeValue.DELETE_ONE_DOCUMENT:\n        return <DeleteOneDocumentPart {...props} />\n      case FirebaseStoreActionTypeValue.GET_COLLECTIONS:\n        return <GetCollectionsPart {...props} />\n      case FirebaseStoreActionTypeValue.QUERY_COLLECTION_GROUP:\n        return <QueryCollectionGroupPart {...props} />\n      case FirebaseRealtimeActionTypeValue.QUERY_DATABASE:\n        return <QueryDatabasePart {...props} />\n      case FirebaseRealtimeActionTypeValue.SET_DATA:\n        return <SetDataPart {...props} />\n      case FirebaseRealtimeActionTypeValue.UPDATE_DATA:\n        return <UpdateDataPart {...props} />\n      case FirebaseRealtimeActionTypeValue.APPEND_DATA_TO_LIST:\n        return <AppendDataToListPart {...props} />\n    }\n  }, [content.operation, content.options, handleOptionsValueChange])\n\n  return (\n    <div css={actionItemContainer}>\n      <SingleTypeComponent\n        title={t(\"editor.action.panel.firebase.service_type\")}\n        componentType=\"select\"\n        value={content.service}\n        showSearch\n        options={firebaseServiceTypeOptions}\n        onSelectedValueChange={handleValueChange(\"service\")}\n      />\n      <SingleTypeComponent\n        title={t(\"editor.action.panel.firebase.action_type\")}\n        componentType=\"select\"\n        showSearch={true}\n        value={content.operation}\n        placeholder={t(\n          \"editor.action.panel.firebase.placeholder.select_an_action\",\n        )}\n        options={ActionTypeList[content.service]}\n        onSelectedValueChange={handleValueChange(\"operation\")}\n      />\n      {renderInputBody}\n      <TransformerComponent />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/GetCollections/index.tsx",
    "content": "import { FirebaseGetCollections } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const GetCollectionsPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseGetCollections\n  const { handleValueChange } = props\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.firebase.parent_document_id\")}\n      value={options.parent}\n      onChange={(value) => handleValueChange(value, \"parent\")}\n      expectedType={VALIDATION_TYPES.STRING}\n      tips={t(\"editor.action.panel.firebase.tips.parent_document_id_tips\")}\n    />\n  )\n}\n\nGetCollectionsPart.displayName = \"GetCollectionsPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/GetDocumentByID/index.tsx",
    "content": "import {\n  FirebaseCollectionType,\n  FirebaseGetDocumentByID,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CollectionInput } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionInput\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const GetDocumentByIDPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseGetDocumentByID\n  const { handleValueChange } = props\n\n  return (\n    <>\n      <CollectionInput\n        handleValueChange={handleValueChange}\n        value={options.collection}\n        collectionType={options.collectionType as FirebaseCollectionType}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.document_id\")}\n        value={options.id}\n        onChange={(value) => handleValueChange(value, \"id\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n    </>\n  )\n}\n\nGetDocumentByIDPart.displayName = \"GetDocumentByIDPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/GetUserByEmail/index.tsx",
    "content": "import { FirebaseGetUserByEmail } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const GetUserByEmailPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseGetUserByEmail\n  const { handleValueChange } = props\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.firebase.email\")}\n      value={options.filter}\n      onChange={(value) => handleValueChange(value, \"filter\")}\n      expectedType={VALIDATION_TYPES.STRING}\n    />\n  )\n}\n\nGetUserByEmailPart.displayName = \"GetUserByEmailPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/GetUserByID/index.tsx",
    "content": "import {\n  FirebaseDeleteOneUser,\n  FirebaseGetUserByID,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const GetUserByIDPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseGetUserByID | FirebaseDeleteOneUser\n  const { handleValueChange } = props\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.firebase.uid\")}\n      value={options.filter}\n      onChange={(value) => handleValueChange(value, \"filter\")}\n      expectedType={VALIDATION_TYPES.STRING}\n    />\n  )\n}\n\nGetUserByIDPart.displayName = \"GetUserByIDPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/GetUserByPhone/index.tsx",
    "content": "import { FirebaseGetUserByPhone } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const GetUserByPhonePart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseGetUserByPhone\n  const { handleValueChange } = props\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.firebase.phone_number\")}\n      value={options.filter}\n      onChange={(value) => handleValueChange(value, \"filter\")}\n      expectedType={VALIDATION_TYPES.STRING}\n    />\n  )\n}\n\nGetUserByPhonePart.displayName = \"GetUserByPhonePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/InsertDocument/index.tsx",
    "content": "import {\n  FirebaseCollectionType,\n  FirebaseInsertDocument,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CollectionInput } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionInput\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const InsertDocumentPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseInsertDocument\n  const { handleValueChange } = props\n\n  return (\n    <>\n      <CollectionInput\n        handleValueChange={handleValueChange}\n        value={options.collection}\n        collectionType={options.collectionType as FirebaseCollectionType}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.document_id\")}\n        value={options.id}\n        onChange={(value) => handleValueChange(value, \"id\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        tips={t(\"editor.action.panel.firebase.tips.document_id\")}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.value\")}\n        value={options.value}\n        onChange={(value) => handleValueChange(value, \"value\")}\n        expectedType={VALIDATION_TYPES.OBJECT}\n        placeholder={t(\n          \"editor.action.panel.firebase.placeholder.document_value\",\n        )}\n      />\n    </>\n  )\n}\n\nInsertDocumentPart.displayName = \"InsertDocumentPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/ListUsers/index.tsx",
    "content": "import { FirebaseListUsers } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const ListUsersPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseListUsers\n  const { handleValueChange } = props\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.len_of_list\")}\n        value={options.number}\n        onChange={(value) => handleValueChange(value, \"number\")}\n        expectedType={VALIDATION_TYPES.NUMBER}\n        placeholder={\"{{1000}}\"}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.next_page_token\")}\n        value={options.token}\n        onChange={(value) => handleValueChange(value, \"token\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n    </>\n  )\n}\n\nListUsersPart.displayName = \"ListUsersPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/QueryCollectionGroup/index.tsx",
    "content": "import {\n  FirebaseCollectionType,\n  FirebaseQueryCollectionGroup,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CollectionInput } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionInput\"\nimport { CollectionRecordEditor } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionRecordEditor\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { CheckboxInput } from \"@/page/App/components/Actions/CheckboxInput\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const QueryCollectionGroupPart: FC<FirebaseActionPartProps> = (\n  props,\n) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseQueryCollectionGroup\n  const { handleValueChange } = props\n\n  return (\n    <>\n      <CollectionInput\n        handleValueChange={handleValueChange}\n        value={options.collection}\n        collectionType={options.collectionType as FirebaseCollectionType}\n      />\n      <CollectionRecordEditor\n        name={\"where\"}\n        handleValueChange={handleValueChange}\n        defaultValue={options.where}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.limit\")}\n        value={options.limit}\n        onChange={(value) => handleValueChange(value, \"limit\")}\n        expectedType={VALIDATION_TYPES.NUMBER}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.order_by\")}\n        value={options.orderBy}\n        onChange={(value) => handleValueChange(value, \"orderBy\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.ordering_direction\")}\n        value={options.orderDirection}\n        onChange={(value) => handleValueChange(value, \"orderDirection\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={t(\"editor.action.panel.firebase.placeholder.asc\")}\n      />\n      <CheckboxInput\n        checkboxTitle={t(\"editor.action.panel.firebase.use_start_at\")}\n        checkboxValue={options.startAt.trigger}\n        onCheckboxChange={(value) =>\n          handleValueChange(\n            {\n              value: options.startAt.value,\n              trigger: value,\n            },\n            \"startAt\",\n          )\n        }\n        inputTitle={t(\"editor.action.panel.firebase.start_at\")}\n        inputValue={options.startAt.value}\n        onValueChange={(value) =>\n          handleValueChange(\n            {\n              trigger: options.startAt.trigger,\n              value,\n            },\n            \"startAt\",\n          )\n        }\n        hasExpectedType={false}\n      />\n      <CheckboxInput\n        checkboxTitle={t(\"editor.action.panel.firebase.use_end_at\")}\n        checkboxValue={options.endAt.trigger}\n        onCheckboxChange={(value) =>\n          handleValueChange(\n            {\n              value: options.endAt.value,\n              trigger: value,\n            },\n            \"endAt\",\n          )\n        }\n        inputTitle={t(\"editor.action.panel.firebase.end_at\")}\n        inputValue={options.endAt.value}\n        onValueChange={(value) =>\n          handleValueChange(\n            {\n              trigger: options.endAt.trigger,\n              value,\n            },\n            \"endAt\",\n          )\n        }\n        hasExpectedType={false}\n      />\n    </>\n  )\n}\n\nQueryCollectionGroupPart.displayName = \"QueryCollectionGroupPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/QueryDatabase/index.tsx",
    "content": "import { FirebaseQueryDatabase } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const QueryDatabasePart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseQueryDatabase\n  const { handleValueChange } = props\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.firebase.database_ref\")}\n      value={options.ref}\n      onChange={(value) => handleValueChange(value, \"ref\")}\n      expectedType={VALIDATION_TYPES.STRING}\n    />\n  )\n}\n\nQueryDatabasePart.displayName = \"QueryDatabasePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/QueryFirebase/index.tsx",
    "content": "import {\n  FirebaseCollectionType,\n  QueryFirebase,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CollectionInput } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionInput\"\nimport { CollectionRecordEditor } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionRecordEditor\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { checkboxContainer } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/style\"\nimport { CheckboxInput } from \"@/page/App/components/Actions/CheckboxInput\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const QueryFirebasePart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as QueryFirebase\n  const { handleValueChange } = props\n\n  return (\n    <>\n      <CollectionInput\n        handleValueChange={handleValueChange}\n        value={options.collection}\n        collectionType={options.collectionType as FirebaseCollectionType}\n      />\n      <CollectionRecordEditor\n        name=\"where\"\n        handleValueChange={handleValueChange}\n        defaultValue={options.where}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.limit\")}\n        value={options.limit}\n        onChange={(value) => handleValueChange(value, \"limit\")}\n        expectedType={VALIDATION_TYPES.NUMBER}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.order_by\")}\n        value={options.orderBy}\n        onChange={(value) => handleValueChange(value, \"orderBy\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.ordering_direction\")}\n        value={options.orderDirection}\n        onChange={(value) => handleValueChange(value, \"orderDirection\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={t(\"editor.action.panel.firebase.placeholder.asc\")}\n      />\n      <div css={checkboxContainer}>\n        <CheckboxInput\n          checkboxTitle={t(\"editor.action.panel.firebase.use_start_at\")}\n          checkboxValue={options.startAt.trigger}\n          onCheckboxChange={(value) =>\n            handleValueChange(\n              {\n                value: options.startAt.value,\n                trigger: value,\n              },\n              \"startAt\",\n            )\n          }\n          inputTitle={t(\"editor.action.panel.firebase.start_at\")}\n          inputValue={options.startAt.value}\n          onValueChange={(value) =>\n            handleValueChange(\n              {\n                trigger: options.startAt.trigger,\n                value,\n              },\n              \"startAt\",\n            )\n          }\n          hasExpectedType={false}\n        />\n        <CheckboxInput\n          checkboxTitle={t(\"editor.action.panel.firebase.use_end_at\")}\n          checkboxValue={options.endAt.trigger}\n          onCheckboxChange={(value) =>\n            handleValueChange(\n              {\n                value: options.endAt.value,\n                trigger: value,\n              },\n              \"endAt\",\n            )\n          }\n          inputTitle={t(\"editor.action.panel.firebase.end_at\")}\n          inputValue={options.endAt.value}\n          onValueChange={(value) =>\n            handleValueChange(\n              {\n                trigger: options.endAt.trigger,\n                value,\n              },\n              \"endAt\",\n            )\n          }\n          hasExpectedType={false}\n        />\n      </div>\n    </>\n  )\n}\n\nQueryFirebasePart.displayName = \"QueryFirebasePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/SetData/index.tsx",
    "content": "import { FirebaseSetData } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const SetDataPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseSetData\n  const { handleValueChange } = props\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.database_ref\")}\n        value={options.ref}\n        onChange={(value) => handleValueChange(value, \"ref\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.object_to_set\")}\n        value={options.object}\n        onChange={(value) => handleValueChange(value, \"object\")}\n        expectedType={VALIDATION_TYPES.OBJECT}\n      />\n    </>\n  )\n}\n\nSetDataPart.displayName = \"SetDataPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/UpdateData/index.tsx",
    "content": "import { FirebaseUpdateData } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const UpdateDataPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseUpdateData\n  const { handleValueChange } = props\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.database_ref\")}\n        value={options.ref}\n        onChange={(value) => handleValueChange(value, \"ref\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.object_to_set\")}\n        value={options.object}\n        onChange={(value) => handleValueChange(value, \"object\")}\n        expectedType={VALIDATION_TYPES.OBJECT}\n      />\n    </>\n  )\n}\n\nUpdateDataPart.displayName = \"UpdateDataPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/UpdateDocument/index.tsx",
    "content": "import {\n  FirebaseCollectionType,\n  FirebaseUpdateDocument,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CollectionInput } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionInput\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const UpdateDocumentPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseUpdateDocument\n  const { handleValueChange } = props\n\n  return (\n    <>\n      <CollectionInput\n        handleValueChange={handleValueChange}\n        value={options.collection}\n        collectionType={options.collectionType as FirebaseCollectionType}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.document_id\")}\n        value={options.id}\n        onChange={(value) => handleValueChange(value, \"id\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.value\")}\n        value={options.value}\n        onChange={(value) => handleValueChange(value, \"value\")}\n        expectedType={VALIDATION_TYPES.OBJECT}\n      />\n    </>\n  )\n}\n\nUpdateDocumentPart.displayName = \"UpdateDocumentPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/UpdateOneUser/index.tsx",
    "content": "import { FirebaseUpdateOneUser } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FirebaseActionPartProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/intreface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const UpdateOneUserPart: FC<FirebaseActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const options = props.options as FirebaseUpdateOneUser\n  const { handleValueChange } = props\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.firebase.uid\")}\n        value={options.uid}\n        onChange={(value) => handleValueChange(value, \"uid\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        lineNumbers\n        style={{ height: \"88px\" }}\n        title={t(\"editor.action.panel.firebase.user_object\")}\n        value={options.object}\n        onChange={(value) => handleValueChange(value, \"object\")}\n        expectedType={VALIDATION_TYPES.OBJECT}\n      />\n    </>\n  )\n}\n\nUpdateOneUserPart.displayName = \"UpdateOneUserPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionInput/index.tsx",
    "content": "import { FirebaseCollectionType } from \"@illa-public/public-types\"\nimport { FC, useCallback, useEffect, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { Select } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { CollectionInputProps } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionInput/interface\"\nimport {\n  actionBodyTypeStyle,\n  actionItemCodeEditorStyle,\n  actionItemLabelStyle,\n  actionItemStyle,\n} from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/style\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { fetchResourceMeta } from \"@/services/resource\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const CollectionInput: FC<CollectionInputProps> = (props) => {\n  const { t } = useTranslation()\n  const { handleValueChange, collectionType, value } = props\n  const isDropdown = collectionType === FirebaseCollectionType.DROPDOWN\n  const action = useSelector(getCachedAction)!\n\n  const [collectionSelect, setCollectionSelect] = useState<string[]>([])\n\n  const handleCollectionTypeChange = useCallback(() => {\n    const contentType = isDropdown\n      ? FirebaseCollectionType.RAW\n      : FirebaseCollectionType.DROPDOWN\n    handleValueChange(contentType, \"collectionType\")\n  }, [handleValueChange, isDropdown])\n\n  const handleChange = (value: string) => handleValueChange(value, \"collection\")\n\n  useEffect(() => {\n    if (action.resourceID == undefined) return\n    fetchResourceMeta(action.resourceID).then(({ data }) => {\n      let tables: string[] = []\n      if (data.Schema) {\n        tables = (data.Schema.collections || []) as string[]\n      }\n      setCollectionSelect(tables)\n    })\n  }, [action.resourceID])\n\n  return (\n    <div css={actionItemStyle}>\n      <span css={actionItemLabelStyle}>\n        {t(\"editor.action.panel.firebase.collection\")}\n        <span css={actionBodyTypeStyle} onClick={handleCollectionTypeChange}>\n          {isDropdown\n            ? t(\"editor.action.panel.firebase.use_raw_id\")\n            : t(\"editor.action.panel.firebase.use_a_dropdown\")}\n        </span>\n      </span>\n      {isDropdown ? (\n        <Select\n          colorScheme=\"techPurple\"\n          showSearch={true}\n          defaultValue={value}\n          value={value}\n          ml=\"16px\"\n          w=\"100%\"\n          placeholder={t(\n            \"editor.action.panel.firebase.placeholder.select_collection\",\n          )}\n          onChange={(v) => {\n            handleChange(v as string)\n          }}\n          options={collectionSelect}\n        />\n      ) : (\n        <div css={actionItemCodeEditorStyle}>\n          <CodeEditor\n            value={value}\n            singleLine\n            onChange={handleChange}\n            expectValueType={VALIDATION_TYPES.STRING}\n            lang={CODE_LANG.JAVASCRIPT}\n            codeType={CODE_TYPE.EXPRESSION}\n            canShowCompleteInfo\n            placeholder={t(\n              \"editor.action.panel.firebase.placeholder.input_collection\",\n            )}\n          />\n        </div>\n      )}\n    </div>\n  )\n}\n\nCollectionInput.displayName = \"CollectionInput\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionInput/interface.ts",
    "content": "import { FirebaseCollectionType } from \"@illa-public/public-types\"\n\nexport interface CollectionInputProps {\n  handleValueChange: (value: string, name: string) => void\n  collectionType: FirebaseCollectionType\n  value: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionRecordEditor/constants.ts",
    "content": "enum OperationType {\n  EQUAL = \"==\",\n  GREATER = \">\",\n  LESS = \"<\",\n  LESS_EQUAL = \"<=\",\n  GREATER_EQUAL = \">=\",\n  CONTAINS = \"contains\",\n  IN = \"in\",\n  CONTAINS_ANY = \"array contains any\",\n}\n\nenum OperationTypeValue {\n  EQUAL = \"==\",\n  GREATER = \">\",\n  LESS = \"<\",\n  LESS_EQUAL = \"<=\",\n  GREATER_EQUAL = \">=\",\n  CONTAINS = \"array-contains\",\n  IN = \"in\",\n  CONTAINS_ANY = \"array-contains-any\",\n}\n\nexport const OperationSelectList = [\n  {\n    label: OperationType.EQUAL,\n    value: OperationTypeValue.EQUAL,\n  },\n  {\n    label: OperationType.GREATER,\n    value: OperationTypeValue.GREATER,\n  },\n  {\n    label: OperationType.LESS,\n    value: OperationTypeValue.LESS,\n  },\n  {\n    label: OperationType.LESS_EQUAL,\n    value: OperationTypeValue.LESS_EQUAL,\n  },\n  {\n    label: OperationType.GREATER_EQUAL,\n    value: OperationTypeValue.GREATER_EQUAL,\n  },\n  {\n    label: OperationType.CONTAINS,\n    value: OperationTypeValue.CONTAINS,\n  },\n  {\n    label: OperationType.IN,\n    value: OperationTypeValue.IN,\n  },\n  {\n    label: OperationType.CONTAINS_ANY,\n    value: OperationTypeValue.CONTAINS_ANY,\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionRecordEditor/index.tsx",
    "content": "import { FirebaseWhere } from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { Controller, useForm } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { Select } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { RecordEditor } from \"@/components/RecordEditor\"\nimport {\n  codeMirrorWrapperLabelStyle,\n  codeMirrorWrapperValueStyle,\n} from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionRecordEditor/style\"\nimport { actionItemRecordEditorStyle } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/style\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { OperationSelectList } from \"./constants\"\nimport { CollectionRecordEditorProps } from \"./interface\"\n\nexport const CollectionRecordEditor: FC<CollectionRecordEditorProps> = (\n  props,\n) => {\n  const { t } = useTranslation()\n\n  const { defaultValue, handleValueChange, name } = props\n  const { control, getValues } = useForm({\n    mode: \"onChange\",\n    shouldUnregister: true,\n  })\n\n  const handleChange = useCallback(\n    (\n      index: number,\n      key: string,\n      v: string,\n      operation: string,\n      onChange: (...event: any[]) => void,\n    ) => {\n      const value = getValues()[name]\n      let newRecords: FirebaseWhere[] = [...value]\n      const curOperation = operation || newRecords[index].condition || \"\"\n      newRecords[index] = {\n        field: key,\n        value: v,\n        condition: curOperation,\n      }\n      onChange(newRecords)\n      handleValueChange(newRecords, \"where\")\n    },\n    [handleValueChange, getValues, name],\n  )\n\n  return (\n    <Controller\n      control={control}\n      defaultValue={defaultValue}\n      render={({ field: { value, onChange } }) => {\n        return (\n          <RecordEditor\n            label={t(\"editor.action.panel.firebase.where\")}\n            records={value}\n            customRender={(record, index) => (\n              <>\n                <div css={actionItemRecordEditorStyle}>\n                  <CodeEditor\n                    value={record.field}\n                    singleLine\n                    onChange={(val) => {\n                      handleChange(\n                        index,\n                        val,\n                        record.value,\n                        record.operation,\n                        onChange,\n                      )\n                    }}\n                    wrapperCss={codeMirrorWrapperLabelStyle}\n                    expectValueType={VALIDATION_TYPES.STRING}\n                    lang={CODE_LANG.JAVASCRIPT}\n                    codeType={CODE_TYPE.EXPRESSION}\n                    canShowCompleteInfo\n                    placeholder=\"field\"\n                  />\n                </div>\n                <Select\n                  colorScheme=\"techPurple\"\n                  showSearch={true}\n                  defaultValue={record.condition}\n                  value={record.condition}\n                  w=\"0\"\n                  ml=\"-1px\"\n                  mr=\"-1px\"\n                  bdRadius=\"0\"\n                  flexGrow=\"1\"\n                  onChange={(val) =>\n                    handleChange(\n                      index,\n                      record.field,\n                      record.value,\n                      val as string,\n                      onChange,\n                    )\n                  }\n                  options={OperationSelectList}\n                />\n                <div css={actionItemRecordEditorStyle}>\n                  <CodeEditor\n                    singleLine\n                    value={record.value}\n                    onChange={(val) => {\n                      handleChange(\n                        index,\n                        record.field,\n                        val,\n                        record.condition,\n                        onChange,\n                      )\n                    }}\n                    wrapperCss={codeMirrorWrapperValueStyle}\n                    lang={CODE_LANG.JAVASCRIPT}\n                    codeType={CODE_TYPE.EXPRESSION}\n                    canShowCompleteInfo\n                    placeholder=\"value\"\n                  />\n                </div>\n              </>\n            )}\n            onAdd={() => {\n              onChange([...value, { field: \"\", value: \"\", condition: \"\" }])\n            }}\n            onDelete={(index, _record) => {\n              let newRecords = [...value]\n              newRecords.splice(index, 1)\n              if (newRecords.length === 0) {\n                newRecords = [{ field: \"\", value: \"\", condition: \"\" }]\n              }\n              onChange(newRecords)\n            }}\n            onChangeKey={(index, key, v) =>\n              handleChange(index, key, v, \"\", onChange)\n            }\n            onChangeValue={(index, key, v) =>\n              handleChange(index, key, v, \"\", onChange)\n            }\n          />\n        )\n      }}\n      name={name}\n    />\n  )\n}\n\nCollectionRecordEditor.displayName = \"CollectionRecordEditor\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionRecordEditor/interface.ts",
    "content": "import { FirebaseWhere } from \"@illa-public/public-types\"\n\nexport interface CollectionRecordEditorProps {\n  defaultValue: FirebaseWhere[]\n  name: string\n  handleValueChange: (value: FirebaseWhere[], name: string) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionRecordEditor/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const codeMirrorWrapperLabelStyle = css`\n  .cm-editor {\n    border-radius: 8px 0 0 8px;\n  }\n`\nexport const codeMirrorWrapperValueStyle = css`\n  .cm-editor {\n    border-radius: 0;\n  }\n`\n\nexport const selectContainerStyle = css`\n  width: 100%;\n  position: relative;\n  z-index: 1;\n  overflow: hidden;\n  height: 100%;\n  &:hover {\n    overflow: visible;\n  }\n  & > div {\n    position: absolute;\n    left: -1px;\n    right: -1px;\n    top: 8px;\n    bottom: 8px;\n    width: auto;\n    z-index: 2;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/constants.ts",
    "content": "import {\n  FirebaseAuthActionTypeValue,\n  FirebaseRealtimeActionTypeValue,\n  FirebaseServiceTypeValue,\n  FirebaseStoreActionTypeValue,\n} from \"@illa-public/public-types\"\n\nenum ServiceTypeLabel {\n  AUTH = \"Firebase Auth\",\n  FIRESTORE = \"Firestore\",\n  REALTIME = \"Realtime Database\",\n}\n\nexport const firebaseServiceTypeOptions = [\n  {\n    label: ServiceTypeLabel.AUTH,\n    value: FirebaseServiceTypeValue.AUTH,\n  },\n  {\n    label: ServiceTypeLabel.FIRESTORE,\n    value: FirebaseServiceTypeValue.FIRESTORE,\n  },\n  {\n    label: ServiceTypeLabel.REALTIME,\n    value: FirebaseServiceTypeValue.REALTIME,\n  },\n]\n\nenum FirestoreActionTypeLabel {\n  QUERY_FIREBASE = \"Query Firebase\",\n  INSERT_DOCUMENT = \"Insert Document\",\n  UPDATE_DOCUMENT = \"Update Document\",\n  GET_DOCUMENT_BY_ID = \"Get Document by ID\",\n  DELETE_ONE_DOCUMENT = \"Delete a Document\",\n  GET_COLLECTIONS = \"Get Collections\",\n  QUERY_COLLECTION_GROUP = \"Query Collection Group\",\n}\n\nconst FirestoreActionType = [\n  {\n    label: FirestoreActionTypeLabel.QUERY_FIREBASE,\n    value: FirebaseStoreActionTypeValue.QUERY_FIREBASE,\n  },\n  {\n    label: FirestoreActionTypeLabel.INSERT_DOCUMENT,\n    value: FirebaseStoreActionTypeValue.INSERT_DOCUMENT,\n  },\n  {\n    label: FirestoreActionTypeLabel.UPDATE_DOCUMENT,\n    value: FirebaseStoreActionTypeValue.UPDATE_DOCUMENT,\n  },\n  {\n    label: FirestoreActionTypeLabel.GET_DOCUMENT_BY_ID,\n    value: FirebaseStoreActionTypeValue.GET_DOCUMENT_BY_ID,\n  },\n  {\n    label: FirestoreActionTypeLabel.DELETE_ONE_DOCUMENT,\n    value: FirebaseStoreActionTypeValue.DELETE_ONE_DOCUMENT,\n  },\n  {\n    label: FirestoreActionTypeLabel.GET_COLLECTIONS,\n    value: FirebaseStoreActionTypeValue.GET_COLLECTIONS,\n  },\n  {\n    label: FirestoreActionTypeLabel.QUERY_COLLECTION_GROUP,\n    value: FirebaseStoreActionTypeValue.QUERY_COLLECTION_GROUP,\n  },\n]\n\nenum AuthActionTypeLabel {\n  GET_USER_BY_UID = \"Get user by UID\",\n  GET_USER_BY_EMAIL = \"Get user by email\",\n  GET_USER_BY_PHONE = \"Get user by phone number\",\n  CREATE_ONE_USER = \"Create a user\",\n  UPDATE_ONE_USER = \"Update a user\",\n  DELETE_ONE_USER = \"Delete a user\",\n  LIST_USERS = \"List users\",\n}\n\nconst AuthActionType = [\n  {\n    label: AuthActionTypeLabel.GET_USER_BY_UID,\n    value: FirebaseAuthActionTypeValue.GET_USER_BY_UID,\n  },\n  {\n    label: AuthActionTypeLabel.GET_USER_BY_EMAIL,\n    value: FirebaseAuthActionTypeValue.GET_USER_BY_EMAIL,\n  },\n  {\n    label: AuthActionTypeLabel.GET_USER_BY_PHONE,\n    value: FirebaseAuthActionTypeValue.GET_USER_BY_PHONE,\n  },\n  {\n    label: AuthActionTypeLabel.CREATE_ONE_USER,\n    value: FirebaseAuthActionTypeValue.CREATE_ONE_USER,\n  },\n  {\n    label: AuthActionTypeLabel.UPDATE_ONE_USER,\n    value: FirebaseAuthActionTypeValue.UPDATE_ONE_USER,\n  },\n  {\n    label: AuthActionTypeLabel.DELETE_ONE_USER,\n    value: FirebaseAuthActionTypeValue.DELETE_ONE_USER,\n  },\n  {\n    label: AuthActionTypeLabel.LIST_USERS,\n    value: FirebaseAuthActionTypeValue.LIST_USERS,\n  },\n]\n\nenum RealtimeActionTypeLabel {\n  QUERY_DATABASE = \"Query database\",\n  SET_DATA = \"Set data\",\n  UPDATE_DATA = \"Update data\",\n  APPEND_DATA_TO_LIST = \"Append data to a list\",\n}\n\nconst RealtimeActionType = [\n  {\n    label: RealtimeActionTypeLabel.QUERY_DATABASE,\n    value: FirebaseRealtimeActionTypeValue.QUERY_DATABASE,\n  },\n  {\n    label: RealtimeActionTypeLabel.SET_DATA,\n    value: FirebaseRealtimeActionTypeValue.SET_DATA,\n  },\n  {\n    label: RealtimeActionTypeLabel.UPDATE_DATA,\n    value: FirebaseRealtimeActionTypeValue.UPDATE_DATA,\n  },\n  {\n    label: RealtimeActionTypeLabel.APPEND_DATA_TO_LIST,\n    value: FirebaseRealtimeActionTypeValue.APPEND_DATA_TO_LIST,\n  },\n]\n\nexport const ActionTypeList = {\n  [FirebaseServiceTypeValue.AUTH]: AuthActionType,\n  [FirebaseServiceTypeValue.FIRESTORE]: FirestoreActionType,\n  [FirebaseServiceTypeValue.REALTIME]: RealtimeActionType,\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/index.tsx",
    "content": "import { FirebasePanel } from \"./FirebasePanel\"\n\nFirebasePanel.displayName = \"FirebasePanel\"\nexport default FirebasePanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/intreface.ts",
    "content": "import {\n  FirebaseCheckboxParams,\n  FirebaseContentType,\n  FirebaseWhere,\n} from \"@illa-public/public-types\"\n\nexport interface FirebaseActionPartProps {\n  options: FirebaseContentType\n  handleValueChange: (\n    value: string | boolean | FirebaseWhere[] | FirebaseCheckboxParams,\n    name: string,\n  ) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/FirebasePanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const actionContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n`\nexport const actionItemStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 48px;\n  padding: 0 16px;\n`\n\nexport const actionItemLabelStyle = css`\n  min-width: 160px;\n  font-size: 14px;\n  display: flex;\n  flex-direction: column;\n  font-weight: 500;\n  text-align: right;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n\nexport const actionBodyTypeStyle = css`\n  color: ${getColor(\"techPurple\", \"03\")};\n  cursor: pointer;\n  margin-top: 5px;\n`\n\nexport const checkboxItemStyle = css`\n  min-width: 160px;\n  font-size: 14px;\n  font-weight: 500;\n  margin-left: 10px;\n  text-align: left;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const actionItemCodeEditorStyle = css`\n  margin-top: 8px;\n  margin-bottom: 8px;\n  margin-left: 16px;\n  flex-grow: 1;\n  width: 0;\n`\n\nexport const actionItemRecordEditorStyle = css`\n  margin-top: 8px;\n  margin-bottom: 8px;\n  border-radius: 0;\n  flex-grow: 1;\n  width: 0;\n`\n\nexport const codeEditorLabelStyle = css`\n  min-width: 160px;\n  font-size: 14px;\n  font-weight: 500;\n  text-align: right;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  height: 48px;\n  display: flex;\n  flex-direction: row;\n  justify-content: end;\n  align-items: center;\n  align-self: start;\n`\n\nexport const checkboxContainer = css`\n  padding: 8px 0 16px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GlobalDataPanel/index.tsx",
    "content": "import { GlobalDataActionContent } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport Space from \"../Layout/Space\"\nimport {\n  globalDataPanelContainerStyle,\n  inputAreaStyle,\n  labelStyle,\n  tipsStyle,\n} from \"./style\"\n\nconst GlobalDataPanel: FC = () => {\n  const currentAction = useSelector(getCachedAction)!\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n\n  const handleOnChangeValue = (value: string) => {\n    dispatch(\n      configActions.updateCachedAction({\n        ...currentAction,\n        content: {\n          initialValue: value,\n        },\n      }),\n    )\n  }\n\n  return (\n    <>\n      <Space />\n      <div css={globalDataPanelContainerStyle}>\n        <span css={labelStyle}>\n          {t(\"editor.data_work_space.global_data_modal.initial_value.label\")}\n        </span>\n        <div css={inputAreaStyle}>\n          <CodeEditor\n            value={\n              (currentAction.content as GlobalDataActionContent).initialValue\n            }\n            height=\"58px\"\n            onChange={handleOnChangeValue}\n            modalTitle={t(\n              \"editor.data_work_space.global_data_modal.initial_value.label\",\n            )}\n            modalDescription={t(\n              \"editor.data_work_space.global_data_modal.initial_value.tooltips\",\n            )}\n            placeholder={t(\n              \"editor.data_work_space.global_data_modal.initial_value.placeholder\",\n            )}\n          />\n          <span css={tipsStyle}>\n            {t(\"editor.action.panel.label.tips.global-data.how-to-use\")}\n          </span>\n        </div>\n      </div>\n    </>\n  )\n}\n\nGlobalDataPanel.displayName = \"GlobalDataPanel\"\n\nexport default GlobalDataPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GlobalDataPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const globalDataPanelContainerStyle = css`\n  display: flex;\n  width: 100%;\n  padding: 8px 16px;\n  gap: 16px;\n`\n\nexport const labelStyle = css`\n  width: 200px;\n  text-align: right;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n  white-space: nowrap;\n`\n\nexport const inputAreaStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n  width: 100%;\n`\n\nexport const tipsStyle = css`\n  font-size: 14px;\n  font-weight: 400;\n  line-height: 22px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/AppendSpreadsheetSubPanel/index.tsx",
    "content": "import { GoogleSheetsActionAppendOpts } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { BasicSheetConfig } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BasicSheetConfig\"\nimport { GoogleSheetsActionSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const AppendSpreadsheetSubPanel: FC<GoogleSheetsActionSubPanelProps> = (\n  props,\n) => {\n  const { onChange, spreadsheetsOption } = props\n  const { t } = useTranslation()\n  const opts = props.opts as GoogleSheetsActionAppendOpts\n\n  return (\n    <>\n      <BasicSheetConfig\n        sheetName={opts.sheetName}\n        spreadsheet={opts.spreadsheet}\n        onChange={onChange}\n        spreadsheetsOption={spreadsheetsOption}\n        fx={opts.fx}\n      />\n      <InputEditor\n        value={opts.values}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        onChange={onChange(\"values\")}\n        title={t(\"editor.action.form.label.gs.values_to_append\")}\n        placeholder={t(\"editor.action.form.tips.gs.values_to_append\")}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n    </>\n  )\n}\nAppendSpreadsheetSubPanel.displayName = \"AppendSpreadsheetSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BasicSheetConfig/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FxIcon } from \"@illa-design/react\"\nimport {\n  getFxIconStyle,\n  sheetConfigContainerStyle,\n  spreadsheetContainerStyle,\n} from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BasicSheetConfig/style\"\nimport { BasicSheetConfigProps } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const BasicSheetConfig: FC<BasicSheetConfigProps> = (props) => {\n  const {\n    spreadsheet,\n    sheetName,\n    onChange,\n    spreadsheetsOption,\n    isHiddenSheetName = false,\n    fx,\n  } = props\n  const { t } = useTranslation()\n\n  const handleOnClick = () => {\n    onChange(\"fx\")(!fx)\n  }\n\n  return (\n    <div css={sheetConfigContainerStyle}>\n      <div css={spreadsheetContainerStyle}>\n        {fx ? (\n          <InputEditor\n            title={t(\"editor.action.form.label.gs.spreadsheet\")}\n            value={spreadsheet}\n            onChange={onChange(\"spreadsheet\")}\n            expectedType={VALIDATION_TYPES.STRING}\n          />\n        ) : (\n          <SingleTypeComponent\n            title={t(\"editor.action.form.label.gs.spreadsheet\")}\n            componentType=\"select\"\n            value={spreadsheet}\n            onChange={onChange(\"spreadsheet\")}\n            options={spreadsheetsOption}\n          />\n        )}\n        <FxIcon\n          onClick={handleOnClick}\n          css={getFxIconStyle(isHiddenSheetName, fx)}\n        />\n      </div>\n      {!isHiddenSheetName && (\n        <div css={spreadsheetContainerStyle}>\n          <InputEditor\n            title={t(\"editor.action.form.label.gs.sheet_name\")}\n            value={sheetName ?? \"\"}\n            onChange={onChange(\"sheetName\")}\n            tips={t(\"editor.action.form.tips.gs.leave_blank_to_selec\")}\n            expectedType={VALIDATION_TYPES.STRING}\n          />\n        </div>\n      )}\n    </div>\n  )\n}\nBasicSheetConfig.displayName = \"BasicSheetConfig\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BasicSheetConfig/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const sheetConfigContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  align-items: flex-start;\n`\n\nexport const spreadsheetContainerStyle = css`\n  display: flex;\n  align-items: center;\n  flex: 1;\n`\n\nexport const getFxIconStyle = (fullwidth: boolean, selected?: boolean) => {\n  const hasRightMargin = fullwidth\n    ? css`\n        margin-right: 16px;\n      `\n    : css``\n  return css`\n    width: 16px;\n    height: 16px;\n    color: ${selected\n      ? getColor(\"techPurple\", \"03\")\n      : getColor(\"grayBlue\", \"04\")};\n    cursor: pointer;\n    z-index: 1;\n    ${hasRightMargin};\n    :hover {\n      cursor: pointer;\n      color: ${getColor(\"techPurple\", \"03\")};\n    }\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BulkUpdateSpreadsheetSubPanel/index.tsx",
    "content": "import { GoogleSheetsActionBulkOpts } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { BasicSheetConfig } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BasicSheetConfig\"\nimport { GoogleSheetsActionSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const BulkUpdateSpreadsheetSubPanel: FC<\n  GoogleSheetsActionSubPanelProps\n> = (props) => {\n  const { t } = useTranslation()\n  const { onChange, spreadsheetsOption } = props\n  const opts = props.opts as GoogleSheetsActionBulkOpts\n\n  return (\n    <>\n      <BasicSheetConfig\n        sheetName={opts.sheetName}\n        spreadsheet={opts.spreadsheet}\n        onChange={onChange}\n        spreadsheetsOption={spreadsheetsOption}\n        fx={opts.fx}\n      />\n      <InputEditor\n        value={opts.primaryKey}\n        onChange={onChange(\"primaryKey\")}\n        title={t(\"editor.action.form.label.gs.primary_key_column\")}\n        placeholder={t(\"editor.action.form.placeholder.gs.primary_key_column\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        value={opts.rowsArray}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        onChange={onChange(\"rowsArray\")}\n        title={t(\"editor.action.form.label.gs.array_of_rows_to_upd\")}\n        placeholder={t(\n          \"editor.action.form.placeholder.gs.array_of_rows_to_upd\",\n        )}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n    </>\n  )\n}\nBulkUpdateSpreadsheetSubPanel.displayName = \"BulkUpdateSpreadsheetSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/CopySpreadSheetSubPanel/index.tsx",
    "content": "import { GoogleSheetsActionCopyOpts } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FxIcon } from \"@illa-design/react\"\nimport { BasicSheetConfig } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BasicSheetConfig\"\nimport {\n  applyFxIconStyle,\n  sheetConfigContainerStyle,\n  spreadsheetContainerStyle,\n} from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/CopySpreadSheetSubPanel/style\"\nimport { GoogleSheetsActionSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const CopySpreadsheetSubPanel: FC<GoogleSheetsActionSubPanelProps> = (\n  props,\n) => {\n  const { t } = useTranslation()\n  const { onChange, spreadsheetsOption } = props\n  const opts = props.opts as GoogleSheetsActionCopyOpts\n  const {\n    toSpreadsheet,\n    toSheet,\n    sheetName,\n    spreadsheet,\n    fx,\n    toFx = false,\n  } = opts\n\n  const handleOnClick = () => {\n    onChange(\"toFx\")(!toFx)\n  }\n\n  return (\n    <>\n      <BasicSheetConfig\n        sheetName={sheetName}\n        spreadsheet={spreadsheet}\n        onChange={onChange}\n        spreadsheetsOption={spreadsheetsOption}\n        fx={fx}\n      />\n      <div css={sheetConfigContainerStyle}>\n        <div css={spreadsheetContainerStyle}>\n          {toFx ? (\n            <InputEditor\n              title={t(\"editor.action.form.label.gs.sheet_to_copy_to\")}\n              value={toSpreadsheet}\n              onChange={onChange(\"toSpreadsheet\")}\n              expectedType={VALIDATION_TYPES.STRING}\n            />\n          ) : (\n            <SingleTypeComponent\n              title={t(\"editor.action.form.label.gs.sheet_to_copy_to\")}\n              componentType=\"select\"\n              value={toSpreadsheet}\n              onChange={onChange(\"toSpreadsheet\")}\n              options={spreadsheetsOption}\n            />\n          )}\n          <FxIcon onClick={handleOnClick} css={applyFxIconStyle(toFx)} />\n        </div>\n        <div css={spreadsheetContainerStyle}>\n          <InputEditor\n            title={t(\"editor.action.form.label.gs.sheet_name\")}\n            value={toSheet ?? \"\"}\n            onChange={onChange(\"toSheet\")}\n            tips={t(\"editor.action.form.tips.gs.copy_to_sheet_name\")}\n            expectedType={VALIDATION_TYPES.STRING}\n          />\n        </div>\n      </div>\n    </>\n  )\n}\nCopySpreadsheetSubPanel.displayName = \"CopySpreadsheetSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/CopySpreadSheetSubPanel/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const sheetConfigContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  align-items: flex-start;\n`\n\nexport const spreadsheetContainerStyle = css`\n  align-items: center;\n  display: flex;\n  flex: 1;\n`\n\nexport function applyFxIconStyle(selected?: boolean): SerializedStyles {\n  return css`\n    width: 16px;\n    height: 16px;\n    color: ${selected\n      ? getColor(\"techPurple\", \"03\")\n      : getColor(\"grayBlue\", \"04\")};\n    cursor: pointer;\n    z-index: 1;\n    :hover {\n      cursor: pointer;\n      color: ${getColor(\"techPurple\", \"03\")};\n    }\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/CreateSpreadsheetSubPanel/index.tsx",
    "content": "import { GoogleSheetsActionCreateOpts } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { GoogleSheetsActionSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const CreateSpreadsheetSubPanel: FC<GoogleSheetsActionSubPanelProps> = (\n  props,\n) => {\n  const { onChange } = props\n  const { t } = useTranslation()\n  const opts = props.opts as GoogleSheetsActionCreateOpts\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.form.label.gs.title_of_spreadsheet\")}\n      value={opts.title}\n      onChange={onChange(\"title\")}\n    />\n  )\n}\nCreateSpreadsheetSubPanel.displayName = \"CreateSpreadsheetSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/DeleteSpreadsheetSubPanel/index.tsx",
    "content": "import { GoogleSheetsActionDeleteOpts } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { BasicSheetConfig } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BasicSheetConfig\"\nimport { GoogleSheetsActionSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DeleteSpreadsheetSubPanel: FC<GoogleSheetsActionSubPanelProps> = (\n  props,\n) => {\n  const { t } = useTranslation()\n  const { onChange, spreadsheetsOption } = props\n  const opts = props.opts as GoogleSheetsActionDeleteOpts\n\n  return (\n    <>\n      <BasicSheetConfig\n        sheetName={opts.sheetName}\n        spreadsheet={opts.spreadsheet}\n        onChange={onChange}\n        spreadsheetsOption={spreadsheetsOption}\n        fx={opts.fx}\n      />\n      <InputEditor\n        value={opts.rowIndex}\n        onChange={onChange(\"rowIndex\")}\n        title={t(\"editor.action.form.label.gs.filters_to_match_row\")}\n        placeholder=\"{{ 2 }}\"\n        expectedType={VALIDATION_TYPES.NUMBER}\n      />\n    </>\n  )\n}\nDeleteSpreadsheetSubPanel.displayName = \"DeleteSpreadsheetSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/GetSpreadsheetSubPanel/index.tsx",
    "content": "import { GoogleSheetsActionGetOpts } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { BasicSheetConfig } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BasicSheetConfig\"\nimport { GoogleSheetsActionSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/interface\"\n\nexport const GetSpreadsheetSubPanel: FC<GoogleSheetsActionSubPanelProps> = (\n  props,\n) => {\n  const { onChange, spreadsheetsOption } = props\n  const opts = props.opts as GoogleSheetsActionGetOpts\n\n  return (\n    <BasicSheetConfig\n      spreadsheet={opts.spreadsheet}\n      onChange={onChange}\n      isHiddenSheetName={true}\n      spreadsheetsOption={spreadsheetsOption}\n      fx={opts.fx}\n    />\n  )\n}\nGetSpreadsheetSubPanel.displayName = \"GetSpreadsheetSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/ReadSpreadsheetSubPanel/index.tsx",
    "content": "import { GoogleSheetsActionReadOpts } from \"@illa-public/public-types\"\nimport { TextLink } from \"@illa-public/text-link\"\nimport { FC } from \"react\"\nimport { Trans, useTranslation } from \"react-i18next\"\nimport { Divider, RadioGroup } from \"@illa-design/react\"\nimport { BasicSheetConfig } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BasicSheetConfig\"\nimport { GoogleSheetsActionSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/interface\"\nimport {\n  sheetConfigContainerStyle,\n  spreadsheetContainerStyle,\n} from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/style\"\nimport { ReadGoogleSheetsActionOptions } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/values\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport {\n  optionLabelContainerStyle,\n  optionLabelStyle,\n  radioGroupContainerStyle,\n} from \"./style\"\n\nexport const ReadSpreadsheetSubPanel: FC<GoogleSheetsActionSubPanelProps> = (\n  props,\n) => {\n  const { t } = useTranslation()\n  const { onChange, spreadsheetsOption } = props\n  const opts = props.opts as GoogleSheetsActionReadOpts\n  const { spreadsheet, sheetName, fx } = opts\n\n  return (\n    <>\n      <BasicSheetConfig\n        spreadsheet={spreadsheet}\n        sheetName={sheetName}\n        onChange={onChange}\n        spreadsheetsOption={spreadsheetsOption}\n        fx={fx}\n        isHiddenSheetName={opts.rangeType === \"a1\"}\n      />\n      <Divider direction=\"horizontal\" w=\"unset\" />\n      <div css={optionLabelContainerStyle}>\n        <span css={optionLabelStyle}>\n          {t(\"editor.action.form.label.gs.data_range\")}\n        </span>\n        <div css={radioGroupContainerStyle}>\n          <RadioGroup\n            type=\"button\"\n            value={opts.rangeType}\n            defaultValue={opts.rangeType}\n            options={ReadGoogleSheetsActionOptions}\n            onChange={onChange(\"rangeType\")}\n          />\n        </div>\n      </div>\n      {opts.rangeType === \"limit\" && (\n        <div css={sheetConfigContainerStyle}>\n          <div css={spreadsheetContainerStyle}>\n            <InputEditor\n              value={opts.limit ?? \"\"}\n              onChange={onChange(\"limit\")}\n              title={t(\"editor.action.form.label.gs.limit\")}\n              expectedType={VALIDATION_TYPES.NUMBER}\n            />\n          </div>\n          <div css={spreadsheetContainerStyle}>\n            <InputEditor\n              value={opts.offset ?? \"\"}\n              onChange={onChange(\"offset\")}\n              title={t(\"editor.action.form.label.gs.offset\")}\n              expectedType={VALIDATION_TYPES.NUMBER}\n            />\n          </div>\n        </div>\n      )}\n      {opts.rangeType === \"a1\" && (\n        <InputEditor\n          title={t(\"editor.action.form.label.gs.a1_notation\")}\n          value={opts.a1Notation}\n          onChange={onChange(\"a1Notation\")}\n          tips={\n            <Trans\n              i18nKey=\"editor.action.form.tips.gs.to_select_the_first_\"\n              t={t}\n              components={[\n                <TextLink\n                  key=\"notation-link\"\n                  onClick={() => {\n                    window.open(\n                      \"https://developers.google.com/sheets/api/guides/concepts#a1_notation\",\n                      \"_blank\",\n                    )\n                  }}\n                />,\n              ]}\n            />\n          }\n        />\n      )}\n    </>\n  )\n}\n\nReadSpreadsheetSubPanel.displayName = \"ReadSpreadsheetSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/ReadSpreadsheetSubPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const optionLabelContainerStyle = css`\n  min-height: 48px;\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  align-items: center;\n  padding: 16px 16px 8px;\n  gap: 128px;\n`\n\nexport const optionLabelStyle = css`\n  height: 22px;\n  font-weight: 500;\n  font-size: 14px;\n  line-height: 22px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n\nexport const radioGroupContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  justify-content: center;\n  align-items: center;\n  padding: 1px;\n  gap: 2px;\n  height: 24px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/UpdateSpreadsheetSubPanel/index.tsx",
    "content": "import { GoogleSheetsActionUpdateOpts, Params } from \"@illa-public/public-types\"\nimport { TextLink } from \"@illa-public/text-link\"\nimport { FC, useCallback } from \"react\"\nimport { Trans, useTranslation } from \"react-i18next\"\nimport { Select } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { RecordEditor } from \"@/components/RecordEditor\"\nimport {\n  codeMirrorWrapperLabelStyle,\n  codeMirrorWrapperValueStyle,\n} from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/components/CollectionRecordEditor/style\"\nimport { actionItemRecordEditorStyle } from \"@/page/App/components/Actions/ActionPanel/FirebasePanel/style\"\nimport { BasicSheetConfig } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BasicSheetConfig\"\nimport { GoogleSheetsActionSubPanelProps } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/interface\"\nimport {\n  updateEditorKeyContainerStyle,\n  updateEditorValueContainerStyle,\n} from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/style\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const UpdateSpreadsheetSubPanel: FC<GoogleSheetsActionSubPanelProps> = (\n  props,\n) => {\n  const { t } = useTranslation()\n  const { onChange, spreadsheetsOption } = props\n  const opts = props.opts as GoogleSheetsActionUpdateOpts\n\n  const isFiltersType = opts.filterType === \"filter\"\n\n  const handleOnChangeKeyOrValue = useCallback(\n    (\n      index: number,\n      key: string,\n      value: string,\n      operator: string,\n      _name?: string,\n    ) => {\n      const params = opts.filters as Params[]\n      let newList = [...params]\n      newList[index] = {\n        key,\n        value,\n        operator,\n      }\n      onChange(\"filters\")(newList)\n    },\n    [onChange, opts.filters],\n  )\n\n  const handleOnAddKeys = useCallback(() => {\n    const params = opts.filters as Params[]\n    let newList: Params[] = [\n      ...params,\n      { key: \"\", value: \"\", operator: \"\" } as Params,\n    ]\n    onChange(\"filters\")(newList)\n  }, [onChange, opts.filters])\n\n  const handleOnDeleteKeys = useCallback(\n    (index: number) => {\n      const params = opts.filters as Params[]\n      let newList = [...params]\n      newList.splice(index, 1)\n      if (newList.length === 0) {\n        newList = [{ key: \"\", value: \"\", operator: \"\" } as Params]\n      }\n      onChange(\"filters\")(newList)\n    },\n    [onChange, opts.filters],\n  )\n\n  const handleSubLabelClick = useCallback(() => {\n    const updateValue = opts.filterType === \"filter\" ? \"a1\" : \"filter\"\n    onChange(\"filterType\")(updateValue)\n  }, [onChange, opts.filterType])\n\n  return (\n    <>\n      <BasicSheetConfig\n        sheetName={opts.sheetName}\n        spreadsheet={opts.spreadsheet}\n        onChange={onChange}\n        isHiddenSheetName={!isFiltersType}\n        spreadsheetsOption={spreadsheetsOption}\n        fx={opts.fx}\n      />\n      {isFiltersType ? (\n        <RecordEditor\n          label={t(\"editor.action.form.label.gs.filter_by\")}\n          subLabel={\n            isFiltersType\n              ? t(\"editor.action.form.option.gs.filter_by.use_a1_notation\")\n              : t(\"editor.action.form.option.gs.filter_by.use_row_filters\")\n          }\n          onSubLabelClick={handleSubLabelClick}\n          records={(opts.filters ?? []) as Params[]}\n          customRender={(record, index) => (\n            <>\n              <div\n                css={[\n                  actionItemRecordEditorStyle,\n                  updateEditorKeyContainerStyle,\n                ]}\n              >\n                <CodeEditor\n                  value={record.key}\n                  singleLine\n                  onChange={(val) => {\n                    handleOnChangeKeyOrValue(\n                      index,\n                      val,\n                      record.value,\n                      record.operator,\n                    )\n                  }}\n                  wrapperCss={codeMirrorWrapperLabelStyle}\n                  expectValueType={VALIDATION_TYPES.STRING}\n                  lang={CODE_LANG.JAVASCRIPT}\n                  codeType={CODE_TYPE.EXPRESSION}\n                  canShowCompleteInfo\n                  placeholder={t(\n                    \"editor.action.form.placeholder.gs.row_filter.column_name\",\n                  )}\n                />\n              </div>\n              <Select\n                colorScheme=\"techPurple\"\n                showSearch={true}\n                defaultValue={record.operator}\n                value={record.operator}\n                w=\"0\"\n                h=\"32px\"\n                bdRadius=\"0\"\n                flexGrow=\"1\"\n                onChange={(val) =>\n                  handleOnChangeKeyOrValue(\n                    index,\n                    record.key,\n                    record.value,\n                    val as string,\n                  )\n                }\n                options={[\"=\"]}\n              />\n              <div\n                css={[\n                  actionItemRecordEditorStyle,\n                  updateEditorValueContainerStyle,\n                ]}\n              >\n                <CodeEditor\n                  singleLine\n                  value={record.value}\n                  onChange={(val) => {\n                    handleOnChangeKeyOrValue(\n                      index,\n                      record.key,\n                      val,\n                      record.operator,\n                    )\n                  }}\n                  wrapperCss={codeMirrorWrapperValueStyle}\n                  expectValueType={VALIDATION_TYPES.STRING}\n                  lang={CODE_LANG.JAVASCRIPT}\n                  codeType={CODE_TYPE.EXPRESSION}\n                  canShowCompleteInfo\n                  placeholder={t(\n                    \"editor.action.form.placeholder.gs.row_filter.value\",\n                  )}\n                />\n              </div>\n            </>\n          )}\n          name=\"filter\"\n          onAdd={handleOnAddKeys}\n          onDelete={handleOnDeleteKeys}\n          onChangeKey={() => {}}\n          onChangeValue={() => {}}\n        />\n      ) : (\n        <InputEditor\n          title={t(\"editor.action.form.label.gs.filter_by\")}\n          value={opts.a1Notation}\n          onChange={onChange(\"a1Notation\")}\n          tips={\n            <Trans\n              i18nKey=\"editor.action.form.tips.gs.a1_notation\"\n              t={t}\n              components={[\n                <TextLink\n                  key=\"editor.action.form.tips.gs.a1_notation\"\n                  onClick={() =>\n                    window.open(\n                      \"https://developers.google.com/sheets/api/guides/concepts#a1_notation\",\n                      \"_blank\",\n                    )\n                  }\n                />,\n              ]}\n            />\n          }\n          expectedType={VALIDATION_TYPES.STRING}\n          subtitle={\n            isFiltersType\n              ? t(\"editor.action.form.option.gs.filter_by.use_a1_notation\")\n              : t(\"editor.action.form.option.gs.filter_by.use_row_filters\")\n          }\n          handleSubtitleClick={handleSubLabelClick}\n        />\n      )}\n      <InputEditor\n        title={t(\"editor.action.form.label.gs.update_value\")}\n        value={opts.values}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        onChange={onChange(\"values\")}\n        placeholder={t(\"editor.action.form.placeholder.gs.update_value\")}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n    </>\n  )\n}\nUpdateSpreadsheetSubPanel.displayName = \"UpdateSpreadsheetSubPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/index.tsx",
    "content": "import {\n  GoogleSheetsActionInitial,\n  GoogleSheetsActionInitialMaps,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  GoogleSheetsAction,\n  GoogleSheetsActionOpts,\n  GoogleSheetsActionType,\n} from \"@illa-public/public-types\"\nimport { Params } from \"@illa-public/public-types\"\nimport { FC, useCallback, useEffect, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { SelectOptionObject, SelectValue } from \"@illa-design/react\"\nimport { AppendSpreadsheetSubPanel } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/AppendSpreadsheetSubPanel\"\nimport { BulkUpdateSpreadsheetSubPanel } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/BulkUpdateSpreadsheetSubPanel\"\nimport { CopySpreadsheetSubPanel } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/CopySpreadSheetSubPanel\"\nimport { CreateSpreadsheetSubPanel } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/CreateSpreadsheetSubPanel\"\nimport { DeleteSpreadsheetSubPanel } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/DeleteSpreadsheetSubPanel\"\nimport { GetSpreadsheetSubPanel } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/GetSpreadsheetSubPanel\"\nimport { ReadSpreadsheetSubPanel } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/ReadSpreadsheetSubPanel\"\nimport { UpdateSpreadsheetSubPanel } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/UpdateSpreadsheetSubPanel\"\nimport { GoogleSheetsActionTypesOptions } from \"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/values\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { actionItemContainer } from \"@/page/App/components/Actions/ActionPanel/style\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { fetchResourceMeta } from \"@/services/resource\"\n\nconst SubPanelMap: Record<GoogleSheetsActionType, any> = {\n  read: ReadSpreadsheetSubPanel,\n  update: UpdateSpreadsheetSubPanel,\n  delete: DeleteSpreadsheetSubPanel,\n  list: null,\n  append: AppendSpreadsheetSubPanel,\n  bulkUpdate: BulkUpdateSpreadsheetSubPanel,\n  copy: CopySpreadsheetSubPanel,\n  create: CreateSpreadsheetSubPanel,\n  get: GetSpreadsheetSubPanel,\n}\n\nconst GoogleSheetsPanel: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    GoogleSheetsAction<GoogleSheetsActionOpts>\n  >\n  const selectedAction = useSelector(getSelectedAction) as ActionItem<\n    GoogleSheetsAction<GoogleSheetsActionOpts>\n  >\n\n  const [spreadsheetsOption, setSpreadsheetsOption] = useState<\n    SelectOptionObject[]\n  >([])\n\n  const content = cachedAction?.content ?? GoogleSheetsActionInitial\n  const selectedContent = selectedAction.content\n\n  useEffect(() => {\n    if (cachedAction.resourceID == undefined) return\n    fetchResourceMeta(cachedAction.resourceID).then(({ data }) => {\n      let tables: { id: string; name: string }[] = []\n      if (data.Schema) {\n        tables = (data.Schema?.spreadsheets ?? []) as {\n          id: string\n          name: string\n        }[]\n      }\n      setSpreadsheetsOption(\n        tables.map((table) => ({ label: table.name, value: table.id })),\n      )\n    })\n  }, [cachedAction.resourceID])\n\n  const handleSelectValueChange = useCallback(\n    (value: SelectValue) => {\n      const content =\n        selectedContent.method === value\n          ? selectedContent\n          : {\n              method: value as GoogleSheetsActionType,\n              opts: GoogleSheetsActionInitialMaps[\n                value as GoogleSheetsActionType\n              ],\n            }\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content,\n        }),\n      )\n    },\n    [cachedAction, dispatch, selectedContent],\n  )\n\n  const handleValueChange = useCallback(\n    (key: string) => (value: string | boolean | Params[]) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            opts: {\n              ...content.opts,\n              [key]: value,\n            },\n          },\n        }),\n      )\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  const SubPanel = SubPanelMap[content.method]\n\n  return (\n    <div css={actionItemContainer}>\n      <SingleTypeComponent\n        title={t(\"editor.action.form.label.gs.action_type\")}\n        componentType=\"select\"\n        value={content.method}\n        options={GoogleSheetsActionTypesOptions}\n        onSelectedValueChange={handleSelectValueChange}\n      />\n      {SubPanel && (\n        <SubPanel\n          opts={content.opts}\n          onChange={handleValueChange}\n          spreadsheetsOption={spreadsheetsOption}\n        />\n      )}\n      <TransformerComponent />\n    </div>\n  )\n}\n\nGoogleSheetsPanel.displayName = \"GoogleSheetsPanel\"\nexport default GoogleSheetsPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/interface.ts",
    "content": "import { GoogleSheetsActionOpts } from \"@illa-public/public-types\"\nimport { Params } from \"@illa-public/public-types\"\nimport { SelectOptionObject } from \"@illa-design/react\"\n\nexport interface GoogleSheetsActionSubPanelProps {\n  opts: GoogleSheetsActionOpts\n  spreadsheetsOption: SelectOptionObject[]\n  onChange: (key: string) => (value: string | boolean | Params[]) => void\n}\n\nexport interface BasicSheetConfigProps {\n  sheetName?: string\n  spreadsheet: string\n  isHiddenSheetName?: boolean\n  spreadsheetsOption: SelectOptionObject[]\n  fx: boolean\n  onChange: (key: string) => (value: string | boolean) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const sheetConfigContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  align-items: flex-start;\n`\n\nexport const spreadsheetContainerStyle = css`\n  display: flex;\n  position: relative;\n  width: 50%;\n`\n\nexport const updateEditorKeyContainerStyle = css`\n  flex-grow: 2;\n  .cm-editor {\n    height: 32px;\n  }\n`\n\nexport const updateEditorValueContainerStyle = css`\n  flex-grow: 3;\n  .cm-editor {\n    height: 32px;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GoogleSheetsPanel/values.ts",
    "content": "import { GoogleSheetsActionType } from \"@illa-public/public-types\"\nimport i18n from \"@/i18n/config\"\n\nexport const GoogleSheetsActionTypesOptions: {\n  label: string\n  value: GoogleSheetsActionType\n}[] = [\n  {\n    label: i18n.t(\n      \"editor.action.form.option.gs.action_type.read_data_from_a_spr\",\n    ),\n    value: \"read\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.form.option.gs.action_type.append_data_to_a_spr\",\n    ),\n    value: \"append\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.form.option.gs.action_type.update_a_spreadsheet\",\n    ),\n    value: \"update\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.form.option.gs.action_type.bulk_update_a_spread\",\n    ),\n    value: \"bulkUpdate\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.form.option.gs.action_type.delete_a_single_row_\",\n    ),\n    value: \"delete\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.form.option.gs.action_type.create_a_spreadsheet\",\n    ),\n    value: \"create\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.form.option.gs.action_type.copy_a_single_sheet_\",\n    ),\n    value: \"copy\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.form.option.gs.action_type.list_available_sprea\",\n    ),\n    value: \"list\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.form.option.gs.action_type.get_spreadsheet_info\",\n    ),\n    value: \"get\",\n  },\n]\n\nexport const ReadGoogleSheetsActionOptions = [\n  {\n    label: i18n.t(\"editor.action.form.option.gs.data_range.use_a1_notation\"),\n    value: \"a1\",\n  },\n  {\n    label: i18n.t(\n      \"editor.action.form.option.gs.data_range.use_limit_and_offset\",\n    ),\n    value: \"limit\",\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GraphQLPanel/index.tsx",
    "content": "import { ActionItem, GraphQLAction } from \"@illa-public/public-types\"\nimport { Params } from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { RecordEditor } from \"@/components/RecordEditor\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { actionItemContainer } from \"./style\"\n\nconst GraphQLPanel: FC = () => {\n  const { t } = useTranslation()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<GraphQLAction>\n  const content = cachedAction.content as GraphQLAction\n\n  const dispatch = useDispatch()\n\n  const handleValueChange = useCallback(\n    (value: string | Params[], name: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            [name]: value,\n          },\n        }),\n      )\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  const handleOnAddKeys = useCallback(\n    (name?: string) => {\n      if (name && content.hasOwnProperty(name)) {\n        const oldList = content[name as keyof typeof content] as Params[]\n        let newList: Params[] = [...oldList, { key: \"\", value: \"\" } as Params]\n        dispatch(\n          configActions.updateCachedAction({\n            ...cachedAction,\n            content: {\n              ...content,\n              [name]: newList,\n            },\n          }),\n        )\n      }\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  const handleOnDeleteKeyValue = useCallback(\n    (index: number, record: Params, name?: string) => {\n      if (name && content.hasOwnProperty(name)) {\n        const oldList = content[name as keyof typeof content] as Params[]\n        let newList = [...oldList]\n        newList.splice(index, 1)\n        if (newList.length === 0) {\n          newList = [{ key: \"\", value: \"\" }]\n        }\n        dispatch(\n          configActions.updateCachedAction({\n            ...cachedAction,\n            content: {\n              ...content,\n              [name]: newList,\n            },\n          }),\n        )\n      }\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  const handleOnChangeKeyOrValue = useCallback(\n    (index: number, key: string, value: string, name?: string) => {\n      if (name && content.hasOwnProperty(name)) {\n        const oldList = content[name as keyof typeof content] as Params[]\n        let newList: Params[] = [...oldList]\n        newList[index] = { key, value } as Params\n        dispatch(\n          configActions.updateCachedAction({\n            ...cachedAction,\n            content: {\n              ...content,\n              [name]: newList,\n            },\n          }),\n        )\n      }\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  return (\n    <div css={actionItemContainer}>\n      <InputEditor\n        lineNumbers\n        title={t(\"editor.action.panel.graphql.query\")}\n        placeholder={t(\"editor.action.panel.graphql.placeholder.query\")}\n        value={content.query}\n        onChange={(value) => handleValueChange(value, \"query\")}\n        mode={CODE_LANG.SQL}\n        style={{ height: \"88px\" }}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <RecordEditor\n        key=\"variables\"\n        label={t(\"editor.action.panel.graphql.variables\")}\n        records={content.variables}\n        name=\"variables\"\n        onAdd={handleOnAddKeys}\n        onDelete={handleOnDeleteKeyValue}\n        onChangeKey={handleOnChangeKeyOrValue}\n        onChangeValue={handleOnChangeKeyOrValue}\n        valueInputType={VALIDATION_TYPES.ANY}\n      />\n      <RecordEditor\n        key=\"headers\"\n        label={t(\"editor.action.panel.graphql.headers\")}\n        name=\"headers\"\n        records={content.headers}\n        onAdd={handleOnAddKeys}\n        onDelete={handleOnDeleteKeyValue}\n        onChangeKey={handleOnChangeKeyOrValue}\n        onChangeValue={handleOnChangeKeyOrValue}\n      />\n      <TransformerComponent />\n    </div>\n  )\n}\n\nGraphQLPanel.displayName = \"GraphQLPanel\"\nexport default GraphQLPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/GraphQLPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/HuggingFaceCommonPanel/constants.ts",
    "content": "export const ParametersTypeMap = [\n  {\n    label: 'Fill in \"inputs\" parameter with key-value',\n    value: \"pairs\",\n  },\n  {\n    label: 'Fill in \"inputs\" parameter with text',\n    value: \"text\",\n  },\n  {\n    label: 'Fill in \"inputs\" parameter with JSON',\n    value: \"json\",\n  },\n  {\n    label: \"Binary\",\n    value: \"binary\",\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/HuggingFaceCommonPanel/index.tsx",
    "content": "import {\n  HuggingFaceInputInitial,\n  HuggingFacePairsBodyInitital,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  HuggingFaceAction,\n  HuggingFaceBodyContent,\n  HuggingFaceParametesType,\n} from \"@illa-public/public-types\"\nimport { Params } from \"@illa-public/public-types\"\nimport { TextLink } from \"@illa-public/text-link\"\nimport { Namespace, TFunction } from \"i18next\"\nimport { FC, useCallback } from \"react\"\nimport { Trans, useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Select, SelectValue } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { RecordEditor } from \"@/components/RecordEditor\"\nimport { HuggingFaceCommonPanelProps } from \"@/page/App/components/Actions/ActionPanel/HuggingFaceCommonPanel/interface\"\nimport {\n  bodyChooserStyle,\n  bodyEditorContainerStyle,\n  bodyLabelStyle,\n  bodySelectorStyle,\n  codeEditorStyle,\n} from \"@/page/App/components/Actions/ActionPanel/RestApiPanel/BodyEditor/style\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { ParametersTypeMap } from \"./constants\"\nimport { actionItemContainer, textCodeEditorStyle } from \"./style\"\n\nconst getDetailedParameters = ({\n  t,\n  content,\n  handleParametersValueChange,\n}: {\n  t: TFunction<Namespace, undefined>\n  content: HuggingFaceAction<HuggingFaceBodyContent>\n  handleParametersValueChange: (value: string, key: string) => void\n}) => {\n  return (\n    <>\n      {[\n        {\n          title: t(\"editor.action.panel.hugging_face.use_cache\"),\n          name: \"useCache\",\n          value: content.detailParams?.useCache,\n          placeholder: t(\n            \"editor.action.panel.hugging_face.placeholder.use_cache\",\n          ),\n        },\n        {\n          title: t(\"editor.action.panel.hugging_face.wait_for_model\"),\n          name: \"waitForModel\",\n          value: content.detailParams?.waitForModel,\n          placeholder: t(\n            \"editor.action.panel.hugging_face.placeholder.use_cache\",\n          ),\n        },\n        {\n          title: t(\"editor.action.panel.hugging_face.min_length\"),\n          name: \"minLength\",\n          value: content.detailParams?.minLength,\n          placeholder: t(\n            \"editor.action.panel.hugging_face.placeholder.min_length\",\n          ),\n        },\n        {\n          title: t(\"editor.action.panel.hugging_face.max_length\"),\n          name: \"maxLength\",\n          value: content.detailParams?.maxLength,\n          placeholder: t(\n            \"editor.action.panel.hugging_face.placeholder.min_length\",\n          ),\n        },\n\n        {\n          title: t(\"editor.action.panel.hugging_face.top_k\"),\n          name: \"topK\",\n          value: content.detailParams?.topK,\n          placeholder: t(\"editor.action.panel.hugging_face.placeholder.top_k\"),\n        },\n        {\n          title: t(\"editor.action.panel.hugging_face.top_p\"),\n          name: \"topP\",\n          value: content.detailParams?.topP,\n          placeholder: t(\"editor.action.panel.hugging_face.placeholder.top_p\"),\n        },\n\n        {\n          title: t(\"editor.action.panel.hugging_face.temperature\"),\n          name: \"temperature\",\n          value: content.detailParams?.temperature,\n          placeholder: t(\n            \"editor.action.panel.hugging_face.placeholder.temperature\",\n          ),\n          tips: t(\"editor.action.panel.hugging_face.tips.temperature\"),\n        },\n        {\n          title: t(\"editor.action.panel.hugging_face.repetition_penalty\"),\n          name: \"repetitionPenalty\",\n          value: content.detailParams?.repetitionPenalty,\n          placeholder: t(\n            \"editor.action.panel.hugging_face.placeholder.repetition_penalty\",\n          ),\n          tips: t(\"editor.action.panel.hugging_face.tips.repetition_penalty\"),\n        },\n        {\n          title: t(\"editor.action.panel.hugging_face.max_time\"),\n          name: \"maxTime\",\n          value: content.detailParams?.maxTime,\n          placeholder: t(\n            \"editor.action.panel.hugging_face.placeholder.max_time\",\n          ),\n        },\n      ].map(\n        (\n          {\n            title,\n            name,\n            value,\n            placeholder,\n            tips,\n          }: {\n            title: string\n            name: string\n            value: string\n            placeholder?: string\n            tips?: string\n          },\n          index: number,\n        ) => (\n          <InputEditor\n            key={index}\n            title={title}\n            value={value ?? \"\"}\n            onChange={(value) => handleParametersValueChange(value, name)}\n            expectedType={VALIDATION_TYPES.STRING}\n            placeholder={placeholder ?? \"\"}\n            tips={tips ?? \"\"}\n          />\n        ),\n      )}\n    </>\n  )\n}\n\nexport const HuggingFaceCommonPanel: FC<HuggingFaceCommonPanelProps> = (\n  props,\n) => {\n  const { withoutModel = false } = props\n  const { t } = useTranslation()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    HuggingFaceAction<HuggingFaceBodyContent>\n  >\n  const selectedAction = useSelector(getSelectedAction) as ActionItem<\n    HuggingFaceAction<HuggingFaceBodyContent>\n  >\n\n  const content =\n    cachedAction.content as HuggingFaceAction<HuggingFaceBodyContent>\n  const currentParameterType = content.inputs.type || \"text\"\n  const dispatch = useDispatch()\n\n  const handleURLClick = (link: string) => window.open(link, \"_blank\")\n\n  const handleValueChange = useCallback(\n    (key: string) => (value: string | boolean) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            [key]: value,\n          },\n        }),\n      )\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  const handleInputsValueChange = useCallback(\n    (value: HuggingFaceBodyContent) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            inputs: {\n              type: content.inputs.type,\n              content: value,\n            },\n          },\n        }),\n      )\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  const handleParameterChange = useCallback(\n    (value?: SelectValue) => {\n      let newBody =\n        value === \"pairs\"\n          ? HuggingFacePairsBodyInitital\n          : HuggingFaceInputInitial\n      if (\n        selectedAction.resourceID === cachedAction.resourceID &&\n        selectedAction.content?.inputs?.type === value\n      ) {\n        newBody = selectedAction.content.inputs.content\n      }\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            withDetailParams:\n              value === \"binary\" ? false : content.withDetailParams,\n            inputs: {\n              type: value as HuggingFaceParametesType,\n              content: newBody,\n            },\n          },\n        }),\n      )\n    },\n    [cachedAction, content, dispatch, selectedAction],\n  )\n\n  const handleOnAddKeys = useCallback(() => {\n    let newList: Params[] = [\n      ...((content.inputs.content as Params[]) ?? [{ key: \"\", value: \"\" }]),\n      { key: \"\", value: \"\" } as Params,\n    ]\n    handleInputsValueChange(newList)\n  }, [content, handleInputsValueChange])\n\n  const handleOnChangeKey = useCallback(\n    (index: number, key: string, value: string) => {\n      let newList: Params[] = [\n        ...((content.inputs.content as Params[]) ?? [{ key: \"\", value: \"\" }]),\n      ]\n      newList[index] = { key, value: value } as Params\n      handleInputsValueChange(newList)\n    },\n    [content, handleInputsValueChange],\n  )\n\n  const handleOnChangeValue = useCallback(\n    (index: number, key: string, value: string) => {\n      let newList: Params[] = [\n        ...((content.inputs.content as Params[]) ?? [{ key: \"\", value: \"\" }]),\n      ]\n      newList[index] = { key, value: value } as Params\n      handleInputsValueChange(newList)\n    },\n    [content, handleInputsValueChange],\n  )\n\n  const handleOnDeleteKey = useCallback(\n    (index: number, _record: Params) => {\n      let newList: Params[] = [\n        ...((content.inputs.content as Params[]) ?? [{ key: \"\", value: \"\" }]),\n      ]\n      newList.splice(index, 1)\n      handleInputsValueChange(newList)\n    },\n    [content, handleInputsValueChange],\n  )\n\n  const handleParametersValueChange = useCallback(\n    (value: string, key: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            detailParams: {\n              ...content.detailParams,\n              [key]: value,\n            },\n          },\n        }),\n      )\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  return (\n    <div css={actionItemContainer}>\n      {!withoutModel && (\n        <InputEditor\n          title={t(\"editor.action.panel.hugging_face.mode_id\")}\n          value={content.modelID ?? \"\"}\n          onChange={handleValueChange(\"modelID\")}\n          expectedType={VALIDATION_TYPES.STRING}\n          tips={\n            <Trans\n              i18nKey=\"editor.action.panel.hugging_face.tips.mode_id\"\n              t={t}\n              components={[\n                <TextLink\n                  key=\"editor.action.panel.hugging_face.tips.mode_id\"\n                  onClick={() => {\n                    handleURLClick(\"https://huggingface.co/models\")\n                  }}\n                />,\n              ]}\n            />\n          }\n        />\n      )}\n      <div css={bodyEditorContainerStyle}>\n        <span css={bodyLabelStyle}>\n          {t(\"editor.action.panel.hugging_face.parameter\")}\n        </span>\n        <div css={bodyChooserStyle}>\n          <div css={bodySelectorStyle}>\n            <Select\n              colorScheme=\"techPurple\"\n              showSearch={true}\n              defaultValue={content?.inputs?.type || \"text\"}\n              value={content?.inputs?.type || \"text\"}\n              w=\"100%\"\n              placeholder={t(\n                \"editor.action.panel.firebase.placeholder.select_an_action\",\n              )}\n              onChange={handleParameterChange}\n              options={ParametersTypeMap}\n            />\n          </div>\n          {currentParameterType === \"pairs\" && (\n            <RecordEditor\n              label=\"\"\n              records={\n                (content.inputs.content as Params[]) ?? [{ key: \"\", value: \"\" }]\n              }\n              onChangeKey={handleOnChangeKey}\n              onChangeValue={handleOnChangeValue}\n              onDelete={handleOnDeleteKey}\n              onAdd={handleOnAddKeys}\n              valueInputType={VALIDATION_TYPES.ANY}\n            />\n          )}\n          {(currentParameterType === \"binary\" ||\n            currentParameterType === \"json\") && (\n            <div css={codeEditorStyle}>\n              <CodeEditor\n                key={currentParameterType}\n                lang={CODE_LANG.JAVASCRIPT}\n                showLineNumbers\n                value={(content.inputs.content as string) ?? \"\"}\n                expectValueType={VALIDATION_TYPES.STRING}\n                height=\"88px\"\n                placeholder={\n                  currentParameterType === \"binary\"\n                    ? t(\"editor.action.panel.hugging_face.placeholder.binary\")\n                    : t(\"editor.action.panel.hugging_face.placeholder.json\")\n                }\n                onChange={handleInputsValueChange}\n              />\n            </div>\n          )}\n          {currentParameterType === \"text\" && (\n            <div css={textCodeEditorStyle}>\n              <CodeEditor\n                lang={CODE_LANG.JAVASCRIPT}\n                value={(content?.inputs.content ?? \"\") as string}\n                onChange={handleInputsValueChange}\n                expectValueType={VALIDATION_TYPES.STRING}\n                placeholder={t(\n                  \"editor.action.panel.hugging_face.placeholder.text\",\n                )}\n              />\n            </div>\n          )}\n        </div>\n      </div>\n      {currentParameterType !== \"binary\" && (\n        <SingleTypeComponent\n          componentType=\"checkbox\"\n          value={content.withDetailParams ?? false}\n          checkoutTitle={t(\n            \"editor.action.panel.hugging_face.use_detail_parameters\",\n          )}\n          onBooleanValueChange={handleValueChange(\"withDetailParams\")}\n          tips={\n            <Trans\n              i18nKey=\"editor.action.panel.hugging_face.tips.use_detail_parameters\"\n              t={t}\n              components={[\n                <TextLink\n                  key=\"editor.action.panel.hugging_face.tips.use_detail_parameters\"\n                  onClick={() => {\n                    handleURLClick(\n                      \"https://huggingface.co/docs/api-inference/detailed_parameters\",\n                    )\n                  }}\n                />,\n              ]}\n            />\n          }\n        />\n      )}\n      {content.withDetailParams && (\n        <>\n          {getDetailedParameters({ t, content, handleParametersValueChange })}\n        </>\n      )}\n      <TransformerComponent />\n    </div>\n  )\n}\n\nHuggingFaceCommonPanel.displayName = \"HuggingFaceCommonPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/HuggingFaceCommonPanel/interface.ts",
    "content": "export interface HuggingFaceCommonPanelProps {\n  withoutModel?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/HuggingFaceCommonPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n\nexport const textCodeEditorStyle = css`\n  width: 100%;\n  margin-top: 8px;\n  margin-bottom: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/HuggingFaceEndpointPanel/index.tsx",
    "content": "import { FC } from \"react\"\nimport { HuggingFaceCommonPanel } from \"@/page/App/components/Actions/ActionPanel/HuggingFaceCommonPanel\"\n\nconst HuggingFaceEndpointPanel: FC = () => {\n  return <HuggingFaceCommonPanel withoutModel />\n}\nHuggingFaceEndpointPanel.displayName = \"HuggingFaceEndpointPanel\"\nexport default HuggingFaceEndpointPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/HuggingFacePanel/index.tsx",
    "content": "import { FC } from \"react\"\nimport { HuggingFaceCommonPanel } from \"@/page/App/components/Actions/ActionPanel/HuggingFaceCommonPanel\"\n\nconst HuggingFacePanel: FC = () => {\n  return <HuggingFaceCommonPanel />\n}\n\nHuggingFacePanel.displayName = \"HuggingFacePanel\"\nexport default HuggingFacePanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/DeleteMultiplePart/index.tsx",
    "content": "import { ILLADriveDeleteMultipleContent } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { ILLADriveActionPartProps } from \"../interface\"\n\nexport const DeleteMultiplePart: FC<ILLADriveActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const commandArgs = props.commandArgs as ILLADriveDeleteMultipleContent\n  const { handleOptionsValueChange } = props\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.file_ids\")}\n        tips={t(\"editor.action.panel.label.tips.drive.file_ids\")}\n        placeholder={t(\"editor.action.panel.label.placeholder.drive.file_ids\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileIDs}\n        onChange={(value) => handleOptionsValueChange(\"fileIDs\", value)}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n    </>\n  )\n}\n\nDeleteMultiplePart.displayName = \"DeleteMultiplePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/DeleteOnePart/index.tsx",
    "content": "import { ILLADriveDeleteOneContent } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { ILLADriveActionPartProps } from \"../interface\"\n\nexport const DeleteOnePart: FC<ILLADriveActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const commandArgs = props.commandArgs as ILLADriveDeleteOneContent\n  const { handleOptionsValueChange } = props\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.file_id\")}\n        tips={t(\"editor.action.panel.label.tips.drive.file_id\")}\n        placeholder={t(\"editor.action.panel.label.placeholder.drive.file_id\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileID}\n        onChange={(value) => handleOptionsValueChange(\"fileID\", value)}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n    </>\n  )\n}\n\nDeleteOnePart.displayName = \"DeleteOnePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/DownloadMultiplePart/index.tsx",
    "content": "import { ILLADriveDownloadMultipleContent } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { ILLADriveActionPartProps } from \"../interface\"\n\nexport const DownloadMultiplePart: FC<ILLADriveActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const commandArgs = props.commandArgs as ILLADriveDownloadMultipleContent\n  const { handleOptionsValueChange } = props\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.file_ids\")}\n        tips={t(\"editor.action.panel.label.tips.drive.file_ids\")}\n        placeholder={t(\"editor.action.panel.label.placeholder.drive.file_ids\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileIDs}\n        onChange={(value) => handleOptionsValueChange(\"fileIDs\", value)}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n    </>\n  )\n}\n\nDownloadMultiplePart.displayName = \"DownloadMultiplePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/DownloadOnePart/index.tsx",
    "content": "import { ILLADriveDownloadOneContent } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { ILLADriveActionPartProps } from \"../interface\"\n\nexport const DownloadOnePart: FC<ILLADriveActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const commandArgs = props.commandArgs as ILLADriveDownloadOneContent\n  const { handleOptionsValueChange } = props\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.file_id\")}\n        tips={t(\"editor.action.panel.label.tips.drive.file_id\")}\n        placeholder={t(\"editor.action.panel.label.placeholder.drive.file_id\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileID}\n        onChange={(value) => handleOptionsValueChange(\"fileID\", value)}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n    </>\n  )\n}\n\nDownloadOnePart.displayName = \"DownloadOnePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/ListAllPart/index.tsx",
    "content": "import {\n  EXPIRATION_TYPE,\n  ILLADriveListAllContent,\n  ILLA_DRIVE_FILTER_TYPE,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { ILLADriveActionPartProps } from \"@/page/App/components/Actions/ActionPanel/ILLADrivePanel/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport FolderSelect from \"../components/FolderSelect\"\nimport SortOperate from \"../components/SortOperate\"\n\nexport const ListAllPart: FC<ILLADriveActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const commandArgs = props.commandArgs as ILLADriveListAllContent\n  const { handleOptionsValueChange } = props\n  const filterType = commandArgs.filterType\n  const expirationType = commandArgs.expirationType\n  const sortByeOptions = [\n    \"id\",\n    \"lastModifiedAt\",\n    \"lastModifiedBy\",\n    \"name\",\n    \"contentType\",\n    \"size\",\n  ]\n\n  const FileUrlExpiredTypeOption = [\n    {\n      label: t(\"editor.inspect.setter_option.drive_builder.expired_time.never\"),\n      value: EXPIRATION_TYPE.PERSISTENT,\n    },\n    {\n      label: t(\n        \"editor.inspect.setter_option.drive_builder.expired_time.customer\",\n      ),\n      value: EXPIRATION_TYPE.CUSTOM,\n    },\n  ]\n\n  const FilterTypeOption = [\n    {\n      label: t(\"editor.action.panel.label.option.drive.file_type.none\"),\n      value: ILLA_DRIVE_FILTER_TYPE.NONE,\n    },\n    {\n      label: t(\"editor.action.panel.label.option.drive.file_type.by_id\"),\n      value: ILLA_DRIVE_FILTER_TYPE.BY_ID,\n    },\n    {\n      label: t(\"editor.action.panel.label.option.drive.file_type.by_name\"),\n      value: ILLA_DRIVE_FILTER_TYPE.BY_NAME,\n    },\n  ]\n\n  return (\n    <>\n      <SingleTypeComponent\n        title={t(\"editor.action.panel.label.drive.filter_type\")}\n        tips={t(\"editor.action.panel.label.tips.drive.filter_type\")}\n        value={commandArgs.filterType}\n        componentType=\"select\"\n        type=\"button\"\n        forceEqualWidth={true}\n        onChange={(value) => handleOptionsValueChange(\"filterType\", value)}\n        options={FilterTypeOption}\n      />\n      {filterType === ILLA_DRIVE_FILTER_TYPE.BY_NAME && (\n        <InputEditor\n          title={t(\"editor.action.panel.label.drive.file_name\")}\n          tips={t(\"editor.action.panel.label.tips.drive.file_name\")}\n          placeholder={t(\n            \"editor.action.panel.label.placeholder.drive.file_name\",\n          )}\n          lineNumbers\n          mode={CODE_LANG.JAVASCRIPT}\n          value={commandArgs.search}\n          onChange={(value) => handleOptionsValueChange(\"search\", value)}\n          expectedType={VALIDATION_TYPES.STRING}\n        />\n      )}\n      {filterType === ILLA_DRIVE_FILTER_TYPE.BY_ID && (\n        <InputEditor\n          title={t(\"editor.action.panel.label.drive.file_id\")}\n          tips={t(\"editor.action.panel.label.tips.drive.file_id\")}\n          placeholder={t(\"editor.action.panel.label.placeholder.drive.file_id\")}\n          lineNumbers\n          mode={CODE_LANG.JAVASCRIPT}\n          value={commandArgs.fileID}\n          onChange={(value) => handleOptionsValueChange(\"fileID\", value)}\n          expectedType={VALIDATION_TYPES.STRING}\n        />\n      )}\n      <FolderSelect value={commandArgs.path} />\n\n      <SingleTypeComponent\n        title={t(\"editor.inspect.setter_label.drive_builder.expired_time\")}\n        tips={t(\"editor.inspect.setter_tips.drive_builder.expired_time\")}\n        value={commandArgs.expirationType}\n        componentType=\"radio-group\"\n        type=\"button\"\n        forceEqualWidth={true}\n        onChange={(value) => handleOptionsValueChange(\"expirationType\", value)}\n        radioOptions={FileUrlExpiredTypeOption}\n      />\n      {expirationType === EXPIRATION_TYPE.CUSTOM && (\n        <InputEditor\n          title={t(\"editor.inspect.setter_label.drive_builder.time\")}\n          tips={t(\"editor.inspect.setter_tips.drive_builder.time\")}\n          mode={CODE_LANG.JAVASCRIPT}\n          value={commandArgs.expiry}\n          onChange={(value) => handleOptionsValueChange(\"expiry\", value)}\n          expectedType={VALIDATION_TYPES.NUMBER}\n        />\n      )}\n      <SingleTypeComponent\n        title={t(\"editor.inspect.setter_label.drive_builder.turn_on_hotlink\")}\n        tips={t(\"editor.inspect.setter_tips.drive_builder.turn_on_hotlink\")}\n        value={commandArgs.hotlinkProtection}\n        componentType=\"switch\"\n        onChange={(value) =>\n          handleOptionsValueChange(\"hotlinkProtection\", value)\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.limit\")}\n        tips={t(\"editor.action.panel.label.tips.drive.limit\")}\n        placeholder={t(\"editor.action.panel.label.placeholder.drive.limit\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.limit}\n        onChange={(value) => handleOptionsValueChange(\"limit\", value)}\n        expectedType={VALIDATION_TYPES.NUMBER}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.page\")}\n        tips={t(\"editor.action.panel.label.tips.drive.page\")}\n        placeholder={t(\"editor.action.panel.label.placeholder.drive.page\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.page}\n        onChange={(value) => handleOptionsValueChange(\"page\", value)}\n        expectedType={VALIDATION_TYPES.NUMBER}\n      />\n      <SortOperate\n        sortByeOptions={sortByeOptions}\n        commandArgs={commandArgs}\n        handleOptionsValueChange={handleOptionsValueChange}\n      />\n    </>\n  )\n}\n\nListAllPart.displayName = \"ListAllPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/ListFolders/index.tsx",
    "content": "import {\n  ILLADriveListFoldersContent,\n  ILLA_DRIVE_FILTER_TYPE,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { ILLADriveActionPartProps } from \"@/page/App/components/Actions/ActionPanel/ILLADrivePanel/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport FolderSelect from \"../components/FolderSelect\"\nimport SortOperate from \"../components/SortOperate\"\n\nexport const ListFolders: FC<ILLADriveActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const commandArgs = props.commandArgs as ILLADriveListFoldersContent\n  const { handleOptionsValueChange } = props\n  const filterType = commandArgs.filterType\n\n  const sortByeOptions = [\n    \"id\",\n    \"lastModifiedAt\",\n    \"lastModifiedBy\",\n    \"name\",\n    \"fileNum\",\n    \"folderNum\",\n  ]\n\n  const FilterTypeOption = [\n    {\n      label: t(\"editor.action.panel.label.option.drive.file_type.none\"),\n      value: ILLA_DRIVE_FILTER_TYPE.NONE,\n    },\n    {\n      label: t(\"editor.action.panel.label.option.drive.file_type.by_id\"),\n      value: ILLA_DRIVE_FILTER_TYPE.BY_ID,\n    },\n    {\n      label: t(\"editor.action.panel.label.option.drive.file_type.by_name\"),\n      value: ILLA_DRIVE_FILTER_TYPE.BY_NAME,\n    },\n  ]\n\n  return (\n    <>\n      <SingleTypeComponent\n        title={t(\"editor.action.panel.label.drive.filter_type\")}\n        tips={t(\"editor.action.panel.label.tips.drive.filter_type\")}\n        value={commandArgs.filterType}\n        componentType=\"select\"\n        type=\"button\"\n        forceEqualWidth={true}\n        onChange={(value) => handleOptionsValueChange(\"filterType\", value)}\n        options={FilterTypeOption}\n      />\n      {filterType === ILLA_DRIVE_FILTER_TYPE.BY_ID && (\n        <InputEditor\n          title={t(\"editor.action.panel.label.drive.folder_name\")}\n          tips={t(\"editor.action.panel.label.tips.drive.folder_name\")}\n          lineNumbers\n          mode={CODE_LANG.JAVASCRIPT}\n          value={commandArgs.folderID}\n          onChange={(value) => handleOptionsValueChange(\"fileID\", value)}\n          expectedType={VALIDATION_TYPES.STRING}\n        />\n      )}\n      {filterType === ILLA_DRIVE_FILTER_TYPE.BY_NAME && (\n        <InputEditor\n          title={t(\"editor.action.panel.label.drive.file_name\")}\n          tips={t(\"editor.action.panel.label.tips.drive.file_name\")}\n          placeholder={t(\n            \"editor.action.panel.label.placeholder.drive.file_name\",\n          )}\n          lineNumbers\n          mode={CODE_LANG.JAVASCRIPT}\n          value={commandArgs.search}\n          onChange={(value) => handleOptionsValueChange(\"search\", value)}\n          expectedType={VALIDATION_TYPES.STRING}\n        />\n      )}\n      <FolderSelect value={commandArgs.path} />\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.limit\")}\n        tips={t(\"editor.action.panel.label.tips.drive.limit\")}\n        placeholder={t(\"editor.action.panel.label.placeholder.drive.limit\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.limit}\n        onChange={(value) => handleOptionsValueChange(\"limit\", value)}\n        expectedType={VALIDATION_TYPES.NUMBER}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.page\")}\n        tips={t(\"editor.action.panel.label.tips.drive.page\")}\n        placeholder={t(\"editor.action.panel.label.placeholder.drive.page\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.page}\n        onChange={(value) => handleOptionsValueChange(\"page\", value)}\n        expectedType={VALIDATION_TYPES.NUMBER}\n      />\n      <SortOperate\n        sortByeOptions={sortByeOptions}\n        commandArgs={commandArgs}\n        handleOptionsValueChange={handleOptionsValueChange}\n      />\n    </>\n  )\n}\n\nListFolders.displayName = \"ListFolders\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/UpdatePart/index.tsx",
    "content": "import { ILLADriveUpdateContent } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { ILLADriveActionPartProps } from \"../interface\"\n\nexport const UpdatePart: FC<ILLADriveActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const commandArgs = props.commandArgs as ILLADriveUpdateContent\n  const { handleOptionsValueChange } = props\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.file_id\")}\n        tips={t(\"editor.action.panel.label.tips.drive.file_id\")}\n        placeholder={t(\"editor.action.panel.label.placeholder.drive.file_id\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileID}\n        onChange={(value) => handleOptionsValueChange(\"fileID\", value)}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.target_file_name\")}\n        tips={t(\"editor.action.panel.label.tips.drive.target_file_name\")}\n        placeholder={t(\n          \"editor.action.panel.label.placeholder.drive.target_file_name\",\n        )}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileName}\n        onChange={(value) => handleOptionsValueChange(\"fileName\", value)}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n    </>\n  )\n}\n\nUpdatePart.displayName = \"UpdatePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/UploadMultiplePart/index.tsx",
    "content": "import { ILLADriveUploadMultipleContent } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { SingleTypeComponent } from \"../../SingleTypeComponent\"\nimport FolderSelect from \"../components/FolderSelect\"\nimport { ILLADriveActionPartProps } from \"../interface\"\n\nexport const UploadMultiplePart: FC<ILLADriveActionPartProps> = (props) => {\n  const { t } = useTranslation()\n\n  const commandArgs = props.commandArgs as ILLADriveUploadMultipleContent\n  const { handleOptionsValueChange } = props\n\n  return (\n    <>\n      <SingleTypeComponent\n        title={t(\"editor.action.panel.label.drive.overwrite\")}\n        tips={t(\"editor.action.panel.label.tips.drive.overwrite\")}\n        value={commandArgs.overwriteDuplicate}\n        componentType=\"switch\"\n        onChange={(value) =>\n          handleOptionsValueChange(\"overwriteDuplicate\", value)\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.file_name_array\")}\n        tips={t(\"editor.action.panel.label.drive.file_name_array\")}\n        placeholder={t(\"editor.action.panel.label.drive.file_name_array\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileNameArray}\n        onChange={(value) => handleOptionsValueChange(\"fileNameArray\", value)}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.file_data_array\")}\n        tips={t(\"editor.action.panel.label.tips.drive.file_data_array\")}\n        placeholder={t(\n          \"editor.action.panel.label.placeholder.drive.file_data_array\",\n        )}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileDataArray}\n        onChange={(value) => handleOptionsValueChange(\"fileDataArray\", value)}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n\n      <InputEditor\n        title={t(\"editor.action.panel.label.drive.file_type_array\")}\n        tips={t(\"editor.action.panel.label.tips.drive.file_type_array\")}\n        placeholder={t(\"editor.action.panel.label.placeholder.file_type_array\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileTypeArray}\n        onChange={(value) => handleOptionsValueChange(\"fileTypeArray\", value)}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n      <FolderSelect value={commandArgs.path} />\n    </>\n  )\n}\n\nUploadMultiplePart.displayName = \"UploadMultiplePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/UploadPart/index.tsx",
    "content": "import {\n  ILLADriveUploadOneContent,\n  ILLA_DRIVE_UPLOAD_FILE_TYPE,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { SingleTypeComponent } from \"../../SingleTypeComponent\"\nimport FolderSelect from \"../components/FolderSelect\"\nimport { ILLADriveActionPartProps } from \"../interface\"\n\nexport const UploadPart: FC<ILLADriveActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const commandArgs = props.commandArgs as ILLADriveUploadOneContent\n  const { handleOptionsValueChange } = props\n\n  const FileTypeOptions = [\n    {\n      label: t(\"editor.inspect.setter_option.file_download.auto\"),\n      value: ILLA_DRIVE_UPLOAD_FILE_TYPE.AUTO,\n    },\n    {\n      label: t(\"editor.inspect.setter_option.file_download.plain_text\"),\n      value: ILLA_DRIVE_UPLOAD_FILE_TYPE.TXT,\n    },\n    {\n      label: t(\"editor.inspect.setter_option.file_download.jpeg\"),\n      value: ILLA_DRIVE_UPLOAD_FILE_TYPE.JPEG,\n    },\n    {\n      label: t(\"editor.inspect.setter_option.file_download.png\"),\n      value: ILLA_DRIVE_UPLOAD_FILE_TYPE.PNG,\n    },\n    {\n      label: t(\"editor.inspect.setter_option.file_download.svg\"),\n      value: ILLA_DRIVE_UPLOAD_FILE_TYPE.SVG,\n    },\n    {\n      label: t(\"editor.inspect.setter_option.file_download.json\"),\n      value: ILLA_DRIVE_UPLOAD_FILE_TYPE.JSON,\n    },\n    {\n      label: t(\"editor.inspect.setter_option.file_download.csv\"),\n      value: ILLA_DRIVE_UPLOAD_FILE_TYPE.CSV,\n    },\n    {\n      label: t(\"editor.inspect.setter_option.file_download.tsv\"),\n      value: ILLA_DRIVE_UPLOAD_FILE_TYPE.TSV,\n    },\n    {\n      label: t(\"editor.inspect.setter_option.file_download.excel\"),\n      value: ILLA_DRIVE_UPLOAD_FILE_TYPE.XLSX,\n    },\n  ]\n\n  return (\n    <>\n      <SingleTypeComponent\n        title={t(\"editor.action.panel.label.drive.overwrite\")}\n        tips={t(\"editor.action.panel.label.tips.drive.overwrite\")}\n        value={commandArgs.overwriteDuplicate}\n        componentType=\"switch\"\n        onChange={(value) =>\n          handleOptionsValueChange(\"overwriteDuplicate\", value)\n        }\n      />\n      <InputEditor\n        title={t(\"editor.inspect.setter_label.file_download.file_name\")}\n        tips={t(\"editor.inspect.setter_tips.file_download.file_name\")}\n        placeholder={t(\n          \"editor.inspect.setter.placeholder.file_download.file_name\",\n        )}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileName}\n        onChange={(value) => handleOptionsValueChange(\"fileName\", value)}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.inspect.setter_label.drive_builder.fileData\")}\n        tips={t(\"editor.inspect.setter_tips.drive_builder.fileData\")}\n        placeholder={t(\n          \"editor.inspect.setter.placeholder.drive_builder.fileData\",\n        )}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.fileData}\n        onChange={(value) => handleOptionsValueChange(\"fileData\", value)}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <SingleTypeComponent\n        title={t(\"editor.inspect.setter_label.file_download.file_type\")}\n        tips={t(\"editor.inspect.setter_tips.file_download.file_type\")}\n        value={commandArgs.fileType}\n        onChange={(value) => handleOptionsValueChange(\"fileType\", value)}\n        componentType=\"select\"\n        options={FileTypeOptions}\n      />\n      <FolderSelect value={commandArgs.path} />\n    </>\n  )\n}\n\nUploadPart.displayName = \"UploadPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/components/BaseFxSelect/index.tsx",
    "content": "import { FC } from \"react\"\nimport { FxIcon } from \"@illa-design/react\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { containerStyle, getFxIconStyle } from \"./style\"\n\ninterface BaseFxSelectProps {\n  attrName: string\n  value: string\n  isFx: boolean\n  label: string\n  options: string[]\n  handleOptionsValueChange: (name: string, value: string | boolean) => void\n}\n\nexport const BaseFxSelect: FC<BaseFxSelectProps> = (props) => {\n  const { attrName, value, isFx, options, label, handleOptionsValueChange } =\n    props\n\n  const handleOnClick = () => {\n    handleOptionsValueChange(`${attrName}Fx`, !isFx)\n  }\n\n  return (\n    <div css={containerStyle}>\n      {isFx ? (\n        <InputEditor\n          title={label}\n          value={value}\n          onChange={(v) => handleOptionsValueChange(attrName, v as string)}\n          expectedType={VALIDATION_TYPES.STRING}\n        />\n      ) : (\n        <SingleTypeComponent\n          title={label}\n          componentType=\"select\"\n          value={value}\n          onChange={(v) => handleOptionsValueChange(attrName, v as string)}\n          options={options}\n        />\n      )}\n      <FxIcon onClick={handleOnClick} css={getFxIconStyle(isFx)} />\n    </div>\n  )\n}\nBaseFxSelect.displayName = \"BaseFxSelect\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/components/BaseFxSelect/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const containerStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  align-items: center;\n`\n\nexport const getFxIconStyle = (selected?: boolean) => {\n  return css`\n    width: 16px;\n    height: 16px;\n    color: ${selected\n      ? getColor(\"techPurple\", \"03\")\n      : getColor(\"grayBlue\", \"04\")};\n    cursor: pointer;\n    z-index: 1;\n    margin-right: 16px;\n    :hover {\n      cursor: pointer;\n      color: ${getColor(\"techPurple\", \"03\")};\n    }\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/components/FolderSelect/index.tsx",
    "content": "import { FC, useContext } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport Folder from \"@/assets/drive/panelFolder.svg?react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { FolderOperateModalContext } from \"@/components/FolderOperateModal/context\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { PathSelectContext } from \"../../provider\"\nimport {\n  actionItemCodeEditorStyle,\n  actionItemTip,\n  fileSelectContainerStyle,\n  folderIconStyle,\n  folderSelectStyle,\n  headerStyle,\n  inputContainerStyle,\n  nameStyle,\n} from \"./style\"\n\ninterface FolderSelectProps {\n  value: string\n}\n\nconst FolderSelect: FC<FolderSelectProps> = ({ value }) => {\n  const { t } = useTranslation()\n  const { setFolderOperateVisible } = useContext(FolderOperateModalContext)\n  const { handleOptionsValueChange } = useContext(PathSelectContext)\n  return (\n    <div css={folderSelectStyle}>\n      <div css={headerStyle}>\n        <span css={nameStyle}>\n          {t(\"editor.action.panel.label.drive.folder\")}\n        </span>\n        <div\n          css={fileSelectContainerStyle}\n          onClick={() => setFolderOperateVisible(true)}\n        >\n          <span css={folderIconStyle}>\n            <Folder />\n          </span>\n          <span>{t(\"drive.upload.select.select_entry\")}</span>\n        </div>\n      </div>\n      <div css={inputContainerStyle}>\n        <CodeEditor\n          singleLine\n          wrapperCss={actionItemCodeEditorStyle}\n          lang={CODE_LANG.JAVASCRIPT}\n          value={value}\n          onChange={(value) => handleOptionsValueChange(\"path\", value)}\n          expectValueType={VALIDATION_TYPES.STRING}\n          modalTitle={t(\"editor.action.panel.label.drive.folder\")}\n        />\n        <div css={actionItemTip}>\n          <span>{t(\"editor.action.panel.label.tips.drive.folder\")}</span>\n        </div>\n      </div>\n    </div>\n  )\n}\n\nexport default FolderSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/components/FolderSelect/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const folderSelectStyle = css`\n  width: 100%;\n  display: flex;\n  padding: 8px 16px;\n  flex-direction: column;\n  justify-content: center;\n  align-items: flex-end;\n  gap: 8px;\n`\n\nexport const fileSelectContainerStyle = css`\n  display: flex;\n  padding: 1px 8px;\n  justify-content: center;\n  align-items: center;\n  gap: 4px;\n  cursor: pointer;\n  & > span {\n    color: ${getColor(\"grayBlue\", \"02\")};\n    font-size: 14px;\n    font-style: normal;\n    font-weight: 500;\n    line-height: 22px;\n    text-transform: capitalize;\n  }\n`\nexport const folderIconStyle = css`\n  width: 16px;\n  height: 16px;\n`\n\nexport const headerStyle = css`\n  display: flex;\n  width: 100%;\n  justify-content: space-between;\n  align-items: center;\n`\n\nexport const actionItemTip = css`\n  font-size: 14px;\n  white-space: pre-line;\n  padding-left: 16px;\n  min-height: 30px;\n  padding-bottom: 8px;\n  display: flex;\n  align-items: stretch;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  align-self: flex-start;\n`\n\nexport const inputContainerStyle = css`\n  width: 100%;\n  display: flex;\n  position: relative;\n  padding-left: 160px;\n  padding-right: 16px;\n  flex-direction: column;\n`\n\nexport const actionItemCodeEditorStyle = css`\n  width: 100%;\n  margin: 0 0 8px 16px;\n`\n\nexport const nameStyle = css`\n  display: flex;\n  width: 160px;\n  justify-content: flex-end;\n  align-items: center;\n  gap: 4px;\n  flex-shrink: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/components/PathOperate/index.tsx",
    "content": "import { useContext } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button } from \"@illa-design/react\"\nimport { FolderOperateModalContext } from \"@/components/FolderOperateModal/context\"\nimport { PathSelectContext } from \"../../provider\"\n\nconst PathOperate = () => {\n  const { handleOptionsValueChange } = useContext(PathSelectContext)\n  const { currentFolderPath, setFolderOperateVisible } = useContext(\n    FolderOperateModalContext,\n  )\n  const { t } = useTranslation()\n  const handleClick = () => {\n    handleOptionsValueChange(\"path\", `/${currentFolderPath}`)\n    setFolderOperateVisible(false)\n  }\n  return (\n    <Button colorScheme=\"techPurple\" onClick={handleClick}>\n      <span>{t(\"drive.upload.select.confirm_button\")}</span>\n    </Button>\n  )\n}\nexport default PathOperate\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/components/PathOperate/style.ts",
    "content": ""
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/components/SortOperate/index.tsx",
    "content": "import {\n  ILLADriveListAllContent,\n  ILLADriveListFoldersContent,\n  SORTED_TYPE,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { BaseFxSelect } from \"../BaseFxSelect\"\nimport { containerStyle } from \"./style\"\n\ninterface SortOperateProps {\n  commandArgs: ILLADriveListAllContent | ILLADriveListFoldersContent\n  sortByeOptions: string[]\n  handleOptionsValueChange: (name: string, value: string | boolean) => void\n}\n\nconst SortOperate: FC<SortOperateProps> = ({\n  sortByeOptions,\n  commandArgs,\n  handleOptionsValueChange,\n}) => {\n  const { t } = useTranslation()\n  const sortTypeOptions = [SORTED_TYPE.ascend, SORTED_TYPE.descend]\n\n  return (\n    <div css={containerStyle}>\n      <BaseFxSelect\n        attrName=\"sortedBy\"\n        label={t(\"editor.action.panel.label.drive.sort_by\")}\n        isFx={commandArgs.sortedByFx}\n        value={commandArgs.sortedBy}\n        options={sortByeOptions}\n        handleOptionsValueChange={handleOptionsValueChange}\n      />\n      <BaseFxSelect\n        attrName=\"sortedType\"\n        label={t(\"editor.action.panel.label.drive.sort_direction\")}\n        isFx={commandArgs.sortedTypeFx}\n        value={commandArgs.sortedType}\n        options={sortTypeOptions}\n        handleOptionsValueChange={handleOptionsValueChange}\n      />\n    </div>\n  )\n}\n\nexport default SortOperate\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/components/SortOperate/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  width: 100%;\n  display: flex;\n  justify-content: flex-end;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/constants.ts",
    "content": "export const PAGESIZE = 10\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/index.tsx",
    "content": "import {\n  ILLADriveDeleteMultipleContentInitial,\n  ILLADriveDeleteOneContentInitial,\n  ILLADriveDownloadMultipleContentInitial,\n  ILLADriveDownloadOneContentInitial,\n  ILLADriveListAllContentInitial,\n  ILLADriveListFoldersContentInitial,\n  ILLADriveUpdateContentInitial,\n  ILLADriveUploadMultipleContentInitial,\n  ILLADriveUploadOneContentInitial,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  ILLADriveAction,\n  ILLADriveActionTypeContent,\n  ILLA_DRIVE_ACTION_REQUEST_TYPE,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport FolderOperateModal from \"@/components/FolderOperateModal\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { PathSelectProvider } from \"./provider\"\nimport { actionItemContainer } from \"./style\"\nimport { getInputBody } from \"./utils\"\n\nconst ILLADrivePanel: FC = () => {\n  const { t } = useTranslation()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    ILLADriveAction<ILLADriveActionTypeContent>\n  >\n  const selectedAction = useSelector(getSelectedAction)!\n  const dispatch = useDispatch()\n  let content =\n    cachedAction.content as ILLADriveAction<ILLADriveActionTypeContent>\n\n  const handleOptionsValueChange = useCallback(\n    (name: string, value: string | boolean) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            commandArgs: {\n              ...cachedAction.content.commandArgs,\n              [name]: value,\n            },\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch],\n  )\n\n  const renderInputBody = getInputBody(content, handleOptionsValueChange)\n\n  const handleActionChange = (value: ILLA_DRIVE_ACTION_REQUEST_TYPE) => {\n    let newCommandArgs: ILLADriveActionTypeContent =\n      ILLADriveListAllContentInitial\n    if (\n      cachedAction.resourceID === selectedAction.resourceID &&\n      (selectedAction.content as ILLADriveAction<ILLADriveActionTypeContent>)\n        .operation === value\n    ) {\n      newCommandArgs = (\n        selectedAction.content as ILLADriveAction<ILLADriveActionTypeContent>\n      ).commandArgs\n    } else {\n      switch (value) {\n        case ILLA_DRIVE_ACTION_REQUEST_TYPE.LIST:\n          newCommandArgs = ILLADriveListAllContentInitial\n          break\n        case ILLA_DRIVE_ACTION_REQUEST_TYPE.LIST_FOLDERS:\n          newCommandArgs = ILLADriveListFoldersContentInitial\n          break\n        case ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_ONE:\n          newCommandArgs = ILLADriveDownloadOneContentInitial\n          break\n        case ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_MULTIPLE:\n          newCommandArgs = ILLADriveDownloadMultipleContentInitial\n          break\n        case ILLA_DRIVE_ACTION_REQUEST_TYPE.DELETE_ONE:\n          newCommandArgs = ILLADriveDeleteOneContentInitial\n          break\n        case ILLA_DRIVE_ACTION_REQUEST_TYPE.DELETE_MULTIPLE:\n          newCommandArgs = ILLADriveDeleteMultipleContentInitial\n          break\n        case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD:\n          newCommandArgs = ILLADriveUploadOneContentInitial\n          break\n        case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD_MULTIPLE:\n          newCommandArgs = ILLADriveUploadMultipleContentInitial\n        case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPDATE:\n          newCommandArgs = ILLADriveUpdateContentInitial\n          break\n      }\n    }\n    dispatch(\n      configActions.updateCachedAction({\n        ...cachedAction,\n        content: {\n          ...cachedAction.content,\n          operation: value,\n          commandArgs: newCommandArgs,\n        },\n      }),\n    )\n  }\n\n  const ILLADriveActionList = [\n    {\n      label: t(\"editor.action.panel.label.option.drive.method.list\"),\n      value: ILLA_DRIVE_ACTION_REQUEST_TYPE.LIST,\n    },\n    // not support yet\n    // {\n    //   label: t(\"editor.action.panel.label.option.drive.method.list_folders\"),\n    //   value: ILLA_DRIVE_ACTION_REQUEST_TYPE.LIST_FOLDERS,\n    // }\n    {\n      label: t(\"editor.action.panel.label.option.drive.method.download\"),\n      value: ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_ONE,\n    },\n    {\n      label: t(\n        \"editor.action.panel.label.option.drive.method.download_multi_file\",\n      ),\n      value: ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_MULTIPLE,\n    },\n    {\n      label: t(\"editor.action.panel.label.option.drive.method.delete\"),\n      value: ILLA_DRIVE_ACTION_REQUEST_TYPE.DELETE_ONE,\n    },\n    {\n      label: t(\n        \"editor.action.panel.label.option.drive.method.delete_multi_file\",\n      ),\n      value: ILLA_DRIVE_ACTION_REQUEST_TYPE.DELETE_MULTIPLE,\n    },\n    {\n      label: t(\"editor.action.panel.label.option.drive.method.upload_file\"),\n      value: ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD,\n    },\n    {\n      label: t(\n        \"editor.action.panel.label.option.drive.method.upload_multi_file\",\n      ),\n      value: ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD_MULTIPLE,\n    },\n    {\n      label: t(\"editor.action.panel.label.option.drive.method.update\"),\n      value: ILLA_DRIVE_ACTION_REQUEST_TYPE.UPDATE,\n    },\n  ]\n\n  return (\n    <PathSelectProvider handleOptionsValueChange={handleOptionsValueChange}>\n      <div css={actionItemContainer}>\n        <SingleTypeComponent\n          title={t(\"editor.action.panel.label.drive.method\")}\n          tips={t(\"editor.action.panel.label.tips.drive.method\")}\n          componentType=\"select\"\n          value={content.operation}\n          showSearch\n          onChange={handleActionChange}\n          options={ILLADriveActionList}\n        />\n        {renderInputBody}\n        <TransformerComponent />\n      </div>\n      <FolderOperateModal />\n    </PathSelectProvider>\n  )\n}\n\nILLADrivePanel.displayName = \"ILLADrivePanel\"\nexport default ILLADrivePanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/interface.ts",
    "content": "import { ILLADriveActionTypeContent } from \"@illa-public/public-types\"\n\nexport interface ILLADriveActionPartProps {\n  commandArgs: ILLADriveActionTypeContent\n  handleOptionsValueChange: (name: string, value: string | boolean) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/provider.tsx",
    "content": "import { FC, ReactNode, createContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  FolderOperateModalContext,\n  ROOT_PATH,\n} from \"@/components/FolderOperateModal\"\nimport PathOperate from \"./components/PathOperate\"\n\ninterface Injected {\n  handleOptionsValueChange: (name: string, value: string) => void\n}\n\ninterface FileUploadProviderProps {\n  children: ReactNode\n  handleOptionsValueChange: (name: string, value: string) => void\n}\n\nexport const PathSelectContext = createContext<Injected>({} as Injected)\n\nexport const PathSelectProvider: FC<FileUploadProviderProps> = ({\n  children,\n  handleOptionsValueChange,\n}) => {\n  const { t } = useTranslation()\n  const [currentFolderPath, setCurrentFolderPath] = useState(ROOT_PATH)\n  const [folderOperateVisible, setFolderOperateVisible] = useState(false)\n  const [createFolderVisible, setCreateFolderVisible] = useState(false)\n\n  return (\n    <PathSelectContext.Provider\n      value={{\n        handleOptionsValueChange,\n      }}\n    >\n      <FolderOperateModalContext.Provider\n        value={{\n          subTitle: t(\"drive.upload.modal.select_folder\"),\n          currentFolderPath,\n          folderOperateVisible,\n          createFolderVisible,\n          setCreateFolderVisible,\n          setCurrentFolderPath,\n          setFolderOperateVisible,\n          operateChildren: <PathOperate />,\n        }}\n      >\n        {children}\n      </FolderOperateModalContext.Provider>\n    </PathSelectContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/ILLADrivePanel/utils.tsx",
    "content": "import {\n  ILLADriveAction,\n  ILLADriveActionTypeContent,\n  ILLA_DRIVE_ACTION_REQUEST_TYPE,\n} from \"@illa-public/public-types\"\nimport { DeleteMultiplePart } from \"./DeleteMultiplePart\"\nimport { DeleteOnePart } from \"./DeleteOnePart\"\nimport { DownloadMultiplePart } from \"./DownloadMultiplePart\"\nimport { DownloadOnePart } from \"./DownloadOnePart\"\nimport { ListAllPart } from \"./ListAllPart\"\nimport { ListFolders } from \"./ListFolders\"\nimport { UpdatePart } from \"./UpdatePart\"\nimport { UploadMultiplePart } from \"./UploadMultiplePart\"\nimport { UploadPart } from \"./UploadPart\"\n\nexport const getInputBody = (\n  content: ILLADriveAction<ILLADriveActionTypeContent>,\n  handleOptionsValueChange: (name: string, value: string | boolean) => void,\n) => {\n  switch (content.operation) {\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.LIST:\n      return (\n        <ListAllPart\n          handleOptionsValueChange={handleOptionsValueChange}\n          commandArgs={content.commandArgs}\n        />\n      )\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.LIST_FOLDERS:\n      return (\n        <ListFolders\n          handleOptionsValueChange={handleOptionsValueChange}\n          commandArgs={content.commandArgs}\n        />\n      )\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_ONE:\n      return (\n        <DownloadOnePart\n          handleOptionsValueChange={handleOptionsValueChange}\n          commandArgs={content.commandArgs}\n        />\n      )\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_MULTIPLE:\n      return (\n        <DownloadMultiplePart\n          commandArgs={content.commandArgs}\n          handleOptionsValueChange={handleOptionsValueChange}\n        />\n      )\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.DELETE_ONE:\n      return (\n        <DeleteOnePart\n          handleOptionsValueChange={handleOptionsValueChange}\n          commandArgs={content.commandArgs}\n        />\n      )\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.DELETE_MULTIPLE:\n      return (\n        <DeleteMultiplePart\n          commandArgs={content.commandArgs}\n          handleOptionsValueChange={handleOptionsValueChange}\n        />\n      )\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD:\n      return (\n        <UploadPart\n          handleOptionsValueChange={handleOptionsValueChange}\n          commandArgs={content.commandArgs}\n        />\n      )\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD_MULTIPLE:\n      return (\n        <UploadMultiplePart\n          commandArgs={content.commandArgs}\n          handleOptionsValueChange={handleOptionsValueChange}\n        />\n      )\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPDATE:\n      return (\n        <UpdatePart\n          handleOptionsValueChange={handleOptionsValueChange}\n          commandArgs={content.commandArgs}\n        />\n      )\n    default:\n      return <></>\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/GeneralPanelLayout/constants.ts",
    "content": "export const NO_OPTIONS_HEADER = [\"transformer\", \"globalData\"]\nexport const NO_EVENT_HANDLER = [\"transformer\", \"globalData\"]\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/GeneralPanelLayout/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Space } from \"@illa-design/react\"\nimport { ActionEventHandler } from \"@/page/App/components/Actions/ActionPanel/ActionEventHandler\"\nimport PanelHeader from \"@/page/App/components/Actions/ActionPanel/PanelHeader\"\nimport { AIAgentResourceChoose } from \"@/page/App/components/Actions/ActionPanel/PanelHeader/AIAgentResourceChoose\"\nimport MockOperation from \"@/page/App/components/Actions/ActionPanel/PanelHeader/MockOperation\"\nimport TriggerModeChoose from \"@/page/App/components/Actions/ActionPanel/PanelHeader/TriggerModeChoose\"\nimport { NO_EVENT_HANDLER, NO_OPTIONS_HEADER } from \"./constants\"\nimport { GeneralPanelLayoutProps } from \"./interface\"\nimport {\n  actionContainerStyle,\n  headerOptionContainerStyle,\n  headerOptionTitleStyle,\n  spaceStyle,\n} from \"./style\"\n\nconst MockPanelHeader: FC = () => {\n  const { t } = useTranslation()\n  return (\n    <>\n      <div css={headerOptionContainerStyle}>\n        <span css={headerOptionTitleStyle}>\n          {t(\"editor.action.panel.option.trigger.label\")}\n        </span>\n        <TriggerModeChoose />\n      </div>\n      <Space w=\"100%\" h=\"8px\" css={spaceStyle} disp=\"block\" />\n    </>\n  )\n}\n\nconst DataPanelHeader: FC<Pick<GeneralPanelLayoutProps, \"actionType\">> = ({\n  actionType,\n}) => {\n  const { t } = useTranslation()\n  switch (actionType) {\n    case \"aiagent\": {\n      return <AIAgentResourceChoose />\n    }\n    case \"illadrive\": {\n      return (\n        <>\n          <div css={headerOptionContainerStyle}>\n            <span css={headerOptionTitleStyle}>\n              {t(\"editor.action.panel.option.trigger.label\")}\n            </span>\n            <TriggerModeChoose />\n          </div>\n          <Space w=\"100%\" h=\"8px\" css={spaceStyle} disp=\"block\" />\n        </>\n      )\n    }\n    case \"transformer\":\n    case \"globalData\":\n      return null\n    default: {\n      return <PanelHeader />\n    }\n  }\n}\n\nconst GeneralPanelLayout: FC<GeneralPanelLayoutProps> = ({\n  actionType,\n  mockEnabled,\n  children,\n}) => {\n  if (!actionType) return null\n  return (\n    <>\n      {!NO_OPTIONS_HEADER.includes(actionType) && (\n        <MockOperation enableMock={!!mockEnabled} />\n      )}\n      <div css={actionContainerStyle}>\n        {mockEnabled ? (\n          <MockPanelHeader />\n        ) : (\n          <DataPanelHeader actionType={actionType} />\n        )}\n        {children}\n        {!NO_EVENT_HANDLER.includes(actionType) && <ActionEventHandler />}\n      </div>\n    </>\n  )\n}\n\nexport default GeneralPanelLayout\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/GeneralPanelLayout/interface.ts",
    "content": "import { ActionType } from \"@illa-public/public-types\"\nimport { ReactNode } from \"react\"\n\nexport interface GeneralPanelLayoutProps {\n  children: ReactNode\n  mockEnabled?: boolean\n  actionType?: ActionType\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/GeneralPanelLayout/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const actionContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n`\n\nexport const spaceStyle = css`\n  border-bottom: 1px solid ${getColor(\"grayBlue\", \"08\")};\n`\n\nexport const headerOptionContainerStyle = css`\n  display: flex;\n  padding: 8px 16px;\n  justify-content: space-between;\n  align-items: center;\n`\n\nexport const headerOptionTitleStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/HorizontalWithLabel/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport ActionPanelLabel from \"../Label\"\nimport { HorizontalWithLabelProps } from \"./interface\"\nimport { horizontalWithLabelContainerStyle } from \"./style\"\n\nconst HorizontalWithLabel: FC<HorizontalWithLabelProps> = (props) => {\n  const { labelName, children } = props\n  return (\n    <div css={horizontalWithLabelContainerStyle}>\n      <ActionPanelLabel name={labelName} />\n      {children}\n    </div>\n  )\n}\n\nHorizontalWithLabel.displayName = \"HorizontalWithLabel\"\n\nexport default memo(HorizontalWithLabel)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/HorizontalWithLabel/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface HorizontalWithLabelProps {\n  labelName: string\n  children: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/HorizontalWithLabel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const horizontalWithLabelContainerStyle = css`\n  width: 100%;\n  display: flex;\n  padding: 8px 16px;\n  gap: 16px;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/Label/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { ActionPanelLabelProps } from \"./interface\"\nimport { actionPanelLabelContainerStyle } from \"./style\"\n\nconst ActionPanelLabel: FC<ActionPanelLabelProps> = (props) => {\n  const { name } = props\n  return <span css={actionPanelLabelContainerStyle}>{name}</span>\n}\n\nActionPanelLabel.displayName = \"ActionPanelLabel\"\n\nexport default memo(ActionPanelLabel)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/Label/interface.ts",
    "content": "export interface ActionPanelLabelProps {\n  name: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/Label/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const actionPanelLabelContainerStyle = css`\n  width: 160px;\n  flex-shrink: 0;\n  text-align: right;\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/Space/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { spaceStyle } from \"./style\"\n\nconst ActionPanelSpace: FC = () => {\n  return <div css={spaceStyle} />\n}\n\nActionPanelSpace.displayName = \"ActionPanelSpace\"\n\nexport default memo(ActionPanelSpace)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/Layout/Space/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const spaceStyle = css`\n  width: 100%;\n  height: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MicrosoftSqlPanel/MSSQLGUIMode/index.tsx",
    "content": "import { MicrosoftSqlActionGUIMode } from \"@illa-public/public-types\"\nimport { FC, useCallback, useEffect, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { createMessage } from \"@illa-design/react\"\nimport { MSSQLModeProps } from \"@/page/App/components/Actions/ActionPanel/MicrosoftSqlPanel/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { fetchResourceMeta } from \"@/services/resource\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const MSSQLGUIMode: FC<MSSQLModeProps> = (props) => {\n  const { modeContent, onChange, resourceID } = props\n  const message = createMessage()\n  const newModeContent = modeContent as MicrosoftSqlActionGUIMode\n  const { t } = useTranslation()\n  const [collectionSelect, setCollectionSelect] = useState<string[]>([])\n  const [loading, setLoading] = useState<boolean>(false)\n  const [error, setError] = useState<boolean>(false)\n\n  const handleRequestError = useCallback(() => {\n    setError(true)\n    setLoading(false)\n    message.error({\n      type: \"error\",\n      content: t(\"editor.action.message.mssql.table_error\"),\n    })\n  }, [message, t])\n\n  useEffect(() => {\n    if (!resourceID) {\n      return\n    }\n    setLoading(true)\n    fetchResourceMeta(resourceID)\n      .then(\n        ({ data }) => {\n          const tables = Object.keys(data.Schema ?? {}).map((key) => key)\n          setCollectionSelect(tables)\n          setLoading(false)\n          setError(false)\n        },\n        () => {\n          handleRequestError()\n        },\n      )\n      .finally(() => {\n        setLoading(false)\n      })\n  }, [handleRequestError, resourceID])\n\n  return (\n    <>\n      <SingleTypeComponent\n        componentType=\"select\"\n        placeholder={t(\"editor.action.panel.mssql.placeholder.table\")}\n        onSelectedValueChange={(value) =>\n          onChange((value || \"\") as string, \"table\")\n        }\n        options={collectionSelect}\n        value={newModeContent.table}\n        showSearch={true}\n        title={t(\"editor.action.panel.mssql.table\")}\n        loading={loading}\n        error={error}\n      />\n      <InputEditor\n        style={{ height: \"88px\" }}\n        title={t(\"editor.action.panel.mssql.insert_record\")}\n        placeholder={t(\"editor.action.panel.mssql.placeholder.insert_record\")}\n        lineNumbers={true}\n        expectedType={VALIDATION_TYPES.ARRAY}\n        value={newModeContent.records}\n        onChange={(value) => onChange(value, \"records\")}\n      />\n    </>\n  )\n}\nMSSQLGUIMode.displayName = \"MSSQLGUIMode\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MicrosoftSqlPanel/MSSQLSqlMode/index.tsx",
    "content": "import { MicrosoftSqlActionSqlMode } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { MSSQLModeProps } from \"@/page/App/components/Actions/ActionPanel/MicrosoftSqlPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\n\nexport const MSSQLSqlMode: FC<MSSQLModeProps> = (props) => {\n  const { modeContent, showSafeModeTips, onChange } = props\n  const { t } = useTranslation()\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.mssql.query\")}\n      style={{ height: \"88px\" }}\n      placeholder={t(\"editor.action.panel.mssql.placeholder.query\")}\n      lineNumbers={true}\n      value={(modeContent as MicrosoftSqlActionSqlMode).sql}\n      onChange={(value) => onChange(value, \"sql\")}\n      showSafeModeTips={showSafeModeTips}\n    />\n  )\n}\nMSSQLSqlMode.displayName = \"MSSQLSqlMode\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MicrosoftSqlPanel/index.tsx",
    "content": "import {\n  MicrosoftSqlActionGUIModeInitial,\n  MicrosoftSqlActionSqlModeInitial,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  MicrosoftSqlAction,\n  MicrosoftSqlActionType,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Trigger } from \"@illa-design/react\"\nimport { ILLAMarkdown } from \"@/components/ILLAMarkdown\"\nimport { MSSQLGUIMode } from \"@/page/App/components/Actions/ActionPanel/MicrosoftSqlPanel/MSSQLGUIMode\"\nimport { MSSQLSqlMode } from \"@/page/App/components/Actions/ActionPanel/MicrosoftSqlPanel/MSSQLSqlMode\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { actionItemContainer } from \"@/page/App/components/Actions/ActionPanel/style\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { SQLModeSelector } from \"../pulicComponent/SQLModeSelector\"\nimport {\n  labelContainerStyle,\n  labelStyle,\n  labelTipsStyle,\n  modeContainerStyle,\n} from \"./style\"\n\nconst ConfigTypeOptions = [\n  {\n    value: \"sql\",\n    label: \"SQL\",\n  },\n  {\n    value: \"gui\",\n    label: \"Bulk insert\",\n  },\n]\n\ntype MSSQLActionType = MicrosoftSqlAction<MicrosoftSqlActionType>\n\nconst MicrosoftSqlPanel: FC = () => {\n  const { t } = useTranslation()\n  const cachedAction = useSelector(\n    getCachedAction,\n  ) as ActionItem<MSSQLActionType>\n  const selectedAction = useSelector(\n    getSelectedAction,\n  ) as ActionItem<MSSQLActionType>\n  const content = cachedAction.content\n  const selectedContent = selectedAction.content\n  const dispatch = useDispatch()\n\n  const sqlModeInitial =\n    content.mode === \"sql\" || content.mode === \"sql-safe\"\n      ? content.query\n      : MicrosoftSqlActionSqlModeInitial\n  const guiModeInitial =\n    content.mode === \"gui\" ? content.query : MicrosoftSqlActionGUIModeInitial\n\n  const handleValueChange = useCallback(\n    (value: string) => {\n      const isSameModeWithCached = value === selectedContent.mode\n      const { query } = selectedContent\n      const initialMode =\n        value === \"sql\"\n          ? MicrosoftSqlActionSqlModeInitial\n          : MicrosoftSqlActionGUIModeInitial\n\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            mode: value,\n            query: {\n              ...(isSameModeWithCached ? query : initialMode),\n            },\n          } as MSSQLActionType,\n        }),\n      )\n    },\n    [cachedAction, selectedContent, dispatch],\n  )\n  const handleQueryChange = useCallback(\n    (value: string, name: string) => {\n      if (!value) {\n        return\n      }\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            query: {\n              ...content.query,\n              [name]: value,\n            },\n          } as MSSQLActionType,\n        }),\n      )\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  return (\n    <div css={actionItemContainer}>\n      <SingleTypeComponent\n        componentType=\"radio-group\"\n        type=\"button\"\n        title={t(\"editor.action.panel.mssql.config_type\")}\n        forceEqualWidth={true}\n        onChange={handleValueChange}\n        value={\n          content.mode === \"sql\" || content.mode === \"sql-safe\" ? \"sql\" : \"gui\"\n        }\n        radioOptions={ConfigTypeOptions}\n      />\n      {content.mode === \"sql\" || content.mode === \"sql-safe\" ? (\n        <MSSQLSqlMode\n          modeContent={sqlModeInitial}\n          onChange={handleQueryChange}\n          showSafeModeTips={content.mode === \"sql-safe\"}\n        />\n      ) : (\n        <MSSQLGUIMode\n          modeContent={guiModeInitial}\n          onChange={handleQueryChange}\n          resourceID={cachedAction.resourceID}\n        />\n      )}\n      {(content.mode === \"sql\" || content.mode === \"sql-safe\") && (\n        <div css={modeContainerStyle}>\n          <div css={labelContainerStyle}>\n            <Trigger\n              content={\n                <ILLAMarkdown\n                  textString={t(\n                    \"editor.action.panel.label.tips.general.safe_mode\",\n                  )}\n                />\n              }\n              trigger=\"hover\"\n              position=\"left\"\n              maxW=\"240px\"\n            >\n              <span css={labelStyle}>\n                {t(\"editor.action.panel.label.general.safe_mode\")}\n                <span css={labelTipsStyle} />\n              </span>\n            </Trigger>\n          </div>\n          <SQLModeSelector />\n        </div>\n      )}\n      <TransformerComponent />\n    </div>\n  )\n}\nMicrosoftSqlPanel.displayName = \"MicrosoftSqlPanel\"\nexport default MicrosoftSqlPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MicrosoftSqlPanel/interface.ts",
    "content": "import { MicrosoftSqlActionType } from \"@illa-public/public-types\"\n\nexport interface MSSQLModeProps {\n  modeContent: MicrosoftSqlActionType\n  onChange: (value: string, name: string) => void\n  resourceID?: string\n  showSafeModeTips?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MicrosoftSqlPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const labelContainerStyle = css`\n  width: 160px;\n  text-align: right;\n`\n\nexport const labelStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n\n  position: relative;\n`\n\nexport const labelTipsStyle = css`\n  position: absolute;\n  bottom: -2px;\n  left: 0;\n  width: 100%;\n  border-bottom: 1px dashed ${getColor(\"grayBlue\", \"06\")};\n`\n\nexport const modeContainerStyle = css`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 12px 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/AggregatePart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbAggregateContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const AggregatePart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbAggregateContent\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              [name]: value,\n            } as MongoDbAggregateContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.aggregation\")}\n        value={typeContent.aggregation}\n        onChange={handleValueChange(\"aggregation\")}\n        style={{ height: \"188px\" }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.EXPRESSION}\n        placeholder={\n          \"[\\n\" +\n          \"   {\\n\" +\n          '      \"$match\": { \"size\": \"medium\" }\\n' +\n          \"   },\\n\" +\n          \"   {\\n\" +\n          '      \"$group\": { \"_id\": \"$type\", \"totalQuantity\": { \"$sum\": \"$price\" } }\\n' +\n          \"   }\\n\" +\n          \"] \"\n        }\n        canShowCompleteInfo\n        lineNumbers\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.options\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.options}\n        style={{ height: \"188px\" }}\n        onChange={handleValueChange(\"options\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{\\n\" +\n          '\"collation\":{\\n' +\n          '    \"locale\": \"simple\",\\n' +\n          '    \"caseLevel\": true,\\n' +\n          '    \"caseFirst\": \"upper\",\\n' +\n          \"...\\n\" +\n          \"}}\"\n        }\n      />\n    </>\n  )\n}\n\nAggregatePart.displayName = \"AggregatePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/BulkWritePart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbBulkWriteContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const BulkWritePart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbBulkWriteContent\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              [name]: value,\n            } as MongoDbBulkWriteContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.operations\")}\n        lineNumbers\n        style={{ height: \"188px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.operations}\n        onChange={handleValueChange(\"operations\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"[\\n\" +\n          '      { \"insertOne\": { \"document\": { \"_id\": 3, \"type\": \"beef\", \"size\": \"medium\", \"price\": 6 } } },\\n' +\n          '      { \"insertOne\": { \"document\": { \"_id\": 4, \"type\": \"sausage\", \"size\": \"large\", \"price\": 10 } } },\\n' +\n          '      { \"updateOne\": {\\n' +\n          '         \"filter\": { \"type\": \"cheese\" },\\n' +\n          '         \"update\": { \"$set\": { \"price\": 8 } }\\n' +\n          \"      } }\\n\" +\n          \"]\"\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.options\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.options}\n        onChange={handleValueChange(\"options\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n    </>\n  )\n}\n\nBulkWritePart.displayName = \"BulkWritePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/Command/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbCommandContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const CommandPart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbCommandContent\n\n  const handleValueChange = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              document: value,\n            } as MongoDbCommandContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.mongodb.document\")}\n      lineNumbers\n      style={{ height: \"120px\" }}\n      mode={CODE_LANG.JAVASCRIPT}\n      value={typeContent.document}\n      onChange={handleValueChange}\n      expectedType={VALIDATION_TYPES.STRING}\n      placeholder={\n        \"{\\n\" +\n        '      \"find\": \"fruit\",\\n' +\n        '      \"filter\": {\"price\":10000}\\n' +\n        \"}\"\n      }\n    />\n  )\n}\n\nCommandPart.displayName = \"CommandPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/CountPart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbCountContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const CountPart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n\n  const typeContent = props.typeContent as MongoDbCountContent\n\n  const handleValueChange = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              query: value,\n            } as MongoDbCountContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.mongodb.query\")}\n      lineNumbers\n      style={{ height: \"88px\" }}\n      mode={CODE_LANG.JAVASCRIPT}\n      placeholder={\n        \"{\\n\" +\n        '  \"type\":\"cheese\",\\n' +\n        '  \"_id\": {\\n' +\n        '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n        \"  }\\n\" +\n        \"}\"\n      }\n      value={typeContent.query}\n      onChange={handleValueChange}\n      expectedType={VALIDATION_TYPES.STRING}\n    />\n  )\n}\n\nCountPart.displayName = \"CountPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/DeleteManyPart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbDeleteManyContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DeleteManyPart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbDeleteManyContent\n\n  const handleValueChange = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              filter: value,\n            } as MongoDbDeleteManyContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.mongodb.filter\")}\n      lineNumbers\n      style={{ height: \"88px\" }}\n      mode={CODE_LANG.JAVASCRIPT}\n      placeholder={\n        \"{\\n\" +\n        '  \"type\":\"cheese\",\\n' +\n        '  \"_id\": {\\n' +\n        '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n        \"  }\\n\" +\n        \"}\"\n      }\n      value={typeContent.filter}\n      onChange={handleValueChange}\n      expectedType={VALIDATION_TYPES.STRING}\n    />\n  )\n}\n\nDeleteManyPart.displayName = \"DeleteManyPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/DeleteOnePart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbDeleteOneContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DeleteOnePart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbDeleteOneContent\n\n  const handleValueChange = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              filter: value,\n            } as MongoDbDeleteOneContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <InputEditor\n      lineNumbers\n      style={{ height: \"88px\" }}\n      mode={CODE_LANG.JAVASCRIPT}\n      placeholder={\n        \"{\\n\" +\n        '  \"type\":\"cheese\",\\n' +\n        '  \"_id\": {\\n' +\n        '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n        \"  }\\n\" +\n        \"}\"\n      }\n      value={typeContent.filter}\n      expectedType={VALIDATION_TYPES.STRING}\n      title={t(\"editor.action.panel.mongodb.filter\")}\n      onChange={handleValueChange}\n    />\n  )\n}\n\nDeleteOnePart.displayName = \"DeleteOnePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/DistinctPart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbDistinctContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DistinctPart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbDistinctContent\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              [name]: value,\n            } as MongoDbDistinctContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.query\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.query}\n        onChange={handleValueChange(\"query\")}\n        style={{ height: \"188px\" }}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{\\n\" +\n          '  \"type\":\"cheese\",\\n' +\n          '  \"_id\": {\\n' +\n          '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n          \"  }\\n\" +\n          \"}\"\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.field\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.field}\n        onChange={handleValueChange(\"field\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\"_id\"}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.options\")}\n        lineNumbers\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.options}\n        style={{ height: \"188px\" }}\n        placeholder={\n          \"{\\n\" +\n          '\"collation\":{\\n' +\n          '   \"locale\": \"simple\",\\n' +\n          '   \"caseLevel\": true,\\n' +\n          '   \"caseFirst\": \"upper\",\\n' +\n          \"...\\n\" +\n          \"}}\"\n        }\n        onChange={handleValueChange(\"options\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n    </>\n  )\n}\n\nDistinctPart.displayName = \"DistinctPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/FindOneAndUpdatePart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbFindOneAndUpdateContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const FindOneAndUpdatePart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbFindOneAndUpdateContent\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              [name]: value,\n            } as MongoDbFindOneAndUpdateContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.filter\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.filter}\n        onChange={handleValueChange(\"filter\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{\\n\" +\n          '  \"type\":\"cheese\",\\n' +\n          '  \"_id\": {\\n' +\n          '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n          \"  }\\n\" +\n          \"}\"\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.update\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.update}\n        onChange={handleValueChange(\"update\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={'{\"$set\":{\"type\":\"chicken\", \"price\":100}}'}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.options\")}\n        lineNumbers\n        style={{ height: \"188px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.options}\n        onChange={handleValueChange(\"options\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{\\n\" +\n          '\"collation\":{\\n' +\n          '   \"locale\": \"simple\",\\n' +\n          '   \"caseLevel\": true,\\n' +\n          '   \"caseFirst\": \"upper\",\\n' +\n          \"...\\n\" +\n          \"}}\"\n        }\n      />\n    </>\n  )\n}\n\nFindOneAndUpdatePart.displayName = \"FindOneAndUpdatePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/FindOnePart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbFindOneContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const FindOnePart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbFindOneContent\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              [name]: value,\n            } as MongoDbFindOneContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.query\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.query}\n        onChange={handleValueChange(\"query\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{\\n\" +\n          '  \"type\":\"cheese\",\\n' +\n          '  \"_id\": {\\n' +\n          '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n          \"  }\\n\" +\n          \"}\"\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.projection\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.projection}\n        onChange={handleValueChange(\"projection\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{ \\n\" +\n          '  \"_id\": {\\n' +\n          '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n          \"  }\\n\" +\n          \"}\"\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.skip\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.skip}\n        onChange={handleValueChange(\"skip\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\"10\"}\n      />\n    </>\n  )\n}\n\nFindOnePart.displayName = \"FindOnePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/FindPart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbFindContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const FindPart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbFindContent\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              [name]: value,\n            } as MongoDbFindContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.query\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.query}\n        onChange={handleValueChange(\"query\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{\\n\" +\n          '  \"type\":\"cheese\",\\n' +\n          '  \"_id\": {\\n' +\n          '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n          \"  }\\n\" +\n          \"}\"\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.projection\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.projection}\n        onChange={handleValueChange(\"projection\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{ \\n\" +\n          '  \"_id\": {\\n' +\n          '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n          \"  }\\n\" +\n          \"}\"\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.sort_by\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.sortBy}\n        onChange={handleValueChange(\"sortBy\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{ \\n\" +\n          '  \"_id\": {\\n' +\n          '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n          \"  }\\n\" +\n          \"}\"\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.limit\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.limit}\n        onChange={handleValueChange(\"limit\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\"100\"}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.skip\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.skip}\n        onChange={handleValueChange(\"skip\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\"10\"}\n      />\n    </>\n  )\n}\n\nFindPart.displayName = \"FindPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/InertManyPart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbInsertManyContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const InsertManyPart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbInsertManyContent\n\n  const handleValueChange = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              document: value,\n            } as MongoDbInsertManyContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.mongodb.document\")}\n      lineNumbers\n      style={{ height: \"88px\" }}\n      mode={CODE_LANG.JAVASCRIPT}\n      onChange={handleValueChange}\n      value={typeContent.document}\n      expectedType={VALIDATION_TYPES.STRING}\n      placeholder={\n        '[{\"item\":\"apple\", \"price\":1.49},{\"item\":\"banana\", \"price\":2.50}]'\n      }\n    />\n  )\n}\n\nInsertManyPart.displayName = \"InsertManyPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/InertOnePart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbInsertOneContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const InsertOnePart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbInsertOneContent\n\n  const handleValueChange = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              document: value,\n            } as MongoDbInsertOneContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.mongodb.document\")}\n      lineNumbers\n      style={{ height: \"88px\" }}\n      mode={CODE_LANG.JAVASCRIPT}\n      value={typeContent.document}\n      onChange={handleValueChange}\n      expectedType={VALIDATION_TYPES.STRING}\n      placeholder={'{\"item\":\"apple\", \"price\":1.49}'}\n    />\n  )\n}\n\nInsertOnePart.displayName = \"InsertOnePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/UpdateManyPart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbUpdateManyContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const UpdateManyPart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbUpdateManyContent\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              [name]: value,\n            } as MongoDbUpdateManyContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.filter\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        value={typeContent.filter}\n        onChange={handleValueChange(\"filter\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{\\n\" +\n          '  \"type\":\"cheese\",\\n' +\n          '  \"_id\": {\\n' +\n          '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n          \"  }\\n\" +\n          \"}\"\n        }\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.update\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.update}\n        onChange={handleValueChange(\"update\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={'{\"$set\":{\"type\":\"chicken\", \"price\":100}}'}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.options\")}\n        lineNumbers\n        style={{ height: \"188px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.options}\n        onChange={handleValueChange(\"options\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{\\n\" +\n          '\"collation\":{\\n' +\n          '   \"locale\": \"simple\",\\n' +\n          '   \"caseLevel\": true,\\n' +\n          '   \"caseFirst\": \"upper\",\\n' +\n          \"...\\n\" +\n          \"}}\"\n        }\n      />\n    </>\n  )\n}\n\nUpdateManyPart.displayName = \"UpdateManyPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/UpdateOnePart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbUpdateOneContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const UpdateOnePart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbUpdateOneContent\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              [name]: value,\n            } as MongoDbUpdateOneContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <>\n      <InputEditor\n        value={typeContent.filter}\n        onChange={handleValueChange(\"filter\")}\n        title={t(\"editor.action.panel.mongodb.filter\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        expectedType={VALIDATION_TYPES.STRING}\n        mode={CODE_LANG.JAVASCRIPT}\n        placeholder={\n          \"{\\n\" +\n          '  \"type\":\"cheese\",\\n' +\n          '  \"_id\": {\\n' +\n          '    \"$oid\":\"646385ae462e929b7a3d86bc\"\\n' +\n          \"  }\\n\" +\n          \"}\"\n        }\n      />\n      <InputEditor\n        lineNumbers\n        style={{ height: \"88px\" }}\n        value={typeContent.update}\n        onChange={handleValueChange(\"update\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        expectedType={VALIDATION_TYPES.STRING}\n        title={t(\"editor.action.panel.mongodb.update\")}\n        placeholder={'{\"$set\":{\"type\":\"chicken\", \"price\":100}}'}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.mongodb.options\")}\n        lineNumbers\n        style={{ height: \"188px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={typeContent.options}\n        onChange={handleValueChange(\"options\")}\n        expectedType={VALIDATION_TYPES.STRING}\n        placeholder={\n          \"{\\n\" +\n          '\"collation\":{\\n' +\n          '   \"locale\": \"simple\",\\n' +\n          '   \"caseLevel\": true,\\n' +\n          '   \"caseFirst\": \"upper\",\\n' +\n          \"...\\n\" +\n          \"}}\"\n        }\n      />\n    </>\n  )\n}\n\nUpdateOnePart.displayName = \"UpdateOnePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/constants.ts",
    "content": "export const MongoDbActionList = [\n  \"aggregate\",\n  \"bulkWrite\",\n  \"count\",\n  \"deleteMany\",\n  \"deleteOne\",\n  \"distinct\",\n  \"find\",\n  \"findOne\",\n  \"findOneAndUpdate\",\n  \"insertOne\",\n  \"insertMany\",\n  \"listCollections\",\n  \"updateMany\",\n  \"updateOne\",\n  \"command\",\n]\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/index.tsx",
    "content": "import {\n  MongoDbAggregateContentInitial,\n  MongoDbBulkWriteContentInitial,\n  MongoDbCommandContentInitial,\n  MongoDbCountContentInitial,\n  MongoDbDeleteManyContentInitial,\n  MongoDbDeleteOneContentInitial,\n  MongoDbDistinctContentInitial,\n  MongoDbFindContentInitial,\n  MongoDbFindOneAndUpdateContentInitial,\n  MongoDbFindOneContentInitial,\n  MongoDbInsertManyContentInitial,\n  MongoDbInsertOneContentInitial,\n  MongoDbListCollectionsContentInitial,\n  MongoDbUpdateManyContentInitial,\n  MongoDbUpdateOneContentInitial,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionType,\n  MongoDbActionTypeContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { SelectValue } from \"@illa-design/react\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { AggregatePart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/AggregatePart\"\nimport { BulkWritePart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/BulkWritePart\"\nimport { CommandPart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/Command\"\nimport { CountPart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/CountPart\"\nimport { DeleteManyPart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/DeleteManyPart\"\nimport { DeleteOnePart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/DeleteOnePart\"\nimport { DistinctPart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/DistinctPart\"\nimport { FindOneAndUpdatePart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/FindOneAndUpdatePart\"\nimport { FindOnePart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/FindOnePart\"\nimport { FindPart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/FindPart\"\nimport { InsertManyPart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/InertManyPart\"\nimport { InsertOnePart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/InertOnePart\"\nimport { UpdateManyPart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/UpdateManyPart\"\nimport { UpdateOnePart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/UpdateOnePart\"\nimport { ListCollectionsPart } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/listCollectionsPart\"\nimport { actionItemContainer } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/style\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { MongoDbActionList } from \"./constants\"\n\nconst MongoDbPanel: FC = () => {\n  const { t } = useTranslation()\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const selectedAction = useSelector(getSelectedAction)\n  const dispatch = useDispatch()\n\n  let content = cachedAction.content as MongoDbAction<MongoDbActionTypeContent>\n\n  const renderInputBody = useMemo(() => {\n    switch (content.actionType) {\n      case \"aggregate\":\n        return <AggregatePart typeContent={content.typeContent} />\n      case \"bulkWrite\":\n        return <BulkWritePart typeContent={content.typeContent} />\n      case \"count\":\n        return <CountPart typeContent={content.typeContent} />\n      case \"deleteMany\":\n        return <DeleteManyPart typeContent={content.typeContent} />\n      case \"deleteOne\":\n        return <DeleteOnePart typeContent={content.typeContent} />\n      case \"distinct\":\n        return <DistinctPart typeContent={content.typeContent} />\n      case \"find\":\n        return <FindPart typeContent={content.typeContent} />\n      case \"findOne\":\n        return <FindOnePart typeContent={content.typeContent} />\n      case \"findOneAndUpdate\":\n        return <FindOneAndUpdatePart typeContent={content.typeContent} />\n      case \"insertOne\":\n        return <InsertOnePart typeContent={content.typeContent} />\n      case \"insertMany\":\n        return <InsertManyPart typeContent={content.typeContent} />\n      case \"listCollections\":\n        return <ListCollectionsPart typeContent={content.typeContent} />\n      case \"updateMany\":\n        return <UpdateManyPart typeContent={content.typeContent} />\n      case \"updateOne\":\n        return <UpdateOnePart typeContent={content.typeContent} />\n      case \"command\":\n        return <CommandPart typeContent={content.typeContent} />\n      default:\n        return <></>\n    }\n  }, [content.actionType, content.typeContent])\n\n  const handleActionTypeChange = useCallback(\n    (value: SelectValue) => {\n      let newTypeContent: MongoDbActionTypeContent =\n        MongoDbAggregateContentInitial\n      if (\n        selectedAction &&\n        cachedAction.resourceID === selectedAction.resourceID &&\n        (selectedAction.content as MongoDbAction<MongoDbActionTypeContent>)\n          .actionType === value\n      ) {\n        newTypeContent = (\n          selectedAction.content as MongoDbAction<MongoDbActionTypeContent>\n        )?.typeContent\n      } else {\n        switch (value) {\n          case \"aggregate\":\n            newTypeContent = MongoDbAggregateContentInitial\n            break\n          case \"bulkWrite\":\n            newTypeContent = MongoDbBulkWriteContentInitial\n            break\n          case \"count\":\n            newTypeContent = MongoDbCountContentInitial\n            break\n          case \"deleteMany\":\n            newTypeContent = MongoDbDeleteManyContentInitial\n            break\n          case \"deleteOne\":\n            newTypeContent = MongoDbDeleteOneContentInitial\n            break\n          case \"distinct\":\n            newTypeContent = MongoDbDistinctContentInitial\n            break\n          case \"find\":\n            newTypeContent = MongoDbFindContentInitial\n            break\n          case \"findOne\":\n            newTypeContent = MongoDbFindOneContentInitial\n            break\n          case \"findOneAndUpdate\":\n            newTypeContent = MongoDbFindOneAndUpdateContentInitial\n            break\n          case \"insertOne\":\n            newTypeContent = MongoDbInsertOneContentInitial\n            break\n          case \"insertMany\":\n            newTypeContent = MongoDbInsertManyContentInitial\n            break\n          case \"listCollections\":\n            newTypeContent = MongoDbListCollectionsContentInitial\n            break\n          case \"updateMany\":\n            newTypeContent = MongoDbUpdateManyContentInitial\n            break\n          case \"updateOne\":\n            newTypeContent = MongoDbUpdateOneContentInitial\n            break\n          case \"command\":\n            newTypeContent = MongoDbCommandContentInitial\n            break\n        }\n      }\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            actionType: value as MongoDbActionType,\n            typeContent: newTypeContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, selectedAction],\n  )\n\n  const handleCollectionChange = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            collection: value,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch],\n  )\n\n  return (\n    <div css={actionItemContainer}>\n      <SingleTypeComponent\n        componentType=\"select\"\n        showSearch={true}\n        value={content.actionType}\n        onSelectedValueChange={handleActionTypeChange}\n        options={MongoDbActionList}\n        title={t(\"editor.action.panel.mongodb.action_type\")}\n      />\n      {cachedAction.content.actionType !== \"command\" &&\n        cachedAction.content.actionType !== \"listCollections\" && (\n          <InputEditor\n            value={content.collection}\n            title={t(\"editor.action.panel.mongodb.collection\")}\n            onChange={handleCollectionChange}\n            mode={CODE_LANG.JAVASCRIPT}\n            expectedType={VALIDATION_TYPES.STRING}\n          />\n        )}\n      {renderInputBody}\n      <TransformerComponent />\n    </div>\n  )\n}\n\nMongoDbPanel.displayName = \"MongoDbPanel\"\nexport default MongoDbPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/interface.ts",
    "content": "import { MongoDbActionTypeContent } from \"@illa-public/public-types\"\n\nexport interface MongoDbActionPartProps {\n  typeContent: MongoDbActionTypeContent\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/listCollectionsPart/index.tsx",
    "content": "import {\n  ActionItem,\n  MongoDbAction,\n  MongoDbActionTypeContent,\n  MongoDbListCollectionsContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { MongoDbActionPartProps } from \"@/page/App/components/Actions/ActionPanel/MongoDbPanel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const ListCollectionsPart: FC<MongoDbActionPartProps> = (props) => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    MongoDbAction<MongoDbActionTypeContent>\n  >\n  const typeContent = props.typeContent as MongoDbListCollectionsContent\n\n  const handleValueChange = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            typeContent: {\n              ...typeContent,\n              query: value,\n            } as MongoDbListCollectionsContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, dispatch, typeContent],\n  )\n\n  return (\n    <InputEditor\n      title={t(\"editor.action.panel.mongodb.query\")}\n      lineNumbers\n      style={{ height: \"88px\" }}\n      mode={CODE_LANG.JAVASCRIPT}\n      value={typeContent.query}\n      onChange={handleValueChange}\n      expectedType={VALIDATION_TYPES.STRING}\n      placeholder={'{\"name\":\"fruit\"}'}\n    />\n  )\n}\n\nListCollectionsPart.displayName = \"ListCollectionsPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MongoDbPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const codeEditorLabelStyle = css`\n  min-width: 160px;\n  font-size: 14px;\n  font-weight: 500;\n  text-align: right;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  height: 48px;\n  display: flex;\n  flex-direction: row;\n  justify-content: end;\n  align-items: center;\n  align-self: start;\n`\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MysqlLikePanel/index.tsx",
    "content": "import { isILLAAPiError } from \"@illa-public/illa-net\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { MysqlLikeAction } from \"@illa-public/public-types\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { FC, useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Button, Input, Select, Trigger, useMessage } from \"@illa-design/react\"\nimport OpenAIIcon from \"@/assets/openai.svg?react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { ILLAMarkdown } from \"@/components/ILLAMarkdown\"\nimport {\n  actionItemContainer,\n  labelStyle,\n  labelTipsStyle,\n  modeContainerStyle,\n  sqlInputStyle,\n  sqlTransStyle,\n} from \"@/page/App/components/Actions/ActionPanel/MysqlLikePanel/style\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getAppInfo } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { fetchGenerateSQL } from \"@/services/action\"\nimport { fetchResourceMeta } from \"@/services/resource\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { SQLModeSelector } from \"../pulicComponent/SQLModeSelector\"\nimport SQLModeTip from \"../pulicComponent/SQLModeTip\"\n\nconst MysqlLikePanel: FC = () => {\n  const currentAction = useSelector(getCachedAction)!!\n  const [sqlTable, setSqlTable] = useState<Record<string, unknown>>()\n  const dispatch = useDispatch()\n  const appInfo = useSelector(getAppInfo)\n\n  const { t } = useTranslation()\n\n  useEffect(() => {\n    if (currentAction.resourceID == undefined) return\n    fetchResourceMeta(currentAction.resourceID).then(({ data }) => {\n      setSqlTable(data?.Schema ?? {})\n    })\n  }, [currentAction.resourceID])\n\n  const mode = useMemo(() => {\n    switch (currentAction.actionType) {\n      case \"hydra\":\n      case \"postgresql\":\n        return CODE_LANG.PGSQL\n      default:\n        return CODE_LANG.SQL\n    }\n  }, [currentAction.actionType])\n\n  const displayName = currentAction.displayName\n  const mysqlContent = currentAction.content as MysqlLikeAction\n  const value = useMemo(() => {\n    return (currentAction.content as MysqlLikeAction)?.query || \"\"\n  }, [currentAction])\n\n  const inputRef = useRef<HTMLInputElement>(null)\n  const [generateLoading, setGenerateLoading] = useState(false)\n  const [currentSqlAction, setCurrentSqlAction] = useState(1)\n  const message = useMessage()\n\n  const handleQueryChange = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...currentAction,\n          content: {\n            ...mysqlContent,\n            query: value,\n          },\n        }),\n      )\n    },\n    [currentAction, dispatch, mysqlContent],\n  )\n\n  useEffect(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n      element: \"sql_generation\",\n      parameter1: currentAction.actionType,\n    })\n  }, [currentAction.actionType])\n\n  const onBlurOnCodeMirror = useCallback((value: string) => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n      element: \"action_edit_code_mirror\",\n      parameter2: \"content.query\",\n      parameter3: value.length,\n    })\n  }, [])\n  const handleClickGenerate = useCallback(async () => {\n    setGenerateLoading(true)\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"sql_generation\",\n      parameter1: currentAction.actionType,\n      parameter4: {\n        type: currentSqlAction,\n        content: inputRef.current?.value,\n      },\n    })\n    const data = {\n      description: inputRef.current?.value,\n      resourceID: currentAction.resourceID,\n      action: currentSqlAction,\n    }\n    try {\n      const response = await fetchGenerateSQL(appInfo.appId, data)\n      dispatch(\n        configActions.updateCachedAction({\n          ...currentAction,\n          content: {\n            ...mysqlContent,\n            query: response.data.payload,\n          },\n        }),\n      )\n    } catch (e) {\n      if (isILLAAPiError(e)) {\n        message.error({\n          content: e.data.errorMessage,\n        })\n      }\n    }\n    setGenerateLoading(false)\n  }, [\n    appInfo.appId,\n    currentAction,\n    currentSqlAction,\n    dispatch,\n    message,\n    mysqlContent,\n  ])\n\n  return (\n    <div css={actionItemContainer}>\n      {isCloudVersion ? (\n        <div css={sqlTransStyle}>\n          <Select\n            mr=\"-1px\"\n            autoAlignPopupWidth={true}\n            w=\"120px\"\n            flexGrow=\"0\"\n            flexShrink=\"0\"\n            bdRadius=\"8px 0 0 8px\"\n            value={currentSqlAction}\n            options={[\n              {\n                label: \"SELECT\",\n                value: 1,\n              },\n              {\n                label: \"INSERT\",\n                value: 2,\n              },\n              {\n                label: \"UPDATE\",\n                value: 3,\n              },\n              {\n                label: \"DELETE\",\n                value: 4,\n              },\n            ]}\n            onChange={(v) => {\n              setCurrentSqlAction(v as number)\n            }}\n            size=\"large\"\n            colorScheme=\"techPurple\"\n          />\n          <Input\n            size=\"large\"\n            colorScheme=\"techPurple\"\n            bdRadius=\"0\"\n            flexGrow=\"1\"\n            flexShrink=\"1\"\n            placeholder={t(\"editor.action.panel.sqlgc.placeholder.text\")}\n            inputRef={inputRef}\n          />\n          <Button\n            minW=\"168px\"\n            loading={generateLoading}\n            size=\"large\"\n            flexGrow=\"0\"\n            flexShrink=\"0\"\n            bdRadius=\"0 8px 8px 0\"\n            pd=\"9px 24px\"\n            bg=\"linear-gradient(90deg, #FF53D9 0%, #AE47FF 100%);\"\n            leftIcon={<OpenAIIcon />}\n            onClick={handleClickGenerate}\n          >\n            {t(\"editor.action.panel.sqlgc.button.text\")}\n          </Button>\n        </div>\n      ) : null}\n      <div css={sqlInputStyle}>\n        <CodeEditor\n          className={`${displayName}-query`}\n          placeholder=\"select * from users;\"\n          showLineNumbers\n          height=\"88px\"\n          value={value}\n          lang={mode}\n          canShowCompleteInfo\n          expectValueType={VALIDATION_TYPES.STRING}\n          sqlScheme={sqlTable}\n          onChange={handleQueryChange}\n          onBlur={onBlurOnCodeMirror}\n        />\n        {mysqlContent.mode === \"sql-safe\" && <SQLModeTip value={value} />}\n      </div>\n      {(mysqlContent.mode === \"sql\" || mysqlContent.mode === \"sql-safe\") && (\n        <div css={modeContainerStyle}>\n          <Trigger\n            content={\n              <ILLAMarkdown\n                textString={t(\n                  \"editor.action.panel.label.tips.general.safe_mode\",\n                )}\n              />\n            }\n            trigger=\"hover\"\n            position=\"left\"\n            maxW=\"240px\"\n          >\n            <span css={labelStyle}>\n              {t(\"editor.action.panel.label.general.safe_mode\")}\n              <span css={labelTipsStyle} />\n            </span>\n          </Trigger>\n          <SQLModeSelector />\n        </div>\n      )}\n      <TransformerComponent fullWidth />\n    </div>\n  )\n}\n\nMysqlLikePanel.displayName = \"MysqlPanel\"\nexport default MysqlLikePanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/MysqlLikePanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const mysqlContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n`\n\nexport const sqlInputStyle = css`\n  margin: 8px 16px;\n`\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n\nexport const sqlTransStyle = css`\n  padding: 8px 16px;\n  display: flex;\n  width: 100%;\n  align-items: center;\n`\n\nexport const labelStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n  position: relative;\n`\n\nexport const labelTipsStyle = css`\n  position: absolute;\n  bottom: -2px;\n  left: 0;\n  width: 100%;\n  border-bottom: 1px dashed ${getColor(\"grayBlue\", \"06\")};\n`\n\nexport const modeContainerStyle = css`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 12px 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/OracleDBPanel/index.tsx",
    "content": "import { OracleDBActionInitial } from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  OracleDBAction,\n  OracleDBActionSQLMode,\n  OracleDBActionType,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback, useEffect, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Trigger } from \"@illa-design/react\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { ILLAMarkdown } from \"@/components/ILLAMarkdown\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { actionItemContainer } from \"@/page/App/components/Actions/ActionPanel/style\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { fetchResourceMeta } from \"@/services/resource\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { SQLModeSelector } from \"../pulicComponent/SQLModeSelector\"\nimport { labelStyle, labelTipsStyle, modeContainerStyle } from \"./style\"\n\nconst OracleDBPanel: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    OracleDBAction<OracleDBActionType>\n  >\n  const [sqlTable, setSqlTable] = useState<Record<string, unknown>>()\n  const content = cachedAction.content ?? OracleDBActionInitial\n\n  useEffect(() => {\n    if (cachedAction.resourceID == undefined) return\n    fetchResourceMeta(cachedAction.resourceID).then(({ data }) => {\n      setSqlTable(data?.Schema ?? {})\n    })\n  }, [cachedAction.resourceID])\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            opts: {\n              ...content.opts,\n              [name]: value,\n            },\n          },\n        }),\n      )\n    },\n    [cachedAction, content, dispatch],\n  )\n\n  return (\n    <>\n      <div css={actionItemContainer}>\n        <InputEditor\n          style={{ height: \"88px\" }}\n          placeholder={t(\"editor.action.panel.mssql.placeholder.query\")}\n          lineNumbers\n          mode={CODE_LANG.SQL}\n          canShowCompleteInfo\n          expectedType={VALIDATION_TYPES.STRING}\n          value={(content.opts as OracleDBActionSQLMode).raw}\n          onChange={handleValueChange(\"raw\")}\n          sqlScheme={sqlTable}\n          showSafeModeTips={content.mode === \"sql-safe\"}\n        />\n        <TransformerComponent fullWidth />\n      </div>\n      {(content.mode === \"sql\" || content.mode === \"sql-safe\") && (\n        <div css={modeContainerStyle}>\n          <Trigger\n            content={\n              <ILLAMarkdown\n                textString={t(\n                  \"editor.action.panel.label.tips.general.safe_mode\",\n                )}\n              />\n            }\n            trigger=\"hover\"\n            position=\"left\"\n            maxW=\"240px\"\n          >\n            <span css={labelStyle}>\n              {t(\"editor.action.panel.label.general.safe_mode\")}\n              <span css={labelTipsStyle} />\n            </span>\n          </Trigger>\n          <SQLModeSelector />\n        </div>\n      )}\n    </>\n  )\n}\nOracleDBPanel.displayName = \"OracleDBPanel\"\nexport default OracleDBPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/OracleDBPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const labelStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n\n  position: relative;\n`\n\nexport const labelTipsStyle = css`\n  position: absolute;\n  bottom: -2px;\n  left: 0;\n  width: 100%;\n  border-bottom: 1px dashed ${getColor(\"grayBlue\", \"06\")};\n`\n\nexport const modeContainerStyle = css`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 12px 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/PanelHeader/AIAgentResourceChoose/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport {\n  ACTION_RUN_TIME,\n  ActionTriggerMode,\n  AiAgentActionContent,\n  IAdvancedConfig,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Select, Space, TriggerProvider } from \"@illa-design/react\"\nimport { getAgentIcon } from \"@/page/App/components/Actions/getIcon\"\nimport { getDashboardTeamAIAgentList } from \"@/redux/aiAgent/dashboardTeamAIAgentSelector\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport {\n  itemContainer,\n  itemText,\n  resourceChooseContainerStyle,\n  resourceEndStyle,\n  resourceTitleStyle,\n  spaceStyle,\n} from \"./style\"\n\nexport const AIAgentResourceChoose: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n\n  const agentList = useSelector(getDashboardTeamAIAgentList)\n  const action = useSelector(getCachedAction)!!\n  const selectedAction = useSelector(getSelectedAction)!!\n\n  //maybe empty\n  const currentSelectResource = agentList.find(\n    (r) => r.aiAgentID === action.resourceID,\n  )\n\n  const options = agentList.map((item) => ({\n    label: (\n      <>\n        <div css={itemContainer}>\n          {getAgentIcon(item, \"14px\")}\n          <span css={itemText}>{item.name}</span>\n        </div>\n      </>\n    ),\n    value: item.aiAgentID,\n  }))\n\n  return (\n    <TriggerProvider renderInBody zIndex={10}>\n      <div css={resourceChooseContainerStyle}>\n        <span css={resourceTitleStyle}>{t(\"resources\")}</span>\n        <div css={resourceEndStyle}>\n          <Select\n            w=\"360px\"\n            colorScheme=\"techPurple\"\n            value={\n              currentSelectResource\n                ? action.resourceID\n                : t(\"editor.action.resource_choose.deleted\")\n            }\n            onChange={(value) => {\n              const resource = agentList.find((r) => r.aiAgentID === value)\n              if (resource != undefined) {\n                dispatch(\n                  configActions.updateCachedAction({\n                    ...action,\n                    // selected resource is same as action type\n                    actionType: \"aiagent\",\n                    resourceID: value as string,\n                    content: {\n                      ...selectedAction.content,\n                      virtualResource: resource,\n                    },\n                  } as ActionItem<AiAgentActionContent>),\n                )\n              }\n            }}\n            options={options}\n          />\n          <Select\n            ml=\"8px\"\n            w=\"360px\"\n            colorScheme=\"techPurple\"\n            value={action.triggerMode}\n            onChange={(value) => {\n              dispatch(\n                configActions.updateCachedAction({\n                  ...action,\n                  triggerMode: value as ActionTriggerMode,\n                }),\n              )\n              let updateSlice: Partial<IAdvancedConfig> = {}\n              if (value === \"manually\") {\n                updateSlice = {\n                  runtime: ACTION_RUN_TIME.NONE,\n                  pages: [],\n                  delayWhenLoaded: \"\",\n                  displayLoadingPage: false,\n                }\n              }\n              if (value === \"automate\") {\n                updateSlice = {\n                  runtime: ACTION_RUN_TIME.APP_LOADED,\n                  pages: [],\n                  delayWhenLoaded: \"\",\n                  displayLoadingPage: false,\n                }\n              }\n              dispatch(\n                configActions.updateCachedActionAdvancedConfigReducer(\n                  updateSlice,\n                ),\n              )\n            }}\n            onClick={() => {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"action_edit_auto_run\",\n              })\n            }}\n            options={[\n              {\n                label: t(\"editor.action.panel.option.trigger.manually\"),\n                value: \"manually\",\n              },\n              {\n                label: t(\"editor.action.panel.option.trigger.on_change\"),\n                value: \"automate\",\n              },\n            ]}\n          />\n        </div>\n      </div>\n      <Space w=\"100%\" h=\"8px\" css={spaceStyle} disp=\"block\" />\n    </TriggerProvider>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/PanelHeader/AIAgentResourceChoose/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const resourceChooseContainerStyle = css`\n  display: flex;\n  align-items: center;\n  padding: 8px 16px;\n  width: 100%;\n  overflow-x: auto;\n  flex-direction: row;\n`\n\nexport const spaceStyle = css`\n  border-bottom: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n`\n\nexport const resourceTitleStyle = css`\n  flex-grow: 1;\n  font-size: 14px;\n  font-weight: 500;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const resourceEndStyle = css`\n  justify-content: flex-end;\n  flex-grow: 1;\n  margin-left: 16px;\n  display: flex;\n  flex-shrink: 1;\n  flex-direction: row;\n`\n\nexport const itemContainer = css`\n  width: 100%;\n  display: flex;\n  align-items: center;\n`\n\nexport const itemText = css`\n  margin-left: 8px;\n  flex-shrink: 1;\n  text-overflow: ellipsis;\n  overflow: hidden;\n  white-space: nowrap;\n  flex-grow: 1;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/PanelHeader/MockOperation/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch } from \"react-redux\"\nimport { RadioGroup } from \"@illa-design/react\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { MockOperationProps } from \"./interface\"\nimport { mockOperationContainerStyle, mockOperationTitleStyle } from \"./style\"\n\nconst MockOperation: FC<MockOperationProps> = (props) => {\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n\n  const handleChangeDataType = (value: boolean) => {\n    dispatch(\n      configActions.updateCachedActionMockConfigReducer({\n        enabled: value,\n      }),\n    )\n  }\n\n  return (\n    <div css={mockOperationContainerStyle}>\n      <span css={mockOperationTitleStyle}>\n        {t(\"editor.action.panel.option.mock.data_label\")}\n      </span>\n      <RadioGroup\n        type=\"button\"\n        options={[\n          {\n            label: t(\"editor.action.panel.option.mock.data_production\"),\n            value: false,\n          },\n          {\n            label: t(\"editor.action.panel.option.mock.data_mock\"),\n            value: true,\n          },\n        ]}\n        size=\"medium\"\n        onChange={handleChangeDataType}\n        value={props.enableMock}\n        colorScheme=\"techPurple\"\n      />\n    </div>\n  )\n}\n\nexport default memo(MockOperation)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/PanelHeader/MockOperation/interface.ts",
    "content": "export interface MockOperationProps {\n  enableMock: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/PanelHeader/MockOperation/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const mockOperationContainerStyle = css`\n  display: flex;\n  padding: 8px 16px;\n  justify-content: space-between;\n  align-items: center;\n`\n\nexport const mockOperationTitleStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/PanelHeader/ResourceChoose/index.tsx",
    "content": "import { getIconFromResourceType } from \"@illa-public/icon\"\nimport { getInitialContent } from \"@illa-public/public-configs\"\nimport { FC, Suspense } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  AddIcon,\n  PenIcon,\n  Select,\n  Space,\n  globalColor,\n  illaPrefix,\n} from \"@illa-design/react\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getAllResources } from \"@/redux/resource/resourceSelector\"\nimport { createNewStyle, itemContainer, itemLogo, itemText } from \"./style\"\n\ninterface ResourceChooseProps {\n  setGeneratorVisible: (v: boolean) => void\n  setEditorVisible: (v: boolean) => void\n}\n\nconst ResourceChoose: FC<ResourceChooseProps> = ({\n  setGeneratorVisible,\n  setEditorVisible,\n}) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n\n  const resourceList = useSelector(getAllResources)\n  const action = useSelector(getCachedAction)!!\n  const selectedAction = useSelector(getSelectedAction)!!\n\n  //maybe empty\n  const currentSelectResource = resourceList.find(\n    (r) => r.resourceID === action.resourceID,\n  )\n\n  const options = resourceList.map((item) => ({\n    label: (\n      <div css={itemContainer}>\n        <span css={itemLogo}>\n          <Suspense>\n            {getIconFromResourceType(item.resourceType, \"14px\")}\n          </Suspense>\n        </span>\n        <span css={itemText}>{item.resourceName}</span>\n      </div>\n    ),\n    value: item.resourceID,\n  }))\n  options.unshift({\n    label: (\n      <Space\n        size=\"8px\"\n        direction=\"horizontal\"\n        alignItems=\"center\"\n        css={createNewStyle}\n      >\n        <AddIcon size=\"14px\" />\n        {t(\"editor.action.panel.option.resource.new\")}\n      </Space>\n    ),\n    value: \"create\",\n  })\n\n  return (\n    <Select\n      w=\"360px\"\n      colorScheme=\"techPurple\"\n      options={options}\n      value={\n        currentSelectResource\n          ? action.resourceID\n          : t(\"editor.action.resource_choose.deleted\")\n      }\n      onChange={(value) => {\n        if (value === \"create\") {\n          setGeneratorVisible(true)\n          return\n        }\n        const resource = resourceList.find((r) => r.resourceID === value)\n        if (resource != undefined) {\n          dispatch(\n            configActions.updateCachedAction({\n              ...action,\n              // selected resource is same as action type\n              actionType: resource.resourceType,\n              resourceID: value as string,\n              content:\n                selectedAction.actionType === resource.resourceType\n                  ? selectedAction.content\n                  : getInitialContent(resource.resourceType),\n            }),\n          )\n        }\n      }}\n      addAfter={\n        <PenIcon\n          style={\n            currentSelectResource\n              ? { cursor: \"pointer\" }\n              : { cursor: \"not-allowed\" }\n          }\n          color={globalColor(`--${illaPrefix}-grayBlue-04`)}\n          onClick={(e) => {\n            e.stopPropagation()\n            if (currentSelectResource) {\n              setEditorVisible(true)\n            }\n          }}\n        />\n      }\n    />\n  )\n}\n\nexport default ResourceChoose\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/PanelHeader/ResourceChoose/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const createNewStyle = css`\n  color: ${getColor(\"techPurple\", \"03\")};\n`\n\nexport const itemContainer = css`\n  width: 100%;\n  display: flex;\n  align-items: center;\n`\n\nexport const itemLogo = css`\n  flex-shrink: 0;\n`\n\nexport const itemText = css`\n  margin-left: 8px;\n  flex-shrink: 1;\n  text-overflow: ellipsis;\n  overflow: hidden;\n  white-space: nowrap;\n  flex-grow: 1;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/PanelHeader/TriggerModeChoose/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport {\n  ACTION_RUN_TIME,\n  ActionTriggerMode,\n  IAdvancedConfig,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Select } from \"@illa-design/react\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\n\nconst TriggerModeChoose: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const action = useSelector(getCachedAction)!!\n  return (\n    <Select\n      ml=\"8px\"\n      colorScheme=\"techPurple\"\n      value={action.triggerMode}\n      w=\"360px\"\n      onChange={(value) => {\n        dispatch(\n          configActions.updateCachedAction({\n            ...action,\n            triggerMode: value as ActionTriggerMode,\n          }),\n        )\n        let updateSlice: Partial<IAdvancedConfig> = {}\n        if (value === \"manually\") {\n          updateSlice = {\n            runtime: ACTION_RUN_TIME.NONE,\n            pages: [],\n            delayWhenLoaded: \"\",\n            displayLoadingPage: false,\n          }\n        }\n        if (value === \"automate\") {\n          updateSlice = {\n            runtime: ACTION_RUN_TIME.APP_LOADED,\n            pages: [],\n            delayWhenLoaded: \"\",\n            displayLoadingPage: false,\n          }\n        }\n        dispatch(\n          configActions.updateCachedActionAdvancedConfigReducer(updateSlice),\n        )\n      }}\n      onClick={() => {\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n          element: \"action_edit_auto_run\",\n        })\n      }}\n      options={[\n        {\n          label: t(\"editor.action.panel.option.trigger.manually\"),\n          value: \"manually\",\n        },\n        {\n          label: t(\"editor.action.panel.option.trigger.on_change\"),\n          value: \"automate\",\n        },\n      ]}\n    />\n  )\n}\n\nexport default TriggerModeChoose\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/PanelHeader/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport { getInitialContent } from \"@illa-public/public-configs\"\nimport { Resource } from \"@illa-public/public-types\"\nimport {\n  ACTION_MODAL_WIDTH,\n  ResourceCreator,\n  ResourceGenerator,\n  ResourceGeneratorProvider,\n} from \"@illa-public/resource-generator\"\nimport { FC, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Modal, Space, TriggerProvider } from \"@illa-design/react\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getAllResources } from \"@/redux/resource/resourceSelector\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { track } from \"@/utils/mixpanelHelper\"\nimport ResourceChoose from \"./ResourceChoose\"\nimport TriggerModeChoose from \"./TriggerModeChoose\"\nimport {\n  resourceChooseContainerStyle,\n  resourceEndStyle,\n  resourceTitleStyle,\n  spaceStyle,\n} from \"./style\"\n\nconst PanelHeader: FC = () => {\n  const { t } = useTranslation()\n  const [editorVisible, setEditorVisible] = useState(false)\n  const [generatorVisible, setGeneratorVisible] = useState(false)\n  const resourceList = useSelector(getAllResources)\n\n  const action = useSelector(getCachedAction)!!\n  const selectedAction = useSelector(getSelectedAction)!!\n\n  const dispatch = useDispatch()\n\n  const createOrUpdateResourceCallback = (\n    resource: Resource,\n    isUpdate: boolean,\n  ) => {\n    setEditorVisible(false)\n    setGeneratorVisible(false)\n    if (isUpdate) {\n      dispatch(resourceActions.updateResourceItemReducer(resource))\n    } else {\n      dispatch(resourceActions.addResourceItemReducer(resource))\n      dispatch(\n        configActions.updateCachedAction({\n          ...action,\n          actionType: resource.resourceType,\n          resourceID: resource.resourceID,\n          content:\n            selectedAction.actionType === resource.resourceType\n              ? selectedAction.content\n              : getInitialContent(resource.resourceType),\n        }),\n      )\n    }\n  }\n\n  return (\n    <MixpanelTrackProvider\n      basicTrack={track}\n      pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR}\n    >\n      <ResourceGeneratorProvider\n        allResource={resourceList}\n        createOrUpdateResourceCallback={createOrUpdateResourceCallback}\n      >\n        <TriggerProvider renderInBody zIndex={10}>\n          <div css={resourceChooseContainerStyle}>\n            <span css={resourceTitleStyle}>{t(\"resources\")}</span>\n            <div css={resourceEndStyle}>\n              <ResourceChoose\n                setGeneratorVisible={setGeneratorVisible}\n                setEditorVisible={setEditorVisible}\n              />\n              <TriggerModeChoose />\n            </div>\n          </div>\n          <Space w=\"100%\" h=\"8px\" css={spaceStyle} disp=\"block\" />\n          <Modal\n            w={`${ACTION_MODAL_WIDTH}px`}\n            visible={editorVisible}\n            footer={false}\n            closable\n            withoutLine\n            withoutPadding\n            maskClosable={false}\n            onCancel={() => {\n              setEditorVisible(false)\n            }}\n          >\n            <ResourceCreator\n              resourceID={action.resourceID}\n              onBack={() => {\n                setEditorVisible(false)\n              }}\n            />\n          </Modal>\n          <ResourceGenerator\n            visible={generatorVisible}\n            onClose={() => {\n              setGeneratorVisible(false)\n            }}\n          />\n        </TriggerProvider>\n      </ResourceGeneratorProvider>\n    </MixpanelTrackProvider>\n  )\n}\n\nexport default PanelHeader\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/PanelHeader/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const resourceChooseContainerStyle = css`\n  display: flex;\n  align-items: center;\n  padding: 8px 16px;\n  width: 100%;\n  overflow-x: auto;\n  flex-direction: row;\n`\n\nexport const resourceTitleStyle = css`\n  flex-grow: 1;\n  font-size: 14px;\n  font-weight: 500;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const resourceEndStyle = css`\n  justify-content: flex-end;\n  flex-grow: 1;\n  margin-left: 16px;\n  display: flex;\n  flex-shrink: 1;\n  flex-direction: row;\n`\n\nexport const spaceStyle = css`\n  border-bottom: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/RedisPanel/index.tsx",
    "content": "import { RedisAction } from \"@illa-public/public-types\"\nimport { FC, useCallback, useEffect, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { actionItemContainer } from \"@/page/App/components/Actions/ActionPanel/RedisPanel/style\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { fetchResourceMeta } from \"@/services/resource\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst RedisPanel: FC = () => {\n  const action = useSelector(getCachedAction)!!\n  const [sqlTable, setSqlTable] = useState<Record<string, unknown>>()\n\n  useEffect(() => {\n    if (action.resourceID == undefined) return\n    fetchResourceMeta(action.resourceID).then(({ data }) => {\n      setSqlTable(data?.Schema ?? {})\n    })\n  }, [action.resourceID])\n\n  const currentContent = action.content as RedisAction\n  const dispatch = useDispatch()\n\n  const handleValueChange = useCallback(\n    (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...action,\n          content: {\n            ...currentContent,\n            query: value,\n          },\n        }),\n      )\n    },\n    [action, currentContent, dispatch],\n  )\n\n  return (\n    <div css={actionItemContainer}>\n      <InputEditor\n        style={{ maxHeight: \"88px\" }}\n        placeholder=\"SET runoobkey redis\"\n        lineNumbers\n        canShowCompleteInfo\n        value={currentContent.query}\n        mode={CODE_LANG.JAVASCRIPT}\n        expectedType={VALIDATION_TYPES.STRING}\n        sqlScheme={sqlTable}\n        onChange={handleValueChange}\n      />\n\n      <TransformerComponent fullWidth />\n    </div>\n  )\n}\nRedisPanel.displayName = \"RedisPanel\"\nexport default RedisPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/RedisPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/RestApiPanel/BodyEditor/index.tsx",
    "content": "import { RestAPIRawBodyInitial } from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  RestAPIAction,\n  RestAPIBodyContent,\n  RestAPIBodyType,\n  RestAPIRawBody,\n} from \"@illa-public/public-types\"\nimport { Params } from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Select } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { RecordEditor } from \"@/components/RecordEditor\"\nimport { BodyEditorProps } from \"@/page/App/components/Actions/ActionPanel/RestApiPanel/BodyEditor/interface\"\nimport { getSelectedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport {\n  bodyChooserStyle,\n  bodyEditorContainerStyle,\n  bodyLabelStyle,\n  bodySelectorStyle,\n  codeEditorStyle,\n  restRecordKeyStyle,\n  restRecordValueStyle,\n} from \"./style\"\n\nexport const BodyEditor: FC<BodyEditorProps> = (props) => {\n  const { t } = useTranslation()\n\n  const actionItem = props.actionItem\n  const bodyType = actionItem.content.bodyType\n  const body = actionItem.content.body\n  const isFormData = bodyType === \"form-data\"\n\n  const selectedAction = useSelector(getSelectedAction) as ActionItem<\n    RestAPIAction<RestAPIBodyContent>\n  >\n  const dispatch = useDispatch()\n\n  let mode: CODE_LANG = CODE_LANG.JAVASCRIPT\n  if (bodyType === \"raw\") {\n    switch ((body as RestAPIRawBody).type) {\n      case \"text\":\n        mode = CODE_LANG.JAVASCRIPT\n        break\n      case \"json\":\n        mode = CODE_LANG.JSON\n        break\n      case \"xml\":\n        mode = CODE_LANG.XML\n        break\n      case \"javascript\":\n        mode = CODE_LANG.JAVASCRIPT\n        break\n      case \"html\":\n        mode = CODE_LANG.HTML\n        break\n    }\n  }\n\n  const handleActionTypeChange = useCallback(\n    (value: string) => {\n      let newBody = null\n      const content =\n        selectedAction?.content as RestAPIAction<RestAPIBodyContent>\n      if (\n        selectedAction.resourceID === actionItem.resourceID &&\n        content.method !== \"GET\" &&\n        content.bodyType !== \"none\" &&\n        content.bodyType === value\n      ) {\n        newBody = content.body\n      } else {\n        switch (value) {\n          case \"none\":\n            newBody = null\n            break\n          case \"x-www-form-urlencoded\":\n            newBody = [{ key: \"\", value: \"\" }] as Params[]\n            break\n          case \"form-data\":\n            newBody = [{ key: \"\", type: \"\", value: \"\" }] as Params[]\n            break\n          case \"raw\":\n            newBody = RestAPIRawBodyInitial\n            break\n          case \"binary\":\n            newBody = \"\"\n            break\n        }\n      }\n      dispatch(\n        configActions.updateCachedAction({\n          ...actionItem,\n          content: {\n            ...actionItem.content,\n            bodyType: value as RestAPIBodyType,\n            body: newBody,\n          },\n        }),\n      )\n    },\n    [actionItem, dispatch, selectedAction.content, selectedAction.resourceID],\n  )\n\n  const handleOnBodyChange = useCallback(\n    (value: string | Params[]) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...actionItem,\n          content: {\n            ...actionItem.content,\n            body: value,\n          },\n        }),\n      )\n    },\n    [actionItem, dispatch],\n  )\n\n  const handleRecordEditorValueChange = useCallback(\n    (index: number, key: string, type: string, value: string) => {\n      let newList: Params[] = [...(body as Params[])]\n      newList[index] = isFormData\n        ? { key, type, value }\n        : ({ key, value } as Params)\n      handleOnBodyChange(newList)\n    },\n    [body, handleOnBodyChange, isFormData],\n  )\n\n  const handleRawBodyTypeChange = useCallback(\n    (value: string, paramName: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...actionItem,\n          content: {\n            ...actionItem.content,\n            body: {\n              ...(body as RestAPIRawBody),\n              [paramName]: value,\n            },\n          },\n        }),\n      )\n    },\n    [actionItem, body, dispatch],\n  )\n\n  const handleFormUrlencodedValueChange = (\n    index: number,\n    key: string,\n    v: string,\n  ) => {\n    handleRecordEditorValueChange(index, key, \"\", v)\n  }\n\n  const handleOnAddKeys = useCallback(() => {\n    const newListItem = (\n      isFormData ? { key: \"\", type: \"\", value: \"\" } : { key: \"\", value: \"\" }\n    ) as Params\n    const newList: Params[] = [...(body as Params[]), newListItem]\n    handleOnBodyChange(newList)\n  }, [body, handleOnBodyChange, isFormData])\n\n  const handleOnDeleteKeys = useCallback(\n    (index: number) => {\n      let newList: Params[] = [...(body as Params[])]\n      const newListItem = (\n        isFormData ? { key: \"\", type: \"\", value: \"\" } : { key: \"\", value: \"\" }\n      ) as Params\n      newList.splice(index, 1)\n      if (newList.length === 0) {\n        newList = [newListItem]\n      }\n      handleOnBodyChange(newList)\n    },\n    [body, handleOnBodyChange, isFormData],\n  )\n\n  return (\n    <div css={bodyEditorContainerStyle}>\n      <span css={bodyLabelStyle}>\n        {t(\"editor.action.resource.restapi.label.body\")}\n      </span>\n      <div css={bodyChooserStyle}>\n        <div css={bodySelectorStyle}>\n          <Select\n            colorScheme=\"techPurple\"\n            value={bodyType}\n            options={[\n              \"none\",\n              \"form-data\",\n              \"x-www-form-urlencoded\",\n              \"raw\",\n              \"binary\",\n            ]}\n            bdRadius={bodyType === \"raw\" ? \"8px 0 0 8px\" : \"8px\"}\n            onChange={(v) => handleActionTypeChange(v as string)}\n          />\n          {bodyType === \"raw\" && (\n            <Select\n              bdRadius=\"0 8px 8px 0\"\n              colorScheme=\"techPurple\"\n              w=\"162px\"\n              ml=\"-1px\"\n              value={(body as RestAPIRawBody).type}\n              options={[\"text\", \"json\", \"xml\", \"javascript\", \"html\"]}\n              onChange={(val) => handleRawBodyTypeChange(val as string, \"type\")}\n            />\n          )}\n        </div>\n        {bodyType === \"raw\" && (\n          <div css={codeEditorStyle}>\n            <CodeEditor\n              showLineNumbers\n              lang={mode}\n              value={(body as RestAPIRawBody).content}\n              expectValueType={VALIDATION_TYPES.STRING}\n              height=\"88px\"\n              onChange={(value) => handleRawBodyTypeChange(value, \"content\")}\n            />\n          </div>\n        )}\n        {bodyType === \"x-www-form-urlencoded\" && (\n          <RecordEditor\n            label=\"\"\n            name=\"body\"\n            records={body as Params[]}\n            onChangeKey={handleFormUrlencodedValueChange}\n            onChangeValue={handleFormUrlencodedValueChange}\n            onDelete={handleOnDeleteKeys}\n            onAdd={handleOnAddKeys}\n          />\n        )}\n        {bodyType === \"form-data\" && (\n          <RecordEditor\n            label=\"\"\n            name=\"body\"\n            records={body as Params[]}\n            customRender={(record, index) => {\n              return (\n                <>\n                  <CodeEditor\n                    value={record.key}\n                    singleLine\n                    height=\"32px\"\n                    onChange={(val) =>\n                      handleRecordEditorValueChange(\n                        index,\n                        val,\n                        record.type,\n                        record.value,\n                      )\n                    }\n                    wrapperCss={restRecordKeyStyle}\n                    expectValueType={VALIDATION_TYPES.STRING}\n                    lang={CODE_LANG.JAVASCRIPT}\n                    placeholder=\"key\"\n                  />\n                  <Select\n                    colorScheme=\"techPurple\"\n                    showSearch={true}\n                    defaultValue={record.type}\n                    value={record.type}\n                    w=\"0\"\n                    bdRadius=\"0\"\n                    flexGrow=\"1\"\n                    onChange={(val) =>\n                      handleRecordEditorValueChange(\n                        index,\n                        record.key,\n                        val as string,\n                        record.value,\n                      )\n                    }\n                    options={[\n                      {\n                        label: t(\n                          \"editor.action.panel.label.option.restapi.body_type.text\",\n                        ),\n                        value: \"text\",\n                      },\n                      {\n                        label: t(\n                          \"editor.action.panel.label.option.restapi.body_type.file\",\n                        ),\n                        value: \"file\",\n                      },\n                    ]}\n                  />\n                  <CodeEditor\n                    singleLine\n                    expectValueType={\n                      record.type === \"file\"\n                        ? VALIDATION_TYPES.OBJECT\n                        : VALIDATION_TYPES.STRING\n                    }\n                    value={record.value}\n                    onChange={(val) =>\n                      handleRecordEditorValueChange(\n                        index,\n                        record.key,\n                        record.type,\n                        val,\n                      )\n                    }\n                    height=\"32px\"\n                    wrapperCss={restRecordValueStyle}\n                    lang={CODE_LANG.JAVASCRIPT}\n                    placeholder={\n                      record.type === \"file\"\n                        ? t(\n                            \"editor.action.panel.placeholder.restapi.body_type.file\",\n                          )\n                        : \"value\"\n                    }\n                  />\n                </>\n              )\n            }}\n            onChangeKey={() => {}}\n            onChangeValue={() => {}}\n            onDelete={handleOnDeleteKeys}\n            onAdd={handleOnAddKeys}\n          />\n        )}\n        {bodyType === \"binary\" && (\n          <div css={codeEditorStyle}>\n            <CodeEditor\n              lang={CODE_LANG.JAVASCRIPT}\n              showLineNumbers\n              value={(body as string) ?? \"\"}\n              expectValueType={VALIDATION_TYPES.STRING}\n              height=\"88px\"\n              onChange={handleOnBodyChange}\n            />\n          </div>\n        )}\n      </div>\n    </div>\n  )\n}\n\nBodyEditor.displayName = \"BodyEditor\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/RestApiPanel/BodyEditor/interface.ts",
    "content": "import {\n  ActionItem,\n  RestAPIAction,\n  RestAPIBodyContent,\n} from \"@illa-public/public-types\"\n\nexport interface BodyEditorProps {\n  actionItem: ActionItem<RestAPIAction<RestAPIBodyContent>>\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/RestApiPanel/BodyEditor/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport {\n  recordKeyStyle,\n  recordValueStyle,\n} from \"@/components/RecordEditor/style\"\n\nexport const bodyEditorContainerStyle = css`\n  display: flex;\n  padding: 0 16px;\n  flex-direction: row;\n`\n\nexport const bodyLabelStyle = css`\n  min-width: 160px;\n  height: 48px;\n  display: flex;\n  flex-direction: row;\n  justify-content: end;\n  align-items: center;\n  font-size: 14px;\n  font-weight: 500;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const bodyChooserStyle = css`\n  display: flex;\n  flex-grow: 1;\n  flex-direction: column;\n  margin-left: 16px;\n`\n\nexport const bodySelectorStyle = css`\n  display: flex;\n  height: 48px;\n  align-items: center;\n  flex-direction: row;\n`\n\nexport const codeEditorStyle = css`\n  margin: 8px 0;\n`\n\nexport const restRecordKeyStyle = css`\n  ${recordKeyStyle};\n  margin-right: -1px;\n`\n\nexport const restRecordValueStyle = css`\n  ${recordValueStyle};\n  & .cm-scroller {\n    overflow-x: hidden;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/RestApiPanel/index.tsx",
    "content": "import {\n  ActionItem,\n  Params,\n  Resource,\n  RestAPIAction,\n  RestAPIBodyContent,\n  RestAPIBodyType,\n  RestAPIMethod,\n  RestApiAuth,\n  RestApiResource,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Select, SelectValue, Trigger } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { RecordEditor } from \"@/components/RecordEditor\"\nimport { BodyEditor } from \"@/page/App/components/Actions/ActionPanel/RestApiPanel/BodyEditor\"\nimport {\n  actionItemContainer,\n  restapiItemInputStyle,\n  restapiItemLabelStyle,\n  restapiItemStyle,\n  urlStyle,\n} from \"@/page/App/components/Actions/ActionPanel/RestApiPanel/style\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { RootState } from \"@/store\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst resetAPIMethodSelectOptions: RestAPIMethod[] = [\n  \"GET\",\n  \"POST\",\n  \"PUT\",\n  \"HEAD\",\n  \"PATCH\",\n  \"DELETE\",\n  \"OPTIONS\",\n]\n\nconst RestApiPanel: FC = () => {\n  const { t } = useTranslation()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    RestAPIAction<RestAPIBodyContent>\n  >\n  const selectedAction = useSelector(getSelectedAction) as ActionItem<\n    RestAPIAction<RestAPIBodyContent>\n  >\n  const content = cachedAction.content as RestAPIAction<RestAPIBodyContent>\n  const dispatch = useDispatch()\n\n  const currentResource = useSelector((state: RootState) => {\n    return state.resource.find((r) => r.resourceID === cachedAction?.resourceID)\n  })\n\n  const handleChangeMethod = useCallback(\n    (value?: SelectValue) => {\n      let newBodyType: RestAPIBodyType = \"none\"\n      let newBody = null\n\n      if (value !== \"GET\") {\n        if (\n          selectedAction.resourceID === cachedAction.resourceID &&\n          selectedAction.content.method === value\n        ) {\n          newBodyType = selectedAction.content.bodyType\n          newBody = selectedAction.content.body\n        }\n      }\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...content,\n            method: value as RestAPIMethod,\n            bodyType: newBodyType,\n            body: newBody,\n          },\n        }),\n      )\n    },\n    [\n      cachedAction,\n      content,\n      dispatch,\n      selectedAction.content.body,\n      selectedAction.content.bodyType,\n      selectedAction.content.method,\n      selectedAction.resourceID,\n    ],\n  )\n\n  return (\n    <div css={actionItemContainer}>\n      <div css={restapiItemStyle}>\n        <span css={restapiItemLabelStyle}>\n          {t(\"editor.action.resource.restapi.label.action_type\")}\n        </span>\n        <Select\n          colorScheme=\"techPurple\"\n          ml=\"16px\"\n          value={content.method}\n          w=\"160px\"\n          maxW=\"160px\"\n          options={resetAPIMethodSelectOptions}\n          onChange={handleChangeMethod}\n        />\n        <Trigger\n          position=\"top-start\"\n          content={\n            currentResource?.content\n              ? (currentResource as Resource<RestApiResource<RestApiAuth>>)\n                  .content.baseUrl\n              : \"\"\n          }\n        >\n          <div css={urlStyle}>\n            {currentResource?.content\n              ? (currentResource as Resource<RestApiResource<RestApiAuth>>)\n                  .content.baseUrl\n              : \"\"}\n          </div>\n        </Trigger>\n        <CodeEditor\n          singleLine\n          wrapperCss={restapiItemInputStyle}\n          expectValueType={VALIDATION_TYPES.STRING}\n          value={content.url}\n          placeholder={t(\"editor.action.form.placeholder.url\")}\n          lang={CODE_LANG.JAVASCRIPT}\n          onChange={(value) => {\n            dispatch(\n              configActions.updateCachedAction({\n                ...cachedAction,\n                content: {\n                  ...content,\n                  url: value,\n                },\n              }),\n            )\n          }}\n        />\n      </div>\n      <RecordEditor\n        records={content.urlParams}\n        label={t(\"editor.action.resource.restapi.label.url_parameters\")}\n        onChangeKey={(index, key, v) => {\n          let newList: Params[] = [...content.urlParams]\n          newList[index] = { key, value: v } as Params\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                urlParams: newList,\n              },\n            }),\n          )\n        }}\n        onChangeValue={(index, key, v) => {\n          let newList: Params[] = [...content.urlParams]\n          newList[index] = { key, value: v } as Params\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                urlParams: newList,\n              },\n            }),\n          )\n        }}\n        onDelete={(index, _record) => {\n          let newList: Params[] = [...content.urlParams]\n          newList.splice(index, 1)\n          if (newList.length === 0) {\n            newList = [{ key: \"\", value: \"\" }]\n          }\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                urlParams: newList,\n              },\n            }),\n          )\n        }}\n        onAdd={() => {\n          let newList: Params[] = [\n            ...content.urlParams,\n            { key: \"\", value: \"\" } as Params,\n          ]\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                urlParams: newList,\n              },\n            }),\n          )\n        }}\n      />\n      <RecordEditor\n        records={content.headers}\n        label={t(\"editor.action.resource.restapi.label.headers\")}\n        onChangeKey={(index, key, v) => {\n          let newList: Params[] = [...content.headers]\n          newList[index] = { key, value: v } as Params\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                headers: newList,\n              },\n            }),\n          )\n        }}\n        onChangeValue={(index, key, v) => {\n          let newList: Params[] = [...content.headers]\n          newList[index] = { key, value: v } as Params\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                headers: newList,\n              },\n            }),\n          )\n        }}\n        onDelete={(index) => {\n          let newList: Params[] = [...content.headers]\n          newList.splice(index, 1)\n          if (newList.length === 0) {\n            newList = [{ key: \"\", value: \"\" }]\n          }\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                headers: newList,\n              },\n            }),\n          )\n        }}\n        onAdd={() => {\n          let newList: Params[] = [\n            ...content.headers,\n            { key: \"\", value: \"\" } as Params,\n          ]\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                headers: newList,\n              },\n            }),\n          )\n        }}\n      />\n      <RecordEditor\n        records={content.cookies}\n        label={t(\"editor.action.resource.restapi.label.cookies\")}\n        onChangeKey={(index, key, v) => {\n          let newList: Params[] = [...content.cookies]\n          newList[index] = { key, value: v } as Params\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                cookies: newList,\n              },\n            }),\n          )\n        }}\n        onChangeValue={(index, key, v) => {\n          let newList: Params[] = [...content.cookies]\n          newList[index] = { key, value: v } as Params\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                cookies: newList,\n              },\n            }),\n          )\n        }}\n        onDelete={(index) => {\n          let newList: Params[] = [...content.cookies]\n          newList.splice(index, 1)\n          if (newList.length === 0) {\n            newList = [{ key: \"\", value: \"\" }]\n          }\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                cookies: newList,\n              },\n            }),\n          )\n        }}\n        onAdd={() => {\n          let newList: Params[] = [\n            ...content.cookies,\n            { key: \"\", value: \"\" } as Params,\n          ]\n          dispatch(\n            configActions.updateCachedAction({\n              ...cachedAction,\n              content: {\n                ...content,\n                cookies: newList,\n              },\n            }),\n          )\n        }}\n      />\n      {![\"GET\", \"HEAD\"].includes(content.method) && (\n        <BodyEditor actionItem={cachedAction} />\n      )}\n      <TransformerComponent />\n    </div>\n  )\n}\n\nRestApiPanel.displayName = \"RestApiPanel\"\nexport default RestApiPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/RestApiPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const restapiPanelContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n`\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n\nexport const urlStyle = css`\n  width: 200px;\n  box-sizing: border-box;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-weight: 400;\n  margin-left: 24px;\n  margin-right: 8px;\n  border-radius: 8px 0 0 8px;\n  font-size: 14px;\n  text-overflow: ellipsis;\n  overflow-wrap: break-word;\n  white-space: nowrap;\n  overflow: hidden;\n`\n\nexport const restapiItemStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 48px;\n  padding: 0 16px;\n`\n\nexport const restapiItemLabelStyle = css`\n  min-width: 160px;\n  font-size: 14px;\n  font-weight: 500;\n  text-align: right;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const restapiItemInputStyle = css`\n  flex-grow: 1;\n  width: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/DeleteMultiplePart/index.tsx",
    "content": "import {\n  ActionItem,\n  S3Action,\n  S3ActionTypeContent,\n  S3DeleteMultipleContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { S3ActionPartProps } from \"@/page/App/components/Actions/ActionPanel/S3Panel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DeleteMultiplePart: FC<S3ActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    S3Action<S3ActionTypeContent>\n  >\n  const commandArgs = props.commandArgs as S3DeleteMultipleContent\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            commandArgs: {\n              ...commandArgs,\n              [name]: value,\n            } as S3DeleteMultipleContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, commandArgs, dispatch],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.s3.bucket_name\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.bucketName}\n        onChange={handleValueChange(\"bucketName\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.object_key_list\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        placeholder={t(\"editor.action.panel.s3.placeholder.object_key_list\")}\n        value={commandArgs.objectKeyList}\n        onChange={handleValueChange(\"objectKeyList\")}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n    </>\n  )\n}\n\nDeleteMultiplePart.displayName = \"DeleteMultiplePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/DeleteOnePart/index.tsx",
    "content": "import {\n  ActionItem,\n  S3Action,\n  S3ActionTypeContent,\n  S3DeleteOneContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { S3ActionPartProps } from \"@/page/App/components/Actions/ActionPanel/S3Panel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const DeleteOnePart: FC<S3ActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    S3Action<S3ActionTypeContent>\n  >\n  const commandArgs = props.commandArgs as S3DeleteOneContent\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            commandArgs: {\n              ...commandArgs,\n              [name]: value,\n            } as S3DeleteOneContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, commandArgs, dispatch],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.s3.bucket_name\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.bucketName}\n        onChange={handleValueChange(\"bucketName\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.object_key\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.objectKey}\n        onChange={handleValueChange(\"objectKey\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n    </>\n  )\n}\n\nDeleteOnePart.displayName = \"DeleteOnePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/DownloadOnePart/index.tsx",
    "content": "import {\n  ActionItem,\n  S3Action,\n  S3ActionTypeContent,\n  S3DownloadOneContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { S3ActionPartProps } from \"@/page/App/components/Actions/ActionPanel/S3Panel/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { SelectOption } from \"../constants\"\n\nexport const DownloadOnePart: FC<S3ActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    S3Action<S3ActionTypeContent>\n  >\n  const commandArgs = props.commandArgs as S3DownloadOneContent\n  const isShowSignedURL = commandArgs.signedURL\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string | boolean) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            commandArgs: {\n              ...commandArgs,\n              [name]: value,\n            } as S3DownloadOneContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, commandArgs, dispatch],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.s3.bucket_name\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.bucketName}\n        onChange={handleValueChange(\"bucketName\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.object_key\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.objectKey}\n        onChange={handleValueChange(\"objectKey\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <SingleTypeComponent\n        componentType=\"select\"\n        value={+commandArgs.signedURL}\n        style={{\n          position: \"relative\",\n          zIndex: 0,\n        }}\n        title={t(\"editor.action.panel.s3.generate_signed_url\")}\n        showSearch\n        onSelectedValueChange={(value) =>\n          handleValueChange(\"signedURL\")(!!value)\n        }\n        options={SelectOption}\n      />\n      {isShowSignedURL && (\n        <InputEditor\n          title={t(\"editor.action.panel.s3.expiry_duration_of_signed_url\")}\n          mode={CODE_LANG.JAVASCRIPT}\n          value={String(commandArgs.expiry)}\n          onChange={handleValueChange(\"expiry\")}\n          expectedType={VALIDATION_TYPES.NUMBER}\n        />\n      )}\n    </>\n  )\n}\n\nDownloadOnePart.displayName = \"DownloadOnePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/ListAllPart/index.tsx",
    "content": "import {\n  ActionItem,\n  S3Action,\n  S3ActionTypeContent,\n  S3ListAllContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { S3ActionPartProps } from \"@/page/App/components/Actions/ActionPanel/S3Panel/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { SelectOption } from \"../constants\"\n\nexport const ListAllPart: FC<S3ActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    S3Action<S3ActionTypeContent>\n  >\n  const commandArgs = props.commandArgs as S3ListAllContent\n  const isShowSignedURL = commandArgs.signedURL\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string | boolean) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            commandArgs: {\n              ...commandArgs,\n              [name]: value,\n            } as S3ListAllContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, commandArgs, dispatch],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.s3.bucket_name\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.bucketName}\n        onChange={handleValueChange(\"bucketName\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.prefix_to_filter_reseults\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.prefix}\n        onChange={handleValueChange(\"prefix\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.delimiter\")}\n        popoverContent={t(\"editor.action.panel.s3.tips.delimiter\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.delimiter}\n        onChange={handleValueChange(\"delimiter\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <SingleTypeComponent\n        componentType=\"select\"\n        value={+commandArgs.signedURL}\n        title={t(\"editor.action.panel.s3.generate_signed_url\")}\n        showSearch\n        onSelectedValueChange={(value) =>\n          handleValueChange(\"signedURL\")(!!value)\n        }\n        options={SelectOption}\n        style={{\n          position: \"relative\",\n          zIndex: 0,\n        }}\n      />\n      {isShowSignedURL && (\n        <InputEditor\n          title={t(\"editor.action.panel.s3.expiry_duration_of_signed_url\")}\n          mode={CODE_LANG.JAVASCRIPT}\n          value={String(commandArgs.expiry)}\n          onChange={handleValueChange(\"expiry\")}\n          expectedType={VALIDATION_TYPES.NUMBER}\n        />\n      )}\n      <InputEditor\n        title={t(\"editor.action.panel.s3.max_keys\")}\n        popoverContent={t(\"editor.action.panel.s3.tips.max_keys\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.maxKeys}\n        onChange={handleValueChange(\"maxKeys\")}\n        expectedType={VALIDATION_TYPES.NUMBER}\n      />\n    </>\n  )\n}\n\nListAllPart.displayName = \"ListAllPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/ReadOnePart/index.tsx",
    "content": "import {\n  ActionItem,\n  S3Action,\n  S3ActionTypeContent,\n  S3ReadOneContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { S3ActionPartProps } from \"@/page/App/components/Actions/ActionPanel/S3Panel/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { SelectOption } from \"../constants\"\n\nexport const ReadOnePart: FC<S3ActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    S3Action<S3ActionTypeContent>\n  >\n  const commandArgs = props.commandArgs as S3ReadOneContent\n  const isShowSignedURL = commandArgs.signedURL\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string | boolean) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            commandArgs: {\n              ...commandArgs,\n              [name]: value,\n            } as S3ReadOneContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, commandArgs, dispatch],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.s3.bucket_name\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.bucketName}\n        onChange={handleValueChange(\"bucketName\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.object_key\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.objectKey}\n        onChange={handleValueChange(\"objectKey\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <SingleTypeComponent\n        showSearch={true}\n        componentType=\"select\"\n        onChange={(value) => handleValueChange(\"signedURL\")(!!value)}\n        options={SelectOption}\n        value={+commandArgs.signedURL}\n        title={t(\"editor.action.panel.s3.generate_signed_url\")}\n        style={{\n          position: \"relative\",\n          zIndex: 0,\n        }}\n      />\n      {isShowSignedURL && (\n        <InputEditor\n          title={t(\"editor.action.panel.s3.generate_signed_url\")}\n          key=\"read\"\n          mode={CODE_LANG.JAVASCRIPT}\n          value={String(commandArgs.expiry)}\n          onChange={handleValueChange(\"expiry\")}\n          expectedType={VALIDATION_TYPES.NUMBER}\n        />\n      )}\n    </>\n  )\n}\n\nReadOnePart.displayName = \"ReadOnePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/UploadMultiplePart/index.tsx",
    "content": "import {\n  ActionItem,\n  S3Action,\n  S3ActionTypeContent,\n  S3UploadMultipleContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { S3ActionPartProps } from \"@/page/App/components/Actions/ActionPanel/S3Panel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport ContentTypeSelect from \"../components/ContentTypeSelect\"\n\nexport const UploadMultiplePart: FC<S3ActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    S3Action<S3ActionTypeContent>\n  >\n  const commandArgs = props.commandArgs as S3UploadMultipleContent\n  const handleValueChange = useCallback(\n    (name: string) => (value: string | boolean) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            commandArgs: {\n              ...commandArgs,\n              [name]: value,\n            } as S3UploadMultipleContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, commandArgs, dispatch],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.s3.bucket_name\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.bucketName}\n        onChange={handleValueChange(\"bucketName\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <ContentTypeSelect\n        value={commandArgs.contentType}\n        onChange={handleValueChange}\n        fx={commandArgs.fx}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.upload_object_name_list\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        placeholder={t(\"editor.action.panel.s3.placeholder.object_name_list\")}\n        value={commandArgs.objectKeyList}\n        onChange={handleValueChange(\"objectKeyList\")}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.upload_data_list\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        placeholder={t(\"editor.action.panel.s3.placeholder.data_list\")}\n        value={commandArgs.objectDataList}\n        onChange={handleValueChange(\"objectDataList\")}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.timeout_upload_multiple\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.expiry}\n        onChange={handleValueChange(\"expiry\")}\n        expectedType={VALIDATION_TYPES.NUMBER}\n      />\n    </>\n  )\n}\n\nUploadMultiplePart.displayName = \"UploadMultiplePart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/UploadPart/index.tsx",
    "content": "import {\n  ActionItem,\n  S3Action,\n  S3ActionTypeContent,\n  S3UploadContent,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { S3ActionPartProps } from \"@/page/App/components/Actions/ActionPanel/S3Panel/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport ContentTypeSelect from \"../components/ContentTypeSelect\"\n\nexport const UploadPart: FC<S3ActionPartProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    S3Action<S3ActionTypeContent>\n  >\n  const commandArgs = props.commandArgs as S3UploadContent\n  const handleValueChange = useCallback(\n    (name: string) => (value: string | boolean) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            commandArgs: {\n              ...commandArgs,\n              [name]: value,\n            } as S3UploadContent,\n          },\n        }),\n      )\n    },\n    [cachedAction, commandArgs, dispatch],\n  )\n\n  return (\n    <>\n      <InputEditor\n        title={t(\"editor.action.panel.s3.bucket_name\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.bucketName}\n        onChange={handleValueChange(\"bucketName\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <ContentTypeSelect\n        value={commandArgs.contentType}\n        onChange={handleValueChange}\n        fx={commandArgs.fx}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.upload_object_name\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        placeholder={t(\"editor.action.panel.s3.placeholder.object_name\")}\n        value={commandArgs.objectKey}\n        onChange={handleValueChange(\"objectKey\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.upload_data\")}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.objectData}\n        onChange={handleValueChange(\"objectData\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.s3.timeout_upload\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={commandArgs.expiry}\n        onChange={handleValueChange(\"expiry\")}\n        expectedType={VALIDATION_TYPES.NUMBER}\n      />\n    </>\n  )\n}\n\nUploadPart.displayName = \"UploadPart\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/components/ContentTypeSelect/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { FxIcon } from \"@illa-design/react\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { ContentTypeOptions } from \"../../constants\"\nimport { ContentTypeSelectProps } from \"./interface\"\nimport { containerStyle, getFxIconStyle } from \"./style\"\n\nexport const ContentTypeSelect: FC<ContentTypeSelectProps> = (props) => {\n  const { value, onChange, fx } = props\n  const { t } = useTranslation()\n\n  const handleOnClick = () => {\n    onChange(\"fx\")(!fx)\n  }\n\n  return (\n    <div css={containerStyle}>\n      {fx ? (\n        <InputEditor\n          title={t(\"editor.action.panel.s3.content_type\")}\n          value={value}\n          onChange={onChange(\"contentType\")}\n          expectedType={VALIDATION_TYPES.STRING}\n        />\n      ) : (\n        <SingleTypeComponent\n          title={t(\"editor.action.panel.s3.content_type\")}\n          componentType=\"select\"\n          value={value}\n          onChange={onChange(\"contentType\")}\n          options={ContentTypeOptions}\n        />\n      )}\n      <FxIcon onClick={handleOnClick} css={getFxIconStyle(fx)} />\n    </div>\n  )\n}\nContentTypeSelect.displayName = \"ContentTypeSelect\"\nexport default ContentTypeSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/components/ContentTypeSelect/interface.ts",
    "content": "export interface ContentTypeSelectProps {\n  value: string\n  onChange: (name: string) => (value: string | boolean) => void\n  fx: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/components/ContentTypeSelect/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const containerStyle = css`\n  display: flex;\n  align-items: center;\n  flex: 1;\n`\n\nexport const getFxIconStyle = (selected?: boolean) => {\n  return css`\n    width: 16px;\n    height: 16px;\n    color: ${selected\n      ? getColor(\"techPurple\", \"03\")\n      : getColor(\"grayBlue\", \"04\")};\n    cursor: pointer;\n    z-index: 1;\n    margin-right: 16px;\n    :hover {\n      cursor: pointer;\n      color: ${getColor(\"techPurple\", \"03\")};\n    }\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/constants.ts",
    "content": "import { S3ActionRequestType, S3_CONTENT_TYPE } from \"@illa-public/public-types\"\n\nenum S3ActionType {\n  LIST_ALL = \"List all objects in bucket\",\n  READ_ONE = \"Read an object\",\n  DOWNLOAD_ONE = \"Download an object\",\n  DELETE_ONE = \"Delete an object\",\n  DELETE_MULTIPLE = \"Delete multiple objects\",\n  UPLOAD = \"Upload data\",\n  UPLOAD_MULTIPLE = \"Upload multiple data\",\n}\n\nexport const S3ActionList = [\n  {\n    label: S3ActionType.LIST_ALL,\n    value: S3ActionRequestType.LIST_ALL,\n  },\n  {\n    label: S3ActionType.READ_ONE,\n    value: S3ActionRequestType.READ_ONE,\n  },\n  {\n    label: S3ActionType.DOWNLOAD_ONE,\n    value: S3ActionRequestType.DOWNLOAD_ONE,\n  },\n  {\n    label: S3ActionType.DELETE_ONE,\n    value: S3ActionRequestType.DELETE_ONE,\n  },\n  {\n    label: S3ActionType.DELETE_MULTIPLE,\n    value: S3ActionRequestType.DELETE_MULTIPLE,\n  },\n  {\n    label: S3ActionType.UPLOAD,\n    value: S3ActionRequestType.UPLOAD,\n  },\n  {\n    label: S3ActionType.UPLOAD_MULTIPLE,\n    value: S3ActionRequestType.UPLOAD_MULTIPLE,\n  },\n]\n\nexport const SelectOption = [\n  {\n    label: \"No\",\n    value: 0,\n  },\n  {\n    label: \"Yes\",\n    value: 1,\n  },\n]\n\nexport const ContentTypeOptions = [\n  {\n    label: \"Binary\",\n    value: S3_CONTENT_TYPE.BINARY,\n  },\n  {\n    label: \"CSV\",\n    value: S3_CONTENT_TYPE.CSV,\n  },\n  {\n    label: \"JSON\",\n    value: S3_CONTENT_TYPE.JSON,\n  },\n  {\n    label: \"String\",\n    value: S3_CONTENT_TYPE.STRING,\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/index.tsx",
    "content": "import {\n  S3DeleteMultipleContentInitial,\n  S3DeleteOneContentInitial,\n  S3DownloadOneContentInitial,\n  S3ListAllContentInitial,\n  S3ReadOneContentInitial,\n  S3UploadContentInitial,\n  S3UploadMultipleContentInitial,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionItem,\n  S3Action,\n  S3ActionRequestType,\n  S3ActionTypeContent,\n} from \"@illa-public/public-types\"\nimport { FC, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { DeleteMultiplePart } from \"./DeleteMultiplePart\"\nimport { DeleteOnePart } from \"./DeleteOnePart\"\nimport { DownloadOnePart } from \"./DownloadOnePart\"\nimport { ListAllPart } from \"./ListAllPart\"\nimport { ReadOnePart } from \"./ReadOnePart\"\nimport { UploadMultiplePart } from \"./UploadMultiplePart\"\nimport { UploadPart } from \"./UploadPart\"\nimport { S3ActionList } from \"./constants\"\nimport { actionItemContainer } from \"./style\"\n\nconst S3Panel: FC = () => {\n  const { t } = useTranslation()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    S3Action<S3ActionTypeContent>\n  >\n  const selectedAction = useSelector(getSelectedAction)!\n  const dispatch = useDispatch()\n  let content = cachedAction.content as S3Action<S3ActionTypeContent>\n\n  const renderInputBody = useMemo(() => {\n    switch (content.commands) {\n      case S3ActionRequestType.LIST_ALL:\n        return <ListAllPart commandArgs={content.commandArgs} />\n      case S3ActionRequestType.READ_ONE:\n        return <ReadOnePart commandArgs={content.commandArgs} />\n      case S3ActionRequestType.DOWNLOAD_ONE:\n        return <DownloadOnePart commandArgs={content.commandArgs} />\n      case S3ActionRequestType.DELETE_ONE:\n        return <DeleteOnePart commandArgs={content.commandArgs} />\n      case S3ActionRequestType.DELETE_MULTIPLE:\n        return <DeleteMultiplePart commandArgs={content.commandArgs} />\n      case S3ActionRequestType.UPLOAD:\n        return <UploadPart commandArgs={content.commandArgs} />\n      case S3ActionRequestType.UPLOAD_MULTIPLE:\n        return <UploadMultiplePart commandArgs={content.commandArgs} />\n      default:\n        return <></>\n    }\n  }, [content.commands, content.commandArgs])\n\n  const handleActionChange = (value: S3ActionRequestType) => {\n    let newCommandArgs: S3ActionTypeContent = S3ListAllContentInitial\n    if (\n      cachedAction.resourceID === selectedAction.resourceID &&\n      (selectedAction.content as S3Action<S3ActionTypeContent>).commands ===\n        value\n    ) {\n      newCommandArgs = (selectedAction.content as S3Action<S3ActionTypeContent>)\n        .commandArgs\n    } else {\n      switch (value) {\n        case S3ActionRequestType.LIST_ALL:\n          newCommandArgs = S3ListAllContentInitial\n          break\n        case S3ActionRequestType.READ_ONE:\n          newCommandArgs = S3ReadOneContentInitial\n          break\n        case S3ActionRequestType.DOWNLOAD_ONE:\n          newCommandArgs = S3DownloadOneContentInitial\n          break\n        case S3ActionRequestType.DELETE_ONE:\n          newCommandArgs = S3DeleteOneContentInitial\n          break\n        case S3ActionRequestType.DELETE_MULTIPLE:\n          newCommandArgs = S3DeleteMultipleContentInitial\n          break\n        case S3ActionRequestType.UPLOAD:\n          newCommandArgs = S3UploadContentInitial\n          break\n        case S3ActionRequestType.UPLOAD_MULTIPLE:\n          newCommandArgs = S3UploadMultipleContentInitial\n          break\n      }\n    }\n    dispatch(\n      configActions.updateCachedAction({\n        ...cachedAction,\n        content: {\n          ...cachedAction.content,\n          commands: value,\n          commandArgs: newCommandArgs,\n        },\n      }),\n    )\n  }\n\n  return (\n    <div css={actionItemContainer}>\n      <SingleTypeComponent\n        title={t(\"editor.action.panel.s3.action_type\")}\n        componentType=\"select\"\n        value={content.commands}\n        showSearch\n        onChange={handleActionChange}\n        options={S3ActionList}\n      />\n      {renderInputBody}\n      <TransformerComponent />\n    </div>\n  )\n}\n\nS3Panel.displayName = \"S3Panel\"\nexport default S3Panel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/interface.ts",
    "content": "import { S3ActionTypeContent } from \"@illa-public/public-types\"\n\nexport interface S3ActionPartProps {\n  commandArgs: S3ActionTypeContent\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/S3Panel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/SMTPPanel/index.tsx",
    "content": "import {\n  ActionItem,\n  SMPTAction,\n  SMTPActionContenType,\n} from \"@illa-public/public-types\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { SingleTypeComponent } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent\"\nimport { TransformerComponent } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { actionItemContainer } from \"./style\"\n\nconst SMTPPanel: FC = () => {\n  const { t } = useTranslation()\n  const cachedAction = useSelector(getCachedAction) as ActionItem<SMPTAction>\n  const content = cachedAction.content as SMPTAction\n  const isHTML = content.contentType === SMTPActionContenType.HTML\n  const dispatch = useDispatch()\n\n  const handleValueChange = useCallback(\n    (name: string) => (value: string | boolean) => {\n      dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          content: {\n            ...cachedAction.content,\n            [name]: value,\n          },\n        }),\n      )\n    },\n    [dispatch, cachedAction],\n  )\n\n  const handleShowReplyToEmail = useCallback(\n    (show: boolean) => {\n      handleValueChange(\"setReplyTo\")(show)\n    },\n    [handleValueChange],\n  )\n\n  const handleBodyTypeChange = useCallback(() => {\n    const contentType = isHTML\n      ? SMTPActionContenType.PLAIN\n      : SMTPActionContenType.HTML\n    handleValueChange(\"contentType\")(contentType)\n  }, [handleValueChange, isHTML])\n\n  return (\n    <div css={actionItemContainer}>\n      <InputEditor\n        title={t(\"editor.action.panel.smtp.from_email\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={content.from}\n        onChange={handleValueChange(\"from\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <SingleTypeComponent\n        componentType=\"checkbox\"\n        value={content.setReplyTo}\n        onChange={handleShowReplyToEmail}\n        checkoutTitle={t(\"editor.action.panel.smtp.set_replay_email\")}\n      />\n      {content.setReplyTo && (\n        <InputEditor\n          title={t(\"editor.action.panel.smtp.replay_email\")}\n          mode={CODE_LANG.JAVASCRIPT}\n          value={content.replyTo}\n          onChange={handleValueChange(\"replyTo\")}\n          expectedType={VALIDATION_TYPES.STRING}\n        />\n      )}\n      <InputEditor\n        title={t(\"editor.action.panel.smtp.to_email\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={content.to ?? \"\"}\n        placeholder={t(\"editor.action.panel.smtp.placeholder.emails\")}\n        onChange={handleValueChange(\"to\")}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.smtp.bcc_email\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        placeholder={t(\"editor.action.panel.smtp.placeholder.emails\")}\n        value={content.bcc ?? \"\"}\n        onChange={handleValueChange(\"bcc\")}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.smtp.cc_email\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={content.cc ?? \"\"}\n        placeholder={t(\"editor.action.panel.smtp.placeholder.emails\")}\n        onChange={handleValueChange(\"cc\")}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.smtp.subject\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={content.subject}\n        onChange={handleValueChange(\"subject\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.smtp.body\")}\n        subtitle={\n          isHTML\n            ? t(\"editor.action.panel.smtp.use_raw\")\n            : t(\"editor.action.panel.smtp.use_html\")\n        }\n        handleSubtitleClick={handleBodyTypeChange}\n        lineNumbers\n        style={{ height: \"88px\" }}\n        mode={isHTML ? CODE_LANG.HTML : CODE_LANG.JAVASCRIPT}\n        value={content.body}\n        onChange={handleValueChange(\"body\")}\n        expectedType={VALIDATION_TYPES.STRING}\n      />\n      <InputEditor\n        title={t(\"editor.action.panel.smtp.attachment\")}\n        mode={CODE_LANG.JAVASCRIPT}\n        value={content.attachment ?? \"\"}\n        placeholder={t(\"editor.action.panel.smtp.placeholder.attachment\")}\n        onChange={handleValueChange(\"attachment\")}\n        expectedType={VALIDATION_TYPES.ARRAY}\n      />\n      <TransformerComponent />\n    </div>\n  )\n}\n\nSMTPPanel.displayName = \"SMTPPanel\"\nexport default SMTPPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/SMTPPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/SingleTypeComponent/index.tsx",
    "content": "import { FC, useCallback, useMemo } from \"react\"\nimport {\n  Checkbox,\n  RadioGroup,\n  Select,\n  SelectValue,\n  Switch,\n} from \"@illa-design/react\"\nimport { SingleComponentProps } from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent/interface\"\nimport {\n  actionLabelStyle,\n  checkboxContentContainerStyle,\n  checkboxItemStyle,\n  checkboxTipsStyle,\n  checkoutContentStyle,\n  getActionItemStyle,\n} from \"@/page/App/components/Actions/ActionPanel/SingleTypeComponent/style\"\n\nexport const SingleTypeComponent: FC<SingleComponentProps> = (props) => {\n  const {\n    componentType,\n    title,\n    onChange,\n    value,\n    options,\n    checkoutTitle,\n    switchContent,\n    onSelectedValueChange,\n    onBooleanValueChange,\n    placeholder,\n    showSearch = false,\n    tips,\n    radioOptions,\n    forceEqualWidth,\n    type,\n    loading,\n    error,\n    style = {},\n  } = props\n\n  const handleSelectValueChange = useCallback(\n    (value?: boolean | SelectValue) => {\n      if (value === undefined) {\n        return\n      }\n      onChange?.(value)\n      if (typeof value !== \"boolean\") {\n        onSelectedValueChange?.(value)\n      }\n    },\n    [onChange, onSelectedValueChange],\n  )\n\n  const handleBooleanValueChange = useCallback(\n    (value: boolean) => {\n      onChange?.(value)\n      onBooleanValueChange?.(value)\n    },\n    [onBooleanValueChange, onChange],\n  )\n\n  const node = useMemo(() => {\n    switch (componentType) {\n      case \"radio-group\":\n        return (\n          <RadioGroup\n            w=\"100%\"\n            colorScheme=\"gray\"\n            ml=\"16px\"\n            type={type}\n            forceEqualWidth={forceEqualWidth}\n            onChange={onChange}\n            value={value}\n            options={radioOptions}\n          />\n        )\n      case \"select\":\n        return (\n          <Select\n            w=\"100%\"\n            colorScheme=\"techPurple\"\n            ml=\"16px\"\n            loading={loading}\n            error={error}\n            showSearch={showSearch}\n            onChange={handleSelectValueChange}\n            value={value as SelectValue}\n            options={options}\n            placeholder={placeholder}\n          />\n        )\n      case \"checkbox\":\n        return (\n          <div css={checkboxContentContainerStyle}>\n            <div css={checkoutContentStyle}>\n              <Checkbox\n                colorScheme=\"techPurple\"\n                checked={!!value}\n                ml=\"16px\"\n                onChange={handleBooleanValueChange}\n              />\n              <span css={checkboxItemStyle}>{checkoutTitle}</span>\n            </div>\n            {tips && <div css={checkboxTipsStyle}>{tips}</div>}\n          </div>\n        )\n      case \"switch\":\n        return (\n          <>\n            <Switch\n              colorScheme=\"techPurple\"\n              checked={!!value}\n              ml=\"16px\"\n              onChange={handleBooleanValueChange}\n            />\n            <span css={checkboxItemStyle}>{switchContent}</span>\n          </>\n        )\n    }\n  }, [\n    checkoutTitle,\n    componentType,\n    error,\n    forceEqualWidth,\n    handleBooleanValueChange,\n    handleSelectValueChange,\n    loading,\n    onChange,\n    options,\n    placeholder,\n    radioOptions,\n    showSearch,\n    switchContent,\n    tips,\n    type,\n    value,\n  ])\n\n  return (\n    <div css={getActionItemStyle(componentType)} style={style}>\n      <span css={actionLabelStyle}>{title}</span>\n      <>{node}</>\n    </div>\n  )\n}\n\nSingleTypeComponent.displayName = \"SingleTypeComponent\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/SingleTypeComponent/interface.ts",
    "content": "import { ReactNode } from \"react\"\nimport { RadioGroupProps, SelectProps, SelectValue } from \"@illa-design/react\"\n\nexport type SingleComponentType =\n  | \"select\"\n  | \"checkbox\"\n  | \"switch\"\n  | \"radio-group\"\n\nexport interface SingleComponentProps\n  extends Pick<SelectProps, \"options\" | \"showSearch\" | \"loading\" | \"error\">,\n    Pick<RadioGroupProps<any>, \"forceEqualWidth\" | \"type\"> {\n  componentType: SingleComponentType\n  title?: string\n  onChange?: (value: any) => void\n  onSelectedValueChange?: (value: SelectValue) => void\n  onBooleanValueChange?: (value: boolean) => void\n  value: boolean | SelectValue\n  checkoutTitle?: string\n  switchContent?: string\n  placeholder?: string\n  tips?: ReactNode\n  style?: Record<string, string | number>\n  radioOptions?: RadioGroupProps<any>[\"options\"]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/SingleTypeComponent/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const actionItemStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 48px;\n  padding: 0 16px;\n`\n\nexport const checkoutItemStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 30px;\n  padding: 0 16px;\n`\n\nexport const getActionItemStyle = (type: string) => {\n  if ([\"checkbox\", \"switch\"].includes(type)) {\n    return css`\n      ${checkoutItemStyle};\n      width: 100%;\n    `\n  }\n  return css`\n    ${actionItemStyle};\n    width: 100%;\n  `\n}\n\nexport const actionLabelStyle = css`\n  min-width: 160px;\n  width: 160px;\n  font-size: 14px;\n  font-weight: 500;\n  text-align: right;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  line-height: 22px;\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  justify-content: flex-end;\n`\n\nexport const checkboxItemStyle = css`\n  min-width: 160px;\n  font-size: 14px;\n  font-weight: 500;\n  margin-left: 10px;\n  text-align: left;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const checkoutContentStyle = css`\n  min-height: 22px;\n  align-self: flex-start;\n  display: flex;\n  align-items: center;\n`\n\nexport const checkboxTipsStyle = css`\n  display: inline-block;\n  line-height: 22px;\n  font-size: 14px;\n  text-align: right;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n\nexport const checkboxContentContainerStyle = css`\n  display: flex;\n  justify-content: space-between;\n  padding: 8px 0;\n  align-items: center;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/TransformerComponent/index.tsx",
    "content": "import {\n  TransformerInitial,\n  TransformerInitialTrue,\n} from \"@illa-public/public-configs\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { RadioGroup } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { TransformComponentProps } from \"@/page/App/components/Actions/ActionPanel/TransformerComponent/interface\"\nimport {\n  codeMirrorStyle,\n  getCodeMirrorContainerStyle,\n  transformRadioStyle,\n  transformSpaceStyle,\n  transformTitle,\n  transformTitleStyle,\n} from \"@/page/App/components/Actions/ActionPanel/TransformerComponent/style\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const TransformerComponent: FC<TransformComponentProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n\n  const { fullWidth } = props\n  const cachedAction = useSelector(getCachedAction)\n  const selectedAction = useSelector(getSelectedAction)\n\n  return (\n    <>\n      {cachedAction && (\n        <div css={transformTitleStyle}>\n          {fullWidth ? (\n            <PanelLabel\n              labelName={t(\"editor.action.panel.label.transformer\")}\n            />\n          ) : (\n            <span css={transformTitle}>\n              {t(\"editor.action.panel.label.transformer\")}\n            </span>\n          )}\n          <div css={transformSpaceStyle} />\n          <RadioGroup\n            css={transformRadioStyle}\n            forceEqualWidth={true}\n            size=\"medium\"\n            colorScheme=\"gray\"\n            value={cachedAction.transformer.enable}\n            type=\"button\"\n            options={[\n              {\n                value: false,\n                label: t(\"editor.action.panel.btn.disable\"),\n              },\n              {\n                value: true,\n                label: t(\"editor.action.panel.btn.enable\"),\n              },\n            ]}\n            onChange={(value) => {\n              let transformer = TransformerInitial\n              if (\n                selectedAction &&\n                selectedAction.transformer.enable === value\n              ) {\n                transformer = selectedAction.transformer || \"\"\n              } else {\n                if (value) {\n                  transformer = TransformerInitialTrue\n                }\n              }\n              dispatch(\n                configActions.updateCachedAction({\n                  ...cachedAction,\n                  transformer: transformer,\n                }),\n              )\n            }}\n          />\n        </div>\n      )}\n      {cachedAction && cachedAction.transformer.enable && (\n        <div css={getCodeMirrorContainerStyle(!!fullWidth)}>\n          {fullWidth ? null : <span css={transformTitle} />}\n          <CodeEditor\n            value={cachedAction.transformer.rawData}\n            wrapperCss={codeMirrorStyle}\n            showLineNumbers\n            canShowCompleteInfo\n            height=\"88px\"\n            expectValueType={VALIDATION_TYPES.STRING}\n            lang={CODE_LANG.JAVASCRIPT}\n            codeType={CODE_TYPE.NO_METHOD_FUNCTION}\n            modalTitle={t(\"editor.action.panel.label.transformer\")}\n            onChange={(value) => {\n              dispatch(\n                configActions.updateCachedAction({\n                  ...cachedAction,\n                  transformer: {\n                    ...cachedAction.transformer,\n                    rawData: value,\n                  },\n                }),\n              )\n            }}\n          />\n        </div>\n      )}\n    </>\n  )\n}\n\nTransformerComponent.displayName = \"TransformerComponent\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/TransformerComponent/interface.ts",
    "content": "export interface TransformComponentProps {\n  fullWidth?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/TransformerComponent/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const transformTitleStyle = css`\n  min-height: 48px;\n  width: 100%;\n  margin: 0;\n  padding: 0 16px;\n  display: flex;\n  align-items: center;\n  flex-direction: row;\n`\n\nexport const transformRadioStyle = css`\n  width: 184px;\n`\n\nexport const transformSpaceStyle = css`\n  flex-grow: 1;\n`\n\nexport const codeMirrorStyle = css`\n  margin: 8px 16px;\n  width: 100%;\n`\n\nexport const transformTitle = css`\n  min-width: 160px;\n  font-size: 14px;\n  font-weight: 500;\n  text-align: right;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const codeMirrorContainer = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 48px;\n`\n\nexport const codeMirrorPaddingContainer = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 48px;\n  padding: 0 0 0 16px;\n`\n\nexport const getCodeMirrorContainerStyle = (mysqlLike: boolean) => {\n  if (mysqlLike) {\n    return css`\n      ${codeMirrorContainer}\n    `\n  } else {\n    return css`\n      ${codeMirrorPaddingContainer}\n    `\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/TransformerPanel/index.tsx",
    "content": "import { TransformerAction } from \"@illa-public/public-types\"\nimport { FC, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport {\n  realInputValueWithScript,\n  wrapperScriptCode,\n} from \"@/utils/evaluateDynamicString/valueConverter\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { transformerPanelContainerStyle, transformerTipStyle } from \"./style\"\n\nconst TransformerPanel: FC = () => {\n  const { t } = useTranslation()\n\n  const action = useSelector(getCachedAction)!!\n  const content = action.content as TransformerAction\n\n  const dispatch = useDispatch()\n\n  const realInputValue = useMemo(() => {\n    return realInputValueWithScript(content.transformerString)\n  }, [content.transformerString])\n\n  return (\n    <div css={transformerPanelContainerStyle}>\n      <CodeEditor\n        value={realInputValue}\n        showLineNumbers\n        canShowCompleteInfo\n        height=\"88px\"\n        expectValueType={VALIDATION_TYPES.STRING}\n        lang={CODE_LANG.JAVASCRIPT}\n        codeType={CODE_TYPE.NO_METHOD_FUNCTION}\n        onChange={(value) => {\n          dispatch(\n            configActions.updateCachedAction({\n              ...action,\n              content: {\n                transformerString: wrapperScriptCode(value),\n              },\n            }),\n          )\n        }}\n      />\n      <div css={transformerTipStyle}>\n        {t(\"editor.action.resource.transformer.tip.external_reference\")}\n      </div>\n    </div>\n  )\n}\n\nTransformerPanel.displayName = \"TransformerPanel\"\nexport default TransformerPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/TransformerPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const transformerPanelContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  padding: 8px 16px;\n`\n\nexport const transformerTipStyle = css`\n  margin: 0 16px;\n  font-size: 12px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/index.tsx",
    "content": "import {\n  ILLAProperties,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  ILLA_MIXPANEL_PUBLIC_PAGE_NAME,\n  ILLA_PAGE_NAME,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport { INIT_ACTION_MOCK_CONFIG } from \"@illa-public/public-configs\"\nimport { Suspense, lazy } from \"react\"\nimport { FC, useCallback, useMemo, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { ActionResult } from \"@/page/App/components/Actions/ActionPanel/ActionResult\"\nimport { ActionTitleBar } from \"@/page/App/components/Actions/ActionPanel/ActionTitleBar\"\nimport {\n  actionContentStyle,\n  actionPanelContainerStyle,\n  actionPanelStyle,\n  outterActionContainerStyle,\n} from \"@/page/App/components/Actions/ActionPanel/style\"\nimport {\n  getCachedAction,\n  getSelectedAction,\n} from \"@/redux/config/configSelector\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport WidgetLoading from \"@/widgetLibrary/PublicSector/WidgetLoading\"\nimport { SQLModeTipProvider } from \"../Context/SqlModeTipContext\"\nimport ActionMockPanel from \"./ActionMockPanel\"\nimport GeneralPanelLayout from \"./Layout/GeneralPanelLayout\"\n\nconst AdvancedPanel = lazy(\n  () => import(\"@/page/App/components/Actions/AdvancedPanel\"),\n)\n\nconst AirtablePanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/AirtablePanel\"),\n)\nconst AppwritePanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/AppwritePanel\"),\n)\nconst CouchDBPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/CouchDBPanel\"),\n)\nconst DynamoDBPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/DynamoDBPanel\"),\n)\nconst ElasticSearchPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/ElasticSearchPanel\"),\n)\nconst FirebasePanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/FirebasePanel\"),\n)\nconst GoogleSheetsPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/GoogleSheetsPanel\"),\n)\nconst GraphQLPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/GraphQLPanel\"),\n)\nconst HuggingFaceEndpointPanel = lazy(\n  () =>\n    import(\n      \"@/page/App/components/Actions/ActionPanel/HuggingFaceEndpointPanel\"\n    ),\n)\nconst HuggingFacePanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/HuggingFacePanel\"),\n)\nconst MicrosoftSqlPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/MicrosoftSqlPanel\"),\n)\nconst MongoDbPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/MongoDbPanel\"),\n)\nconst MysqlLikePanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/MysqlLikePanel\"),\n)\nconst OracleDBPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/OracleDBPanel\"),\n)\nconst RedisPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/RedisPanel\"),\n)\nconst RestApiPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/RestApiPanel\"),\n)\nconst S3Panel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/S3Panel\"),\n)\nconst SMTPPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/SMTPPanel\"),\n)\nconst TransformerPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/TransformerPanel\"),\n)\nconst AIAgentPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/AIAgentPanel\"),\n)\n\nconst GlobalDataPanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/GlobalDataPanel\"),\n)\n\nconst ILLADrivePanel = lazy(\n  () => import(\"@/page/App/components/Actions/ActionPanel/ILLADrivePanel\"),\n)\n\nexport const ActionPanel: FC = () => {\n  const cachedAction = useSelector(getCachedAction)\n  const selectedAction = useSelector(getSelectedAction)!\n\n  const [resultVisible, setResultVisible] = useState(false)\n  const [activeKey, setActiveKey] = useState(\"general\")\n\n  const handleClickChangeTab = useCallback(\n    (activeKey: string) => {\n      setActiveKey(activeKey)\n      if (activeKey === \"advanced\") {\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n          element: \"advanced_tab\",\n          parameter1: cachedAction?.actionType,\n          parameter2: cachedAction,\n        })\n      }\n      if (activeKey === \"general\") {\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n          element: \"general_tab\",\n          parameter1: cachedAction?.actionType,\n        })\n      }\n    },\n    [cachedAction],\n  )\n  const basicTrack = useCallback(() => {\n    return (\n      event: ILLA_MIXPANEL_EVENT_TYPE,\n      pageName: ILLA_PAGE_NAME,\n      properties: Omit<ILLAProperties, \"page\">,\n    ) => {\n      trackInEditor(event, {\n        parameter1: cachedAction?.actionType,\n        parameter2: cachedAction,\n        ...properties,\n      })\n    }\n  }, [cachedAction])\n\n  const mockConfig = cachedAction?.config?.mockConfig ?? INIT_ACTION_MOCK_CONFIG\n\n  const panel = useMemo(() => {\n    switch (cachedAction?.actionType) {\n      case \"clickhouse\":\n      case \"supabasedb\":\n      case \"mysql\":\n      case \"tidb\":\n      case \"mariadb\":\n      case \"postgresql\":\n      case \"snowflake\":\n      case \"neon\":\n      case \"hydra\":\n        return <MysqlLikePanel />\n      case \"mssql\":\n        return <MicrosoftSqlPanel />\n      case \"oracle\":\n      case \"oracle9i\":\n        return <OracleDBPanel />\n      case \"restapi\":\n        return <RestApiPanel />\n      case \"huggingface\":\n        return <HuggingFacePanel />\n      case \"hfendpoint\":\n        return <HuggingFaceEndpointPanel />\n      case \"redis\":\n      case \"upstash\":\n        return <RedisPanel />\n      case \"mongodb\":\n        return <MongoDbPanel />\n      case \"transformer\":\n        return <TransformerPanel />\n      case \"elasticsearch\":\n        return <ElasticSearchPanel />\n      case \"dynamodb\":\n        return <DynamoDBPanel />\n      case \"s3\":\n        return <S3Panel />\n      case \"smtp\":\n        return <SMTPPanel />\n      case \"googlesheets\":\n        return <GoogleSheetsPanel />\n      case \"firebase\":\n        return <FirebasePanel />\n      case \"graphql\":\n        return <GraphQLPanel />\n      case \"appwrite\":\n        return <AppwritePanel />\n      case \"couchdb\":\n        return <CouchDBPanel />\n      case \"airtable\":\n        return <AirtablePanel />\n      case \"aiagent\":\n        return <AIAgentPanel />\n      case \"globalData\":\n        return <GlobalDataPanel />\n      case \"illadrive\":\n        return <ILLADrivePanel />\n      default:\n        return <></>\n    }\n  }, [cachedAction])\n\n  if (!cachedAction) {\n    return <></>\n  }\n\n  return (\n    <div css={actionPanelStyle}>\n      <SQLModeTipProvider>\n        <div css={actionPanelContainerStyle}>\n          <ActionTitleBar\n            onResultVisibleChange={(visible) => {\n              setResultVisible(visible)\n            }}\n            openState={resultVisible}\n            activeTab={activeKey}\n            handleChangeTab={handleClickChangeTab}\n          />\n          <Suspense fallback={<WidgetLoading />}>\n            {activeKey === \"general\" && (\n              <div css={outterActionContainerStyle}>\n                <GeneralPanelLayout\n                  actionType={cachedAction?.actionType}\n                  mockEnabled={mockConfig?.enabled}\n                >\n                  {mockConfig?.enabled ? (\n                    <ActionMockPanel\n                      enableForReleasedApp={mockConfig.enableForReleasedApp}\n                      mockData={mockConfig.mockData}\n                    />\n                  ) : (\n                    <div css={actionContentStyle}>{panel}</div>\n                  )}\n                </GeneralPanelLayout>\n              </div>\n            )}\n            {activeKey === \"advanced\" && (\n              <MixpanelTrackProvider\n                basicTrack={basicTrack}\n                pageName={ILLA_MIXPANEL_PUBLIC_PAGE_NAME.PLACEHOLDER}\n              >\n                <AdvancedPanel />\n              </MixpanelTrackProvider>\n            )}\n          </Suspense>\n          {resultVisible && (\n            <ActionResult\n              key={selectedAction?.actionID}\n              visible={resultVisible}\n              onClose={() => {\n                setResultVisible(false)\n              }}\n            />\n          )}\n        </div>\n      </SQLModeTipProvider>\n    </div>\n  )\n}\n\nActionPanel.displayName = \"ActionPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/pulicComponent/SQLModeSelector/index.tsx",
    "content": "import {\n  ActionItem,\n  MicrosoftSqlAction,\n  MicrosoftSqlActionType,\n  MysqlLikeAction,\n  OracleDBAction,\n  OracleDBActionType,\n} from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { RadioGroup } from \"@illa-design/react\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\n\nexport const SQLModeSelector: FC = () => {\n  const { t } = useTranslation()\n  const sqlModeOptions = [\n    {\n      label: t(\"editor.action.panel.label.option.general.safe\"),\n      value: \"sql-safe\",\n    },\n    {\n      label: t(\"editor.action.panel.label.option.general.unsafe\"),\n      value: \"sql\",\n    },\n  ]\n\n  const cachedAction = useSelector(getCachedAction) as ActionItem<\n    | MicrosoftSqlAction<MicrosoftSqlActionType>\n    | MysqlLikeAction\n    | OracleDBAction<OracleDBActionType>\n  >\n  const dispatch = useDispatch()\n  const handleOnChangeSqlMode = (value: \"sql\" | \"sql-safe\") => {\n    dispatch(\n      configActions.updateCachedAction({\n        ...cachedAction,\n        content: {\n          ...cachedAction.content,\n          mode: value,\n        },\n      } as ActionItem<\n        | MicrosoftSqlAction<MicrosoftSqlActionType>\n        | MysqlLikeAction\n        | OracleDBAction<OracleDBActionType>\n      >),\n    )\n  }\n\n  return (\n    <RadioGroup\n      colorScheme=\"gray\"\n      w=\"184px\"\n      size=\"small\"\n      type=\"button\"\n      forceEqualWidth\n      onChange={handleOnChangeSqlMode}\n      value={cachedAction.content.mode}\n      options={sqlModeOptions}\n    />\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/pulicComponent/SQLModeTip/index.tsx",
    "content": "import { hasDynamicStringSnippet } from \"@illa-public/dynamic-string\"\nimport { FC, useContext, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport {\n  BoxProps,\n  CloseIcon,\n  WarningIcon,\n  applyBoxStyle,\n  getColor,\n} from \"@illa-design/react\"\nimport { getSelectedAction } from \"@/redux/config/configSelector\"\nimport { SQLModeTipContext } from \"../../../Context/SqlModeTipContext\"\nimport {\n  iconStyle,\n  modeTipContainerStyle,\n  modeTipContentStyle,\n  modeTipHeaderStyle,\n  titleStyle,\n  warnIconStyle,\n} from \"./style\"\n\ninterface SQLModeTipProps extends BoxProps {\n  value: string\n}\n\nconst SQLModeTip: FC<SQLModeTipProps> = ({ value, ...styleProps }) => {\n  const { t } = useTranslation()\n  const { showSQLModeTip, setShowSQLModeTip } = useContext(SQLModeTipContext)\n  const selectedAction = useSelector(getSelectedAction)! ?? {}\n  const hasDynamicString = hasDynamicStringSnippet(value)\n  const showCurrentActionTip = showSQLModeTip[selectedAction.actionID]\n\n  const handleClose = () => {\n    setShowSQLModeTip(selectedAction.actionID, false)\n  }\n\n  const show = useMemo(() => {\n    if (hasDynamicString && showCurrentActionTip === undefined) return true\n    return hasDynamicString && showCurrentActionTip\n  }, [showCurrentActionTip, hasDynamicString])\n\n  if (!show) return null\n  return (\n    <div css={[modeTipContainerStyle, applyBoxStyle(styleProps)]}>\n      <div css={modeTipHeaderStyle}>\n        <span css={warnIconStyle}>\n          <WarningIcon color={getColor(\"white\", \"01\")} size=\"16px\" />\n        </span>\n        <span css={titleStyle}>\n          {t(\"editor.action.panel.label.tips.title.safe_mode\")}\n        </span>\n        <span css={iconStyle} onClick={handleClose}>\n          <CloseIcon color={getColor(\"orange\", \"03\")} size=\"8px\" />\n        </span>\n      </div>\n      <div css={modeTipContentStyle}>\n        {t(\"editor.action.panel.label.tips.desc.safe_mode\")}\n      </div>\n    </div>\n  )\n}\n\nexport default SQLModeTip\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/pulicComponent/SQLModeTip/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const modeTipContainerStyle = css`\n  padding: 16px;\n  margin-top: 8px;\n  border-radius: 4px;\n  gap: 8px;\n  background-color: ${getColor(\"orange\", \"08\")};\n`\n\nexport const modeTipHeaderStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const warnIconStyle = css`\n  width: 16px;\n  height: 16px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  border-radius: 50%;\n  background-color: ${getColor(\"orange\", \"03\")};\n`\n\nexport const titleStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  width: 100%;\n  font-size: 16px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 24px;\n`\n\nexport const iconStyle = css`\n  display: flex;\n  width: 24px;\n  height: 24px;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  gap: 10px;\n  cursor: pointer;\n`\n\nexport const modeTipContentStyle = css`\n  display: flex;\n  padding-left: 24px;\n  align-items: center;\n  gap: 8px;\n  align-self: stretch;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 22px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const actionPanelStyle = css`\n  flex-grow: 1;\n  height: 100%;\n  overflow-x: auto;\n  overflow-y: hidden;\n  display: flex;\n  flex-direction: column;\n  position: relative;\n`\n\nexport const actionPanelContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  min-width: 877px;\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  overflow-y: hidden;\n`\n\nexport const actionContentStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n`\n\nexport const outterActionContainerStyle = css`\n  padding-bottom: 48px;\n  width: 100%;\n  height: calc(100% - 48px);\n  overflow-y: auto;\n  padding-top: 8px;\n`\n\nexport const actionItemContainer = css`\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/utils/calculateFileSize.ts",
    "content": "import { hasDynamicStringSnippet } from \"@illa-public/dynamic-string\"\nimport { ActionType } from \"@illa-public/public-types\"\nimport { evaluateDynamicString } from \"@/utils/evaluateDynamicString\"\nimport { ILLAEditorRuntimePropsCollectorInstance } from \"@/utils/executionTreeHelper/runtimePropsCollector\"\nimport { calculateFileSize } from \"@/utils/file\"\n\nconst MAX_SIZE = 5 * 1024 * 1024\n\nexport const getFileValue = (data: string) => {\n  let value = data\n  if (hasDynamicStringSnippet(data)) {\n    const finalContext =\n      ILLAEditorRuntimePropsCollectorInstance.getGlobalCalcContext()\n    try {\n      value = evaluateDynamicString(\"\", data, finalContext)\n    } catch (ignore) {}\n  }\n  return value\n}\n\nexport const isFileOversize = (data: string, type?: ActionType) => {\n  if (!data.length) {\n    return false\n  }\n  const content = getFileValue(data)\n  const isSMTP = type && type === \"smtp\"\n  if (Array.isArray(content)) {\n    if (content.length <= 0) {\n      return false\n    }\n    return content.every((value) => {\n      const calculateValue = isSMTP ? value.data || \"\" : value\n      return !!(calculateFileSize(calculateValue) > MAX_SIZE)\n    })\n  } else {\n    return !!(calculateFileSize(content) > MAX_SIZE)\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ActionPanel/utils/safeModeTip.ts",
    "content": "const SAFE_MODE_ACTION_TYPE = [\n  \"clickhouse\",\n  \"supabasedb\",\n  \"mysql\",\n  \"tidb\",\n  \"mariadb\",\n  \"postgresql\",\n  \"snowflake\",\n  \"neon\",\n  \"hydra\",\n  \"mssql\",\n  \"oracle\",\n  \"oracle9i\",\n]\n\nexport const isSafeModeAction = (actionType: string) => {\n  return SAFE_MODE_ACTION_TYPE.includes(actionType)\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/Components/Control/index.tsx",
    "content": "import { FC } from \"react\"\nimport { AdvancedPanelControlProps } from \"./interface\"\nimport {\n  applyControllerContainerStyle,\n  controlTitleStyle,\n  controlWrapperStyle,\n  notAllowedMask,\n  subtitleStyle,\n} from \"./style\"\n\nexport const AdvancedPanelControl: FC<AdvancedPanelControlProps> = (props) => {\n  const { title, children, disabled, subtitle } = props\n  return (\n    <div css={applyControllerContainerStyle(disabled)}>\n      <h6 css={controlTitleStyle}>{title}</h6>\n      <div css={controlWrapperStyle}>\n        {children}\n        {subtitle && <span css={subtitleStyle}>{subtitle}</span>}\n        {disabled && <div css={notAllowedMask} />}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/Components/Control/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface AdvancedPanelControlProps {\n  title: string\n  subtitle?: string\n  children: ReactNode\n  disabled?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/Components/Control/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const applyControllerContainerStyle = (disable?: boolean) => css`\n  display: flex;\n  width: 100%;\n  padding: 8px 16px;\n  gap: 16px;\n  align-items: center;\n  opacity: ${!!disable ? 0.3 : 1};\n`\n\nexport const subtitleStyle = css`\n  font-size: 14px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-weight: 500;\n`\nexport const controlTitleStyle = css`\n  width: 240px;\n  flex: none;\n  text-align: right;\n  margin: 0;\n  ${subtitleStyle};\n`\n\nexport const controlWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  width: 100%;\n  position: relative;\n`\n\nexport const notAllowedMask = css`\n  position: absolute;\n  left: 0;\n  top: 0;\n  width: 100%;\n  height: 100%;\n  z-index: 1;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/Components/Header/index.tsx",
    "content": "import { FC } from \"react\"\nimport { AdvancedPanelHeaderProps } from \"./interface\"\nimport { advancedPanelHeaderContainerStyle } from \"./style\"\n\nexport const AdvancedPanelHeader: FC<AdvancedPanelHeaderProps> = (props) => {\n  const { title } = props\n  return <h3 css={advancedPanelHeaderContainerStyle}>{title}</h3>\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/Components/Header/interface.ts",
    "content": "export interface AdvancedPanelHeaderProps {\n  title: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/Components/Header/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const advancedPanelHeaderContainerStyle = css`\n  width: 100%;\n  padding: 16px 16px 0;\n  margin: 0;\n  font-size: 14px;\n  font-weight: 500;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  text-transform: uppercase;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/Components/Space/index.tsx",
    "content": "import { FC } from \"react\"\nimport { advancedPanelSpaceStyle } from \"./style\"\n\nexport const AdvancedPanelSpace: FC = () => {\n  return <div css={advancedPanelSpaceStyle} />\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/Components/Space/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const advancedPanelSpaceStyle = css`\n  width: 100%;\n  height: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/Model/AdvancedOption/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackContext,\n} from \"@illa-public/mixpanel-utils\"\nimport { IAdvancedConfig } from \"@illa-public/public-types\"\nimport { FC, useCallback, useContext } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Switch } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { AdvancedPanelControl } from \"@/page/App/components/Actions/AdvancedPanel/Components/Control\"\nimport { AdvancedPanelHeader } from \"@/page/App/components/Actions/AdvancedPanel/Components/Header\"\nimport { getCachedActionAdvancedConfig } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const AdvancedOptionSetting: FC = () => {\n  const cachedActionAdvancedConfig = useSelector(getCachedActionAdvancedConfig)\n  const { periodInterval, isPeriodically } = cachedActionAdvancedConfig\n\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n  const { track } = useContext(MixpanelTrackContext)\n\n  const handleUpdateAdvancedConfig = useCallback(\n    (key: keyof IAdvancedConfig) => {\n      return (value: unknown) => {\n        const updateSlice = {\n          [key]: value,\n        }\n\n        switch (key) {\n          case \"isPeriodically\": {\n            if (!!value) {\n              updateSlice.periodInterval = \"{{1800}}\"\n            } else {\n              updateSlice.periodInterval = \"\"\n            }\n            break\n          }\n          default:\n            break\n        }\n\n        dispatch(\n          configActions.updateCachedActionAdvancedConfigReducer(updateSlice),\n        )\n      }\n    },\n    [dispatch],\n  )\n\n  const handleCodeMirrorFocus = useCallback(\n    (attrName: string) => {\n      return () => {\n        track(ILLA_MIXPANEL_EVENT_TYPE.FOCUS, {\n          element: \"advanced_code_mirror\",\n          parameter2: attrName,\n        })\n      }\n    },\n    [track],\n  )\n\n  const handleCodeMirrorBlur = useCallback(\n    (attrName: string) => {\n      return (value: string) => {\n        track(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n          element: \"advanced_code_mirror\",\n          parameter2: attrName,\n          parameter3: value,\n        })\n      }\n    },\n    [track],\n  )\n\n  return (\n    <div>\n      <AdvancedPanelHeader title=\"Advanced option\" />\n      <AdvancedPanelControl\n        title=\"\"\n        subtitle={t(\"editor.action.panel.label.advanced.run_this_action_peri\")}\n      >\n        <Switch\n          colorScheme=\"techPurple\"\n          checked={isPeriodically}\n          onChange={handleUpdateAdvancedConfig(\"isPeriodically\")}\n        />\n      </AdvancedPanelControl>\n      <AdvancedPanelControl\n        title={t(\"editor.action.panel.label.advanced.interval\")}\n        disabled={!isPeriodically}\n      >\n        <CodeEditor\n          value={periodInterval}\n          onChange={handleUpdateAdvancedConfig(\"periodInterval\")}\n          expectValueType={VALIDATION_TYPES.NUMBER}\n          onFocus={handleCodeMirrorFocus(\"periodInterval\")}\n          onBlur={handleCodeMirrorBlur(\"periodInterval\")}\n        />\n      </AdvancedPanelControl>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/Model/Timing/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackContext,\n} from \"@illa-public/mixpanel-utils\"\nimport { ACTION_RUN_TIME, IAdvancedConfig } from \"@illa-public/public-types\"\nimport { FC, useCallback, useContext } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Select, Switch } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport i18n from \"@/i18n/config\"\nimport { AdvancedPanelControl } from \"@/page/App/components/Actions/AdvancedPanel/Components/Control\"\nimport { AdvancedPanelHeader } from \"@/page/App/components/Actions/AdvancedPanel/Components/Header\"\nimport { getCachedActionAdvancedConfig } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getCurrentAppPageNames } from \"@/redux/currentApp/components/componentsSelector\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst RUN_TIME_OPTIONS = [\n  {\n    label: i18n.t(\"editor.action.panel.label.option.advanced.on_app_loading\"),\n    value: \"appLoaded\",\n  },\n  {\n    label: i18n.t(\"editor.action.panel.label.option.advanced.on_page_loading\"),\n    value: \"pageLoading\",\n  },\n  {\n    label: i18n.t(\"editor.action.panel.label.option.advanced.none\"),\n    value: \"none\",\n  },\n]\n\nexport const TimingSetting: FC = () => {\n  const cachedActionAdvancedConfig = useSelector(getCachedActionAdvancedConfig)\n  const pageDisplayNames = useSelector(getCurrentAppPageNames)\n  const { runtime, pages, delayWhenLoaded, displayLoadingPage } =\n    cachedActionAdvancedConfig\n\n  const dispatch = useDispatch()\n  const { track } = useContext(MixpanelTrackContext)\n  const { t } = useTranslation()\n\n  const handleUpdateAdvancedConfig = useCallback(\n    (key: keyof IAdvancedConfig) => {\n      return (value: unknown) => {\n        const updateSlice: Partial<IAdvancedConfig> = {\n          [key]: value,\n        }\n        if (key === \"runtime\") {\n          switch (value) {\n            case ACTION_RUN_TIME.APP_LOADED: {\n              updateSlice.pages = []\n              updateSlice.displayLoadingPage = false\n              break\n            }\n            case ACTION_RUN_TIME.NONE: {\n              updateSlice.pages = []\n              updateSlice.delayWhenLoaded = \"\"\n              updateSlice.displayLoadingPage = false\n              break\n            }\n            case ACTION_RUN_TIME.PAGE_LOADING: {\n              break\n            }\n          }\n        }\n\n        if (key === \"displayLoadingPage\" || key === \"isPeriodically\") {\n          track(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n            element: \"action_inspect_switch\",\n            parameter2: key,\n            parameter3: value,\n          })\n        }\n        dispatch(\n          configActions.updateCachedActionAdvancedConfigReducer(updateSlice),\n        )\n      }\n    },\n    [dispatch, track],\n  )\n\n  const handleCodeMirrorFocus = useCallback(\n    (attrName: string) => {\n      return () => {\n        track(ILLA_MIXPANEL_EVENT_TYPE.FOCUS, {\n          element: \"advanced_code_mirror\",\n          parameter2: attrName,\n        })\n      }\n    },\n    [track],\n  )\n\n  const handleCodeMirrorBlur = useCallback(\n    (attrName: string) => {\n      return (value: string) => {\n        track(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n          element: \"advanced_code_mirror\",\n          parameter2: attrName,\n          parameter3: value,\n        })\n      }\n    },\n    [track],\n  )\n\n  const handleSelectPopupVisibleChange = useCallback(\n    (visible: boolean) => {\n      if (!visible) {\n        track(ILLA_MIXPANEL_EVENT_TYPE.CHANGE, {\n          element: \"action_inspect_select\",\n          parameter2: \"pages\",\n          parameter3: pages.length,\n        })\n      }\n    },\n    [pages.length, track],\n  )\n\n  const handleOnClickSelect = useCallback(\n    (attrName: string) => {\n      return () => {\n        track(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n          element: \"action_inspect_select\",\n          parameter2: attrName,\n        })\n      }\n    },\n    [track],\n  )\n\n  return (\n    <div>\n      <AdvancedPanelHeader title=\"TIMING\" />\n      <AdvancedPanelControl\n        title={t(\"editor.action.panel.label.advanced.page_trigger\")}\n      >\n        <Select\n          colorScheme=\"techPurple\"\n          options={RUN_TIME_OPTIONS}\n          value={runtime}\n          onChange={handleUpdateAdvancedConfig(\"runtime\")}\n          onClick={handleOnClickSelect(\"runtime\")}\n        />\n      </AdvancedPanelControl>\n      <AdvancedPanelControl\n        title={t(\"editor.action.panel.label.advanced.page_load_delay\")}\n        disabled={runtime === \"none\"}\n      >\n        <CodeEditor\n          value={delayWhenLoaded}\n          onChange={handleUpdateAdvancedConfig(\"delayWhenLoaded\")}\n          expectValueType={VALIDATION_TYPES.NUMBER}\n          onFocus={handleCodeMirrorFocus(\"delayWhenLoaded\")}\n          onBlur={handleCodeMirrorBlur(\"delayWhenLoaded\")}\n        />\n      </AdvancedPanelControl>\n      <AdvancedPanelControl\n        title={t(\"editor.action.panel.label.advanced.pages\")}\n        disabled={runtime !== \"pageLoading\"}\n      >\n        <Select\n          colorScheme=\"techPurple\"\n          options={pageDisplayNames}\n          value={pages}\n          multiple\n          onChange={handleUpdateAdvancedConfig(\"pages\")}\n          placeholder={t(\n            \"editor.action.panel.label.placeholder.advanced.select_pages\",\n          )}\n          onVisibleChange={handleSelectPopupVisibleChange}\n          onClick={handleOnClickSelect(\"pages\")}\n        />\n      </AdvancedPanelControl>\n      <AdvancedPanelControl\n        title={t(\"editor.action.panel.label.advanced.loading_page\")}\n        disabled={runtime !== \"pageLoading\"}\n        subtitle={t(\n          \"editor.action.panel.label.option.advanced.show_a_loading_page_\",\n        )}\n      >\n        <Switch\n          checked={displayLoadingPage}\n          colorScheme=\"techPurple\"\n          onChange={handleUpdateAdvancedConfig(\"displayLoadingPage\")}\n        />\n      </AdvancedPanelControl>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/index.tsx",
    "content": "import { FC } from \"react\"\nimport { AdvancedPanelSpace } from \"./Components/Space\"\nimport { AdvancedOptionSetting } from \"./Model/AdvancedOption\"\nimport { TimingSetting } from \"./Model/Timing\"\nimport { advancedPanelStyle } from \"./style\"\n\nconst AdvancedPanel: FC = () => {\n  return (\n    <div css={advancedPanelStyle}>\n      <AdvancedPanelSpace />\n      <TimingSetting />\n      <AdvancedPanelSpace />\n      <AdvancedOptionSetting />\n    </div>\n  )\n}\n\nAdvancedPanel.displayName = \"ActionAdvancedPanel\"\nexport default AdvancedPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/AdvancedPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const advancedPanelStyle = css`\n  width: 100%;\n  overflow-y: auto;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/CheckboxInput/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Checkbox } from \"@illa-design/react\"\nimport { CheckboxInputProps } from \"@/page/App/components/Actions/CheckboxInput/interface\"\nimport { InputEditor } from \"@/page/App/components/Actions/InputEditor\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport {\n  checkboxItemStyle,\n  checkoutContentStyle,\n  checkoutItemStyle,\n  codeEditorLabelStyle,\n} from \"./style\"\n\nexport const CheckboxInput: FC<CheckboxInputProps> = (props) => {\n  const {\n    onCheckboxChange,\n    onValueChange,\n    checkboxTitle,\n    checkboxValue,\n    inputTitle,\n    inputValue,\n    inputPlaceholder,\n    inputTips,\n    showInputEditor = true,\n    hasExpectedType = true,\n    expectedType = VALIDATION_TYPES.STRING,\n  } = props\n  return (\n    <>\n      <div css={checkoutItemStyle}>\n        <span css={codeEditorLabelStyle}></span>\n        <div css={checkoutContentStyle}>\n          <Checkbox\n            colorScheme=\"techPurple\"\n            checked={checkboxValue}\n            ml=\"16px\"\n            onChange={onCheckboxChange}\n          />\n          <span css={checkboxItemStyle}>{checkboxTitle}</span>\n        </div>\n      </div>\n      {checkboxValue && showInputEditor && (\n        <InputEditor\n          title={inputTitle}\n          value={inputValue}\n          onChange={onValueChange}\n          hasExpectedType={hasExpectedType}\n          expectedType={expectedType}\n          tips={inputTips}\n          placeholder={inputPlaceholder}\n        />\n      )}\n    </>\n  )\n}\n\nCheckboxInput.displayName = \"CheckboxInput\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/CheckboxInput/interface.ts",
    "content": "import { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface CheckboxInputProps {\n  onCheckboxChange: (value: boolean) => void\n  onValueChange: (value: string) => void\n  checkboxTitle: string\n  checkboxValue: boolean\n  inputTitle: string\n  inputValue: string\n  showInputEditor?: boolean\n  inputPlaceholder?: string\n  inputTips?: string\n  hasExpectedType?: boolean\n  expectedType?: VALIDATION_TYPES\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/CheckboxInput/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const codeEditorLabelStyle = css`\n  min-width: 160px;\n  font-size: 14px;\n  font-weight: 500;\n  text-align: right;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  height: 30px;\n  display: flex;\n  flex-direction: row;\n  justify-content: end;\n  align-items: center;\n  align-self: start;\n`\n\nexport const checkboxItemStyle = css`\n  min-width: 160px;\n  font-size: 14px;\n  line-height: 22px;\n  font-weight: 500;\n  margin-left: 10px;\n  text-align: left;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const checkoutItemStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 30px;\n  padding: 0 16px;\n`\n\nexport const checkoutContentStyle = css`\n  min-height: 22px;\n  align-self: flex-start;\n  display: flex;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/Context/SqlModeTipContext/index.tsx",
    "content": "import { FC, ReactNode, createContext, useCallback, useState } from \"react\"\n\ntype ActionShowSQLMode = Record<string, boolean>\n\ninterface Injected {\n  showSQLModeTip: ActionShowSQLMode\n  setShowSQLModeTip: (actionID: string, show: boolean) => void\n}\n\nexport const SQLModeTipContext = createContext<Injected>({} as Injected)\nexport const SQLModeTipProvider: FC<{ children: ReactNode }> = ({\n  children,\n}) => {\n  const [showSQLModeTip, setShowSQLModeTip] = useState({})\n\n  const handleSetSQModeTip = useCallback((actionID: string, show: boolean) => {\n    setShowSQLModeTip((prev) => {\n      return {\n        ...prev,\n        [actionID]: show,\n      }\n    })\n  }, [])\n  return (\n    <SQLModeTipContext.Provider\n      value={{ showSQLModeTip, setShowSQLModeTip: handleSetSQModeTip }}\n    >\n      {children}\n    </SQLModeTipContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ControlledElement/index.tsx",
    "content": "import { FC, Fragment, useCallback } from \"react\"\nimport { Controller, RegisterOptions } from \"react-hook-form\"\nimport {\n  Checkbox,\n  Input,\n  InputNumber,\n  Password,\n  RadioGroup,\n  Select,\n  Switch,\n  TextArea,\n  getColor,\n} from \"@illa-design/react\"\nimport { ControlledElementProps, DefaultValueType } from \"./interface\"\nimport {\n  applyConfigItemContainer,\n  applyConfigItemLabelText,\n  configItemTip,\n  hostInputContainer,\n  labelContainer,\n  sslStyle,\n} from \"./style\"\n\nexport const ControlledElement: FC<ControlledElementProps> = (props) => {\n  const {\n    title,\n    contentLabel,\n    isRequired = false,\n    defaultValue,\n    placeholders = [],\n    styles = [],\n    name,\n    tips,\n    controlledType,\n    control,\n    error,\n    options = [],\n    rules = [],\n    tipsStyle,\n    allowClear = false,\n    forceEqualWidth,\n    labelStyle,\n    onValueChange,\n  } = props\n\n  const filteredType = (\n    Array.isArray(controlledType) ? controlledType : [controlledType]\n  ).filter((type) => type.trim() && type !== \"none\")\n  const names = Array.isArray(name) ? name : [name]\n  const defaultValues = Array.isArray(defaultValue)\n    ? defaultValue\n    : [defaultValue]\n  const hasTextArea = filteredType.includes(\"textarea\")\n\n  const getElementByControlledType = useCallback(\n    (\n      type: string,\n      name: string,\n      defaultValue: DefaultValueType,\n      placeholder: string,\n      rules: RegisterOptions,\n      style: Record<string, string | number> | undefined = {},\n    ) => {\n      switch (type) {\n        case \"input\":\n          return (\n            <Controller\n              control={control}\n              defaultValue={defaultValue}\n              rules={rules}\n              render={({ field: { value, onChange, onBlur } }) => (\n                <Input\n                  w=\"100%\"\n                  {...style}\n                  onBlur={onBlur}\n                  onChange={onChange}\n                  value={value}\n                  error={error}\n                  colorScheme=\"techPurple\"\n                  placeholder={placeholder}\n                />\n              )}\n              name={name}\n            />\n          )\n        case \"checkbox\":\n          return (\n            <>\n              <Controller\n                control={control}\n                defaultValue={defaultValue}\n                rules={rules}\n                render={({ field: { value, onChange, onBlur } }) => (\n                  <Checkbox\n                    {...style}\n                    onBlur={onBlur}\n                    onChange={(value) => {\n                      onChange(value)\n                      onValueChange?.(value)\n                    }}\n                    checked={value}\n                    colorScheme=\"techPurple\"\n                    placeholder={placeholder}\n                  />\n                )}\n                name={name}\n              />\n              <span css={sslStyle}>{contentLabel}</span>\n            </>\n          )\n        case \"select\":\n          return (\n            <Controller\n              control={control}\n              defaultValue={defaultValue}\n              rules={rules}\n              render={({ field: { value, onChange, onBlur } }) => (\n                <Select\n                  value={value}\n                  onBlur={onBlur}\n                  allowClear={allowClear}\n                  onChange={(value) => {\n                    onValueChange?.(value as string)\n                    onChange(value)\n                  }}\n                  colorScheme=\"techPurple\"\n                  options={options}\n                />\n              )}\n              name={name}\n            />\n          )\n        case \"switch\":\n          return (\n            <>\n              <Controller\n                control={control}\n                defaultValue={defaultValue}\n                rules={rules}\n                render={({ field: { value, onChange, onBlur } }) => (\n                  <Switch\n                    checked={value}\n                    colorScheme=\"techPurple\"\n                    onChange={(open) => {\n                      onChange(open)\n                      onValueChange?.(open)\n                    }}\n                    onBlur={onBlur}\n                    {...style}\n                  />\n                )}\n                name={name}\n              />\n              <span css={sslStyle}>{contentLabel}</span>\n            </>\n          )\n        case \"number\":\n          return (\n            <Controller\n              control={control}\n              defaultValue={defaultValue}\n              rules={rules}\n              render={({ field: { value, onChange, onBlur } }) => (\n                <InputNumber\n                  onBlur={onBlur}\n                  onChange={onChange}\n                  value={value}\n                  colorScheme=\"techPurple\"\n                  w=\"100%\"\n                  placeholder={placeholder}\n                  {...style}\n                />\n              )}\n              name={name}\n            />\n          )\n        case \"password\":\n          return (\n            <Controller\n              control={control}\n              defaultValue={defaultValue}\n              rules={rules}\n              render={({ field: { value, onChange, onBlur } }) => (\n                <Password\n                  autoComplete=\"new-password\"\n                  colorScheme=\"techPurple\"\n                  w=\"100%\"\n                  onBlur={onBlur}\n                  onChange={onChange}\n                  value={value}\n                  placeholder={placeholder}\n                  {...style}\n                />\n              )}\n              name={name}\n            />\n          )\n        case \"radio\":\n          return (\n            <Controller\n              control={control}\n              defaultValue={defaultValue}\n              rules={rules}\n              render={({ field: { value, onChange, onBlur } }) => (\n                <RadioGroup\n                  colorScheme=\"techPurple\"\n                  w=\"100%\"\n                  type=\"radio\"\n                  onBlur={onBlur}\n                  onChange={onChange}\n                  value={value}\n                  placeholder={placeholder}\n                  options={options}\n                  {...style}\n                />\n              )}\n              name={name}\n            />\n          )\n        case \"radio-group\":\n          return (\n            <Controller\n              control={control}\n              defaultValue={defaultValue}\n              rules={rules}\n              render={({ field: { value, onChange, onBlur } }) => (\n                <RadioGroup\n                  colorScheme=\"gray\"\n                  w=\"100%\"\n                  type=\"button\"\n                  onBlur={onBlur}\n                  onChange={onChange}\n                  value={value}\n                  placeholder={placeholder}\n                  forceEqualWidth={forceEqualWidth}\n                  options={options}\n                  {...style}\n                />\n              )}\n              name={name}\n            />\n          )\n        case \"textarea\":\n          return (\n            <Controller\n              control={control}\n              defaultValue={defaultValue}\n              rules={rules}\n              render={({ field: { value, onChange, onBlur } }) => (\n                <TextArea\n                  w=\"100%\"\n                  h=\"100%\"\n                  pb=\"16px\"\n                  minH=\"240px\"\n                  colorScheme=\"techPurple\"\n                  onBlur={onBlur}\n                  onChange={onChange}\n                  value={value}\n                  autoSize={false}\n                  placeholder={placeholder}\n                  {...style}\n                />\n              )}\n              name={name}\n            />\n          )\n      }\n    },\n    [\n      allowClear,\n      contentLabel,\n      control,\n      error,\n      forceEqualWidth,\n      onValueChange,\n      options,\n    ],\n  )\n\n  return (\n    <>\n      {!!filteredType.length && (\n        <div css={applyConfigItemContainer(hasTextArea)}>\n          <div css={labelStyle ? labelStyle : labelContainer}>\n            {isRequired && (\n              <span css={applyConfigItemLabelText(getColor(\"red\", \"03\"))}>\n                *\n              </span>\n            )}\n            <span css={applyConfigItemLabelText(getColor(\"grayBlue\", \"02\"))}>\n              {title}\n            </span>\n          </div>\n          <div css={hostInputContainer}>\n            {filteredType.map((type, index) => (\n              <Fragment key={index}>\n                {getElementByControlledType(\n                  type,\n                  names[index],\n                  defaultValues[index],\n                  placeholders[index],\n                  rules[index],\n                  styles[index],\n                )}\n              </Fragment>\n            ))}\n          </div>\n        </div>\n      )}\n      {tips && <div css={tipsStyle ? tipsStyle : configItemTip}>{tips}</div>}\n    </>\n  )\n}\n\nControlledElement.displayName = \"ControlledElement\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ControlledElement/interface.ts",
    "content": "import { SerializedStyles } from \"@emotion/react\"\nimport { ReactNode } from \"react\"\nimport { Control, RegisterOptions } from \"react-hook-form\"\nimport { SelectOptionObject } from \"@illa-design/react\"\n\nexport type ControlledType =\n  | \"checkbox\"\n  | \"input\"\n  | \"number\"\n  | \"switch\"\n  | \"password\"\n  | \"textarea\"\n  | \"select\"\n  | \"radio-group\"\n  | \"radio\"\n  | \"none\"\n\nexport type DefaultValueType = string | boolean | number\n\nexport interface ControlledElementProps {\n  title: ReactNode\n  isRequired?: boolean\n  defaultValue: DefaultValueType | DefaultValueType[]\n  placeholders?: string[]\n  contentLabel?: string\n  name: string | string[]\n  styles?: Record<string, string | number>[]\n  tips?: string | ReactNode\n  error?: boolean\n  labelStyle?: SerializedStyles\n  tipsStyle?: SerializedStyles\n  controlledType: ControlledType | ControlledType[]\n  options?: string[] | number[] | SelectOptionObject[]\n  control: Control\n  allowClear?: boolean\n  rules?: RegisterOptions[]\n  onValueChange?: (value: DefaultValueType) => void\n  forceEqualWidth?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ControlledElement/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport function applyConfigItemContainer(hasTextarea: boolean) {\n  if (hasTextarea) {\n    return css`\n      display: flex;\n      width: 100%;\n      flex-direction: row;\n      padding-left: 24px;\n    `\n  } else {\n    return css`\n      display: flex;\n      min-height: 48px;\n      align-items: center;\n      flex-direction: row;\n      padding-left: 24px;\n    `\n  }\n}\n\nexport const sslStyle = css`\n  font-size: 14px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  margin-left: 8px;\n`\n\nexport const configItemTip = css`\n  font-size: 14px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-weight: 400;\n  margin-left: 192px;\n  padding: 0 24px 8px 24px;\n  line-height: 22px;\n  min-height: 30px;\n  white-space: normal;\n`\n\nexport const labelContainer = css`\n  display: flex;\n  flex-direction: row;\n  justify-content: end;\n  min-width: 176px;\n  width: 176px;\n`\n\nexport function applyConfigItemLabelText(\n  color: string,\n  margin?: boolean,\n): SerializedStyles {\n  let marginLeft = css``\n  if (margin) {\n    marginLeft = css`\n      margin-left: 4px;\n    `\n  }\n  return css`\n    font-size: 14px;\n    color: ${color};\n    font-weight: 500;\n    ${marginLeft};\n  `\n}\n\nexport const hostInputContainer = css`\n  display: flex;\n  margin-left: 16px;\n  margin-right: 24px;\n  flex-direction: row;\n  width: 100%;\n  align-items: center;\n  gap: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/DragBar/index.tsx",
    "content": "import React, { FC, RefObject, useEffect, useState } from \"react\"\nimport { isNumber } from \"@illa-design/react\"\nimport { DragBarProps } from \"./interface\"\nimport { actionEditorDragBarStyle } from \"./style\"\n\nconst handleResize = (\n  resizeRef: RefObject<HTMLDivElement>,\n  movementY: number,\n  minHeight: number,\n  getMaxHeight?: () => number | undefined,\n  placeholderRef?: RefObject<HTMLDivElement>,\n  callback?: () => void,\n) => {\n  const resize = resizeRef?.current\n  const placeholder = placeholderRef?.current\n  if (!resize) return\n\n  const { height } = resize.getBoundingClientRect()\n  const updatedHeight = height - movementY\n\n  if (getMaxHeight) {\n    const maxHeight = getMaxHeight()\n    if (isNumber(maxHeight) && updatedHeight > maxHeight) return\n  }\n\n  if (updatedHeight < window.innerHeight && updatedHeight > minHeight) {\n    resize.style.height = `${updatedHeight}px`\n    if (placeholder) {\n      placeholder.style.paddingBottom = `${updatedHeight + 48}px`\n    }\n    callback?.()\n  }\n}\n\nexport const DragBar: FC<DragBarProps> = (props) => {\n  const {\n    resizeRef,\n    placeholderRef,\n    minHeight = 300,\n    getMaxHeight,\n    onChange,\n  } = props\n  const [mouseDown, setMouseDown] = useState(false)\n\n  useEffect(() => {\n    const handleMouseMove = (e: MouseEvent) => {\n      e.preventDefault()\n      handleResize(\n        resizeRef,\n        e.movementY,\n        minHeight,\n        getMaxHeight,\n        placeholderRef,\n        () => {\n          onChange?.()\n        },\n      )\n    }\n    if (mouseDown) {\n      window.addEventListener(\"mousemove\", handleMouseMove)\n    }\n\n    return () => {\n      window.removeEventListener(\"mousemove\", handleMouseMove)\n    }\n  }, [getMaxHeight, minHeight, mouseDown, onChange, placeholderRef, resizeRef])\n\n  useEffect(() => {\n    const handleMouseUp = () => setMouseDown(false)\n    window.addEventListener(\"mouseup\", handleMouseUp)\n\n    return () => {\n      window.removeEventListener(\"mouseup\", handleMouseUp)\n    }\n  }, [getMaxHeight, minHeight])\n\n  return (\n    <div\n      css={actionEditorDragBarStyle}\n      onMouseDown={() => {\n        setMouseDown(true)\n      }}\n    />\n  )\n}\n\nDragBar.displayName = \"DragBar\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/DragBar/interface.ts",
    "content": "import { HTMLAttributes, RefObject } from \"react\"\n\nexport interface DragBarProps extends HTMLAttributes<HTMLDivElement> {\n  resizeRef: RefObject<HTMLDivElement>\n  placeholderRef?: RefObject<HTMLDivElement>\n  minHeight?: number\n  getMaxHeight?: () => number | undefined\n  setContainerDimensions?: (height: number) => void\n  onChange?: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/DragBar/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const actionEditorDragBarStyle = css`\n  top: -5px;\n  cursor: row-resize;\n  width: 100%;\n  position: absolute;\n  transition: all 0.2s;\n  height: 5px;\n  z-index: 10;\n\n  &:hover {\n    background: ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/InputEditor/index.tsx",
    "content": "import { FC, useMemo } from \"react\"\nimport { Popover } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport { CODE_LANG } from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { ControlledInputProps } from \"@/page/App/components/Actions/InputEditor/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport SQLModeTip from \"../ActionPanel/pulicComponent/SQLModeTip\"\nimport {\n  actionItemCodeEditorStyle,\n  actionItemStyle,\n  actionItemTip,\n  codeEditorLabelStyle,\n  codeEditorSublabelStyle,\n  sqlModeTipStyle,\n} from \"./style\"\n\nexport const InputEditor: FC<ControlledInputProps> = (props) => {\n  const {\n    title,\n    onChange,\n    expectedType = VALIDATION_TYPES.STRING,\n    value,\n    tips,\n    showSafeModeTips,\n    subtitle,\n    handleSubtitleClick,\n    placeholder,\n    style = {},\n    mode = CODE_LANG.JAVASCRIPT,\n    lineNumbers = false,\n    sqlScheme,\n    canShowCompleteInfo,\n    popoverContent,\n    codeType,\n    hasExpectedType = true,\n  } = props\n\n  const titleNode = useMemo(\n    () => (\n      <span css={codeEditorLabelStyle}>\n        <span>{title}</span>\n        {subtitle && (\n          <span css={codeEditorSublabelStyle} onClick={handleSubtitleClick}>\n            {subtitle}\n          </span>\n        )}\n      </span>\n    ),\n    [handleSubtitleClick, subtitle, title],\n  )\n\n  return (\n    <div style={{ width: \"100%\" }}>\n      <div css={actionItemStyle}>\n        {title && (\n          <>\n            {popoverContent ? (\n              <Popover\n                content={popoverContent}\n                hasCloseIcon={false}\n                trigger=\"hover\"\n                colorScheme=\"gray\"\n                showArrow={false}\n              >\n                {titleNode}\n              </Popover>\n            ) : (\n              <>{titleNode}</>\n            )}\n          </>\n        )}\n        <CodeEditor\n          {...style}\n          singleLine={!lineNumbers}\n          showLineNumbers={lineNumbers}\n          wrapperCss={actionItemCodeEditorStyle}\n          lang={mode}\n          value={value}\n          sqlScheme={sqlScheme}\n          onChange={onChange}\n          expectValueType={hasExpectedType ? expectedType : undefined}\n          placeholder={placeholder}\n          modalTitle={title}\n          codeType={codeType}\n          canShowCompleteInfo={canShowCompleteInfo}\n        />\n      </div>\n      {tips && (\n        <div css={actionItemTip}>\n          <span>{tips}</span>\n        </div>\n      )}\n      {showSafeModeTips && (\n        <SQLModeTip value={value} _css={sqlModeTipStyle(!!title)} />\n      )}\n    </div>\n  )\n}\n\nInputEditor.displayName = \"InputEditor\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/InputEditor/interface.ts",
    "content": "import { ReactNode } from \"react\"\nimport {\n  CODE_LANG,\n  ICodeMirrorOptions,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface ControlledInputProps\n  extends Pick<\n    ICodeMirrorOptions,\n    \"sqlScheme\" | \"canShowCompleteInfo\" | \"codeType\"\n  > {\n  title?: string\n  subtitle?: string\n  handleSubtitleClick?: () => void\n  value: string\n  onChange: (value: string) => void\n  expectedType?: VALIDATION_TYPES\n  placeholder?: string\n  tips?: string | ReactNode\n  showSafeModeTips?: boolean\n  lineNumbers?: boolean\n  mode?: CODE_LANG\n  hasExpectedType?: boolean\n  popoverContent?: string\n  style?: {\n    height?: string\n    minHeight?: string\n    maxHeight?: string\n    width?: string\n    mixWidth?: string\n    maxWidth?: string\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/InputEditor/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const actionItemStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 48px;\n  padding: 0 16px;\n`\n\nexport const actionItemCodeEditorStyle = css`\n  margin-top: 8px;\n  margin-bottom: 8px;\n  margin-left: 16px;\n  flex-grow: 1;\n  width: 0;\n`\n\nexport const codeEditorLabelStyle = css`\n  min-width: 160px;\n  width: 160px;\n  line-height: 22px;\n  font-size: 14px;\n  font-weight: 500;\n  text-align: right;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  min-height: 48px;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: flex-end;\n  align-self: center;\n`\n\nexport const codeEditorSublabelStyle = css`\n  color: ${getColor(\"techPurple\", \"03\")};\n  cursor: pointer;\n  height: 20px;\n  line-height: 20px;\n  font-size: 12px;\n`\n\nexport const actionItemTip = css`\n  font-size: 14px;\n  margin-left: 192px;\n  white-space: pre-line;\n  min-height: 30px;\n  padding-bottom: 8px;\n  display: flex;\n  align-items: stretch;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n\nexport const sqlModeTipStyle = (hasTitle: boolean) => css`\n  margin-left: ${hasTitle ? \"192px\" : \"32px\"};\n  margin-top: 0;\n  margin-right: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/InputRecordEditor/index.tsx",
    "content": "import { FC, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  AddIcon,\n  Button,\n  DeleteIcon,\n  Input,\n  globalColor,\n  illaPrefix,\n} from \"@illa-design/react\"\nimport { InputRecordEditorProps } from \"./interface\"\nimport {\n  applyRecordEditorContainerStyle,\n  recordEditorLabelStyle,\n  recordEditorStyle,\n  recordStyle,\n} from \"./style\"\n\nexport const InputRecordEditor: FC<InputRecordEditorProps> = (props) => {\n  const {\n    records,\n    label,\n    onDelete,\n    onAdd,\n    onChangeKey,\n    onChangeValue,\n    customRender,\n  } = props\n\n  const { t } = useTranslation()\n\n  const recordList = useMemo(() => {\n    return (\n      <>\n        {records?.map((record, index) => {\n          if (customRender) {\n            return (\n              <div css={recordStyle} key={index}>\n                {customRender(record, index)}\n                <Button\n                  ml=\"-1px\"\n                  variant=\"outline\"\n                  minW=\"32px\"\n                  bdRadius=\"0 8px 8px 0\"\n                  colorScheme=\"grayBlue\"\n                  onClick={() => {\n                    onDelete(index, record)\n                  }}\n                  leftIcon={<DeleteIcon />}\n                />\n              </div>\n            )\n          }\n          return (\n            <div css={recordStyle} key={index}>\n              <Input\n                w=\"100%\"\n                colorScheme=\"techPurple\"\n                value={record.key}\n                placeholder=\"key\"\n                bdRadius=\"8px 0 0 8px\"\n                onChange={(value) => {\n                  onChangeKey(index, value, record.value)\n                }}\n              />\n              <Input\n                w=\"100%\"\n                colorScheme=\"techPurple\"\n                placeholder=\"value\"\n                value={record.value}\n                ml=\"-1px\"\n                bdRadius=\"0\"\n                onChange={(value) => {\n                  onChangeValue(index, record.key, value)\n                }}\n              />\n              <Button\n                ml=\"-1px\"\n                type=\"button\"\n                variant=\"outline\"\n                minW=\"32px\"\n                bdRadius=\"0 8px 8px 0\"\n                colorScheme=\"grayBlue\"\n                onClick={() => {\n                  onDelete(index, record)\n                }}\n                leftIcon={<DeleteIcon />}\n              />\n            </div>\n          )\n        })}\n      </>\n    )\n  }, [customRender, onChangeKey, onChangeValue, onDelete, records])\n\n  return (\n    <div css={applyRecordEditorContainerStyle(label)}>\n      {label != \"\" && <span css={recordEditorLabelStyle}>{label}</span>}\n      <div css={recordEditorStyle}>\n        {recordList}\n        <span>\n          <Button\n            type=\"button\"\n            mb=\"8px\"\n            pd=\"1px 8px\"\n            colorScheme=\"techPurple\"\n            size=\"medium\"\n            variant=\"text\"\n            onClick={onAdd}\n            leftIcon={\n              <AddIcon color={globalColor(`--${illaPrefix}-techPurple-03`)} />\n            }\n          >\n            {t(\"editor.action.panel.btn.new\")}\n          </Button>\n        </span>\n      </div>\n    </div>\n  )\n}\n\nInputRecordEditor.displayName = \"InputRecordEditor\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/InputRecordEditor/interface.ts",
    "content": "import { Params } from \"@illa-public/public-types\"\nimport { ReactNode } from \"react\"\n\nexport interface InputRecordEditorProps {\n  label: string\n  records: Params[]\n  onAdd: () => void\n  customRender?: (record: Params, index: number) => ReactNode\n  onDelete: (index: number, record: Params) => void\n  onChangeKey: (index: number, key: string, value: string) => void\n  onChangeValue: (index: number, key: string, value: string) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/InputRecordEditor/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport function applyRecordEditorContainerStyle(label: string) {\n  return css`\n    display: flex;\n    padding-right: ${label !== \"\" ? \"24px\" : \"0\"};\n    flex-direction: row;\n    padding-left: 24px;\n  `\n}\nexport const recordEditorStyle = css`\n  display: flex;\n  flex-grow: 1;\n  flex-direction: column;\n`\n\nexport const recordStyle = css`\n  display: inline-flex;\n  flex-direction: row;\n  align-items: center;\n  min-height: 48px;\n  & > button {\n    color: ${globalColor(`--${illaPrefix}-grayBlue-05`)};\n    :hover {\n      color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n      transition: color 200ms ease-in-out;\n    }\n  }\n`\n\nexport const recordEditorLabelStyle = css`\n  min-width: 160px;\n  margin-left: 16px;\n  margin-right: 16px;\n  height: 48px;\n  display: flex;\n  flex-direction: row;\n  justify-content: end;\n  align-items: center;\n  font-size: 14px;\n  font-weight: 500;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ResourceDivider/index.tsx",
    "content": "import { TFunction } from \"i18next\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Divider } from \"@illa-design/react\"\nimport {\n  ResourceDividerProps,\n  ResourceDividerType,\n} from \"@/page/App/components/Actions/ResourceDivider/interface\"\nimport { optionLabelStyle } from \"./style\"\n\nconst getDividerContent = (type: ResourceDividerType, t: TFunction) => {\n  switch (type) {\n    case \"Service Account\":\n      return t(\"editor.action.form.group.gs.service_account\")\n    case \"General Option\":\n      return t(\"editor.action.resource.db.title.general_option\")\n    case \"Advanced Option\":\n      return t(\"editor.action.resource.db.title.advanced_option\")\n    default:\n      return t(\"editor.action.resource.db.title.general_option\")\n  }\n}\n\nexport const ResourceDivider: FC<ResourceDividerProps> = (props) => {\n  const { type } = props\n  const { t } = useTranslation()\n  const content = getDividerContent(type, t)\n\n  return (\n    <>\n      <Divider\n        direction=\"horizontal\"\n        ml=\"24px\"\n        mr=\"24px\"\n        mt=\"8px\"\n        mb=\"8px\"\n        w=\"unset\"\n      />\n      <div css={optionLabelStyle}>{content}</div>\n    </>\n  )\n}\nResourceDivider.displayName = \"ResourceDivider\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ResourceDivider/interface.ts",
    "content": "export type ResourceDividerType =\n  | \"Service Account\"\n  | \"General Option\"\n  | \"Advanced Option\"\n\nexport interface ResourceDividerProps {\n  type: ResourceDividerType\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/ResourceDivider/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const optionLabelStyle = css`\n  height: 38px;\n  display: flex;\n  font-size: 14px;\n  font-weight: 500;\n  padding: 8px 24px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/SearchHeader/index.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { Dispatch, FC, SetStateAction, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button, Input, SearchIcon } from \"@illa-design/react\"\nimport { SearchHeaderProps } from \"./interface\"\nimport {\n  actionListHeaderContainerStyle,\n  actionTitleStyle,\n  searchHeaderStyle,\n  searchInputContainerStyle,\n  searchInputIconStyle,\n  searchInputStyle,\n} from \"./style\"\n\ninterface SearchInputProps {\n  onSearch: (value: string) => void\n  setInSearchState: Dispatch<SetStateAction<boolean>>\n}\n\nconst SearchInput: FC<SearchInputProps> = (props) => {\n  const { t } = useTranslation()\n  const { onSearch, setInSearchState } = props\n\n  return (\n    <div css={css(searchHeaderStyle, searchInputContainerStyle)}>\n      <motion.div\n        initial={{ width: 0, opacity: 0 }}\n        animate={{ width: \"100%\", opacity: 1 }}\n        exit={{ width: 0, opacity: 0 }}\n        transition={{ duration: 0.2 }}\n      >\n        <Input\n          colorScheme=\"techPurple\"\n          prefix={<SearchIcon size={\"12px\"} css={searchInputIconStyle} />}\n          placeholder={t(\"editor.action.action_list.placeholder.search\")}\n          onChange={onSearch}\n          onClear={() => onSearch(\"\")}\n          css={searchInputStyle}\n          allowClear\n        />\n      </motion.div>\n\n      <motion.div\n        initial={{ opacity: 0 }}\n        animate={{ opacity: 1 }}\n        exit={{ opacity: 0 }}\n        transition={{ duration: 0.2 }}\n      >\n        <Button\n          onClick={() => {\n            setInSearchState(false)\n            onSearch(\"\")\n          }}\n          variant=\"text\"\n          colorScheme={\"white\"}\n          size=\"small\"\n        >\n          {t(\"editor.action.action_list.btn.close\")}\n        </Button>\n      </motion.div>\n    </div>\n  )\n}\n\nexport const SearchHeader: FC<SearchHeaderProps> = (props) => {\n  const { onSearch } = props\n  const [inSearchState, setInSearchState] = useState(false)\n\n  const { t } = useTranslation()\n  return (\n    <AnimatePresence>\n      {inSearchState ? (\n        <SearchInput setInSearchState={setInSearchState} onSearch={onSearch} />\n      ) : (\n        <div css={actionListHeaderContainerStyle}>\n          <h3 css={actionTitleStyle}>{t(\"editor.action.action_list.title\")}</h3>\n          <IconHotSpot iconSize={12} onClick={() => setInSearchState(true)}>\n            <SearchIcon />\n          </IconHotSpot>\n        </div>\n      )}\n    </AnimatePresence>\n  )\n}\n\nSearchHeader.displayName = \"SearchHeader\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/SearchHeader/interface.tsx",
    "content": "export interface SearchHeaderProps {\n  onSearch: (value: string) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/SearchHeader/style.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport chroma from \"chroma-js\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const searchHeaderStyle = css`\n  width: 100%;\n  height: 48px;\n  display: flex;\n  flex-direction: row;\n  padding: 0 16px;\n  align-items: center;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const searchInputContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  justify-content: flex-end;\n`\n\nexport const searchHeaderTitleTextStyle = css`\n  white-space: nowrap;\n  font-size: 14px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  flex: 1;\n`\n\nexport const searchInputStyle = css`\n  margin-right: 8px;\n\n  & > span {\n    border-radius: 8px !important;\n    border-color: ${globalColor(`--${illaPrefix}-techPurple-03`)} !important;\n    box-shadow: 0 0 8px 0\n      ${chroma(globalColor(`--${illaPrefix}-techPurple-03`))\n        .alpha(0.2)\n        .hex()};\n  }\n`\n\nexport const searchInputIconStyle = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-05`)};\n`\n\nexport const actionListHeaderContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 12px 16px;\n`\n\nexport const actionTitleStyle = css`\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  margin: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/api.ts",
    "content": "import { isILLAAPiError } from \"@illa-public/illa-net\"\nimport {\n  ActionContent,\n  ActionItem,\n  GlobalDataActionContent,\n} from \"@illa-public/public-types\"\nimport { v4 } from \"uuid\"\nimport { createMessage, omit } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { getIsILLAGuideMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { fetchCreateAction, fetchDeleteAction } from \"@/services/action\"\nimport store from \"@/store\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\n\nconst message = createMessage()\n\nexport async function onCopyActionItem(action: ActionItem<ActionContent>) {\n  const isGuideMode = getIsILLAGuideMode(store.getState())\n  const newAction = omit(action, [\"displayName\", \"actionID\"])\n  const displayName = DisplayNameGenerator.generateDisplayName(\n    action.actionType === \"globalData\" ? \"state\" : action.actionType,\n  )\n  const data: Omit<ActionItem<ActionContent>, \"actionID\"> = {\n    ...newAction,\n    displayName,\n  }\n  if (action.actionType === \"globalData\") {\n    store.dispatch(\n      componentsActions.setGlobalStateReducer({\n        key: data.displayName,\n        value: (data.content as GlobalDataActionContent).initialValue,\n        oldKey: \"\",\n      }),\n    )\n    return\n  }\n  if (isGuideMode) {\n    const createActionData: ActionItem<ActionContent> = {\n      ...data,\n      actionID: v4(),\n    }\n    store.dispatch(actionActions.addActionItemReducer(createActionData))\n    message.success({\n      content: i18n.t(\"editor.action.action_list.message.success_created\"),\n    })\n    return\n  }\n  try {\n    const response = await fetchCreateAction(data)\n    message.success({\n      content: i18n.t(\"editor.action.action_list.message.success_created\"),\n    })\n    store.dispatch(actionActions.addActionItemReducer(response.data))\n  } catch (e) {\n    if (isILLAAPiError(e)) {\n      message.error({\n        content: i18n.t(\"editor.action.action_list.message.failed\"),\n      })\n      DisplayNameGenerator.removeDisplayName(displayName)\n    } else {\n      DisplayNameGenerator.removeDisplayName(displayName)\n    }\n  }\n}\n\nexport async function onDeleteActionItem(action: ActionItem<ActionContent>) {\n  const isGuideMode = getIsILLAGuideMode(store.getState())\n  const { actionID, displayName } = action\n  if (isGuideMode) {\n    store.dispatch(configActions.resetSelectedActionReducer(displayName))\n\n    store.dispatch(\n      actionActions.removeActionItemReducer({\n        actionID: actionID,\n        displayName,\n      }),\n    )\n    message.success({\n      content: i18n.t(\"editor.action.action_list.message.success_deleted\"),\n    })\n    return\n  }\n  try {\n    await fetchDeleteAction(actionID)\n    store.dispatch(configActions.resetSelectedActionReducer(displayName))\n\n    store.dispatch(\n      actionActions.removeActionItemReducer({\n        actionID: actionID,\n        displayName,\n      }),\n    )\n    message.success({\n      content: i18n.t(\"editor.action.action_list.message.success_deleted\"),\n    })\n  } catch (e) {\n    if (isILLAAPiError(e)) {\n      message.error({\n        content: i18n.t(\"editor.action.action_list.message.failed\"),\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/getIcon.tsx",
    "content": "import { Agent } from \"@illa-public/public-types\"\nimport { agentActionStyle } from \"../../Module/ActionEditor/styles\"\n\nexport function getAgentIcon(agent: Agent, size: string) {\n  return <img src={agent?.icon} css={agentActionStyle(size)} />\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Actions/hook.ts",
    "content": "import {\n  INIT_ACTION_ADVANCED_CONFIG,\n  INIT_ACTION_MOCK_CONFIG,\n  actionItemInitial,\n  getInitialAgentContent,\n  getInitialContent,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionContent,\n  ActionItem,\n  ActionType,\n  Agent,\n  AiAgentActionContent,\n} from \"@illa-public/public-types\"\nimport { HandleCreateAgentActionFunc } from \"@illa-public/resource-generator/components/ActionGenerator/AIAgentSelector/interface\"\nimport { HandleDirectCreateActionFunc } from \"@illa-public/resource-generator/components/ActionGenerator/ActionResourceSelector/interface\"\nimport { useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { v4 } from \"uuid\"\nimport { useMessage } from \"@illa-design/react\"\nimport { aiAgentActions } from \"@/redux/aiAgent/dashboardTeamAIAgentSlice\"\nimport { getIsILLAGuideMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { fetchCreateAction } from \"@/services/action\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\n\nexport const useCreateAction = (): [\n  HandleDirectCreateActionFunc,\n  HandleCreateAgentActionFunc,\n] => {\n  const isGuideMode = useSelector(getIsILLAGuideMode)\n  const dispatch = useDispatch()\n  const message = useMessage()\n  const { t } = useTranslation()\n\n  const handleDirectCreateAction = useCallback(\n    async (\n      currentActionType: ActionType,\n      resourceID: string,\n      successCallback?: () => void,\n      loadingCallback?: (loading: boolean) => void,\n    ) => {\n      if (currentActionType == null) {\n        return\n      }\n      const displayName =\n        DisplayNameGenerator.generateDisplayName(currentActionType)\n      const initialContent = getInitialContent(currentActionType)\n      const data: Omit<ActionItem<ActionContent>, \"actionID\"> = {\n        actionType: currentActionType,\n        displayName,\n        resourceID,\n        content: initialContent,\n        isVirtualResource: false,\n        ...actionItemInitial,\n        config: {\n          public: false,\n          advancedConfig: INIT_ACTION_ADVANCED_CONFIG,\n          mockConfig: INIT_ACTION_MOCK_CONFIG,\n        },\n      }\n      if (isGuideMode) {\n        const createActionData: ActionItem<ActionContent> = {\n          ...data,\n          actionID: v4(),\n        }\n        dispatch(actionActions.addActionItemReducer(createActionData))\n        dispatch(configActions.changeSelectedAction(createActionData))\n        successCallback?.()\n        return\n      }\n      loadingCallback?.(true)\n      try {\n        const { data: responseData } = await fetchCreateAction(data)\n        message.success({\n          content: t(\"editor.action.action_list.message.success_created\"),\n        })\n        dispatch(actionActions.addActionItemReducer(responseData))\n        dispatch(configActions.changeSelectedAction(responseData))\n        successCallback?.()\n      } catch (_e) {\n        message.error({\n          content: t(\"editor.action.action_list.message.failed\"),\n        })\n        DisplayNameGenerator.removeDisplayName(displayName)\n      }\n      loadingCallback?.(false)\n    },\n    [dispatch, message, t, isGuideMode],\n  )\n\n  const handleCreateAgentAction = useCallback(\n    async (\n      item: Agent,\n      successCallback?: () => void,\n      loadingCallback?: (loading: boolean) => void,\n    ) => {\n      dispatch(\n        aiAgentActions.addTeamAIAgentReducer({\n          aiAgent: item,\n        }),\n      )\n      const displayName = DisplayNameGenerator.generateDisplayName(\"aiagent\")\n      const initalAgentContent = getInitialAgentContent(item)\n      const data: Omit<ActionItem<AiAgentActionContent>, \"actionID\"> = {\n        actionType: \"aiagent\",\n        displayName,\n        resourceID: item.aiAgentID,\n        content: {\n          ...initalAgentContent,\n          virtualResource: item,\n        },\n        isVirtualResource: true,\n        ...actionItemInitial,\n        config: {\n          public: false,\n          advancedConfig: INIT_ACTION_ADVANCED_CONFIG,\n          mockConfig: INIT_ACTION_MOCK_CONFIG,\n          icon: item.icon,\n        },\n      }\n      if (isGuideMode) {\n        const createActionData: ActionItem<ActionContent> = {\n          ...data,\n          actionID: v4(),\n        }\n        dispatch(actionActions.addActionItemReducer(createActionData))\n        dispatch(configActions.changeSelectedAction(createActionData))\n        successCallback?.()\n        return\n      }\n      loadingCallback?.(true)\n      try {\n        const { data: responseData } = await fetchCreateAction(data)\n        message.success({\n          content: t(\"editor.action.action_list.message.success_created\"),\n        })\n        dispatch(actionActions.addActionItemReducer(responseData))\n        dispatch(configActions.changeSelectedAction(responseData))\n        successCallback?.()\n      } catch (_e) {\n        message.error({\n          content: t(\"editor.action.action_list.message.failed\"),\n        })\n        DisplayNameGenerator.removeDisplayName(displayName)\n      }\n      loadingCallback?.(false)\n    },\n    [dispatch, isGuideMode, message, t],\n  )\n\n  return [handleDirectCreateAction, handleCreateAgentAction]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/AppLoading/index.tsx",
    "content": "import { FC, HTMLAttributes, useState } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { contentStyle, loadingStyle } from \"@/page/App/style\"\nimport {\n  containerStyle,\n  leftAnimationStyle,\n  navStyle,\n  rightAnimationStyle,\n} from \"./style\"\n\nexport const AppLoading: FC<HTMLAttributes<HTMLDivElement>> = () => {\n  const [showLoading, setShowLoading] = useState<boolean>()\n\n  return (\n    <div css={containerStyle}>\n      <div css={navStyle} />\n      <div css={contentStyle}>\n        <div\n          css={leftAnimationStyle}\n          onAnimationEnd={() => {\n            setShowLoading(true)\n          }}\n        />\n        <div css={loadingStyle}>\n          {showLoading ? <Loading colorScheme=\"techPurple\" /> : null}\n        </div>\n        <div css={rightAnimationStyle} />\n      </div>\n    </div>\n  )\n}\n\nAppLoading.displayName = \"AppLoading\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/AppLoading/style.ts",
    "content": "import { css, keyframes } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\nimport { leftPanelStyle, navbarStyle, rightPanelStyle } from \"@/page/App/style\"\nimport { LEFT_PANEL_WIDTH, NAVBAR_HEIGHT, RIGHT_PANEL_WIDTH } from \"@/style\"\n\nconst enlargeNavBar = keyframes`\n  0% {\n    transform: translate3d(0, -${NAVBAR_HEIGHT}px, 0);\n  }\n  100% {\n    transform: translate3d(0, 0, 0);\n  }\n`\n\nconst enlargeLeftPanel = keyframes`\n  0% {\n    transform: translate3d(-${LEFT_PANEL_WIDTH}px, 0, 0);\n  }\n  100% {\n    transform: translate3d(0, 0, 0);\n  }\n`\n\nconst enlargeRightPanel = keyframes`\n  0% {\n    transform: translate3d(${RIGHT_PANEL_WIDTH}px, 0, 0);\n  }\n  100% {\n    transform: translate3d(0, 0, 0);\n  }\n`\n\nexport const leftAnimationStyle = css`\n  ${leftPanelStyle};\n  transform: translate3d(-${LEFT_PANEL_WIDTH}px, 0, 0);\n  animation: ${enlargeLeftPanel} 300ms ease-in-out 200ms forwards;\n`\nexport const rightAnimationStyle = css`\n  ${rightPanelStyle};\n  transform: translate3d(${RIGHT_PANEL_WIDTH}px, 0, 0);\n  animation: ${enlargeRightPanel} 300ms ease-in-out 200ms forwards;\n`\n\nexport const navStyle = css`\n  ${navbarStyle};\n  background: ${globalColor(`--${illaPrefix}-white-01`)};\n  animation: ${enlargeNavBar} 300ms ease-in-out;\n  border-bottom: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n`\n\nexport const containerStyle = css`\n  background: #fafafb;\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  height: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Avatar/index.tsx",
    "content": "import { HTTP_REQUEST_PUBLIC_BASE_URL } from \"@illa-public/illa-net/constant\"\nimport { getColorByString } from \"@illa-public/utils\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { FC } from \"react\"\nimport { Popover } from \"@illa-design/react\"\nimport { AvatarProps } from \"@/page/App/components/Avatar/interface\"\nimport {\n  applyUserAvatarStyle,\n  getAvatarStyle,\n} from \"@/page/App/components/Avatar/style\"\n\nconst getFirstChar = (str: string | undefined) => {\n  if (!str) return \"U\"\n  const trimStr = str.trim()\n  const regex = /^./u\n  const match = trimStr.match(regex)\n  return match ? match[0].toUpperCase() : \"U\"\n}\n\nexport const Avatar: FC<AvatarProps> = (props) => {\n  const { userID, nickname, avatar, showType, type, showTooltips, className } =\n    props\n  const avatarBgColor = getColorByString(userID || \"\")\n  const avatarText = getFirstChar(nickname)\n  const node = avatar ? (\n    <img\n      src={\n        avatar\n          ? isCloudVersion\n            ? avatar\n            : `${HTTP_REQUEST_PUBLIC_BASE_URL}${avatar}`\n          : undefined\n      }\n      css={getAvatarStyle(showType, type)}\n      className={className}\n    />\n  ) : (\n    <span\n      css={applyUserAvatarStyle(avatarBgColor, showType, type)}\n      className={className}\n    >\n      {avatarText}\n    </span>\n  )\n  return (\n    <Popover\n      trigger=\"hover\"\n      content={nickname}\n      disabled={!showTooltips}\n      hasCloseIcon={false}\n      position=\"top\"\n      colorScheme=\"grayBlue\"\n    >\n      {node}\n    </Popover>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Avatar/interface.ts",
    "content": "import { HTMLAttributes } from \"react\"\n\nexport interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {\n  userID?: string\n  nickname?: string\n  avatar?: string\n  // component or app\n  showType?: string\n  type?: string\n  showTooltips?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Avatar/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport function applyUserAvatarStyle(\n  background: string,\n  showType?: string,\n  type?: string,\n): SerializedStyles {\n  const basicStyle = css`\n    display: inline-block;\n    background: ${background};\n    text-align: center;\n    border-radius: 50%;\n    cursor: pointer;\n    flex-shrink: 0;\n    color: ${globalColor(`--${illaPrefix}-white-01`)};\n  `\n  if (showType === \"components\") {\n    if (type === \"list\") {\n      return css`\n        ${basicStyle};\n        width: 24px;\n        height: 24px;\n        line-height: 24px;\n      `\n    }\n    return css`\n      ${basicStyle};\n      width: 14px;\n      height: 14px;\n      line-height: 14px;\n      font-weight: 500;\n    `\n  }\n\n  return css`\n    ${basicStyle};\n    width: 32px;\n    height: 32px;\n    line-height: 32px;\n  `\n}\n\nexport const getAvatarStyle = (showType?: string, type?: string) => {\n  const basicStyle = css`\n    text-align: center;\n    border-radius: 50%;\n    display: inline-block;\n    cursor: pointer;\n    flex-shrink: 0;\n  `\n  if (showType === \"components\") {\n    if (type === \"list\") {\n      return css`\n        ${basicStyle};\n        width: 24px;\n        height: 24px;\n        line-height: 24px;\n      `\n    }\n    return css`\n      ${basicStyle};\n      width: 14px;\n      height: 14px;\n      line-height: 14px;\n    `\n  }\n\n  return css`\n    ${basicStyle};\n    width: 32px;\n    height: 32px;\n    line-height: 32px;\n  `\n}\n\nexport const triggerStyle = css`\n  z-index: 10;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ComponentPanel/ComponentItem.tsx",
    "content": "import { UpgradeIcon } from \"@illa-public/icon\"\nimport { isSubscribeForUseDrive } from \"@illa-public/upgrade-modal/utils\"\nimport { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { FC, memo } from \"react\"\nimport { useDrag } from \"react-dnd\"\nimport { useSelector } from \"react-redux\"\nimport { ComponentItemProps } from \"@/page/App/components/ComponentPanel/interface\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { getGuideStatus } from \"@/redux/guide/guideSelector\"\nimport store from \"@/store\"\nimport { endDragMultiNodes, startDragMultiNodes } from \"@/utils/drag/drag\"\nimport { generateWidgetLayoutInfo } from \"@/utils/generators/generateComponentNode\"\nimport { DropResultInfo } from \"../DotPanel/components/Canvas/interface\"\nimport { DEFAULT_BODY_COLUMNS_NUMBER } from \"../DotPanel/constant/canvas\"\nimport { illaSnapshot } from \"../DotPanel/constant/snapshotNew\"\nimport { sendShadowMessageHandler } from \"../DotPanel/utils/sendBinaryMessage\"\nimport {\n  DRAG_EFFECT,\n  DragInfo,\n} from \"../ScaleSquare/components/DragContainer/interface\"\nimport {\n  iconStyle,\n  itemContainerStyle,\n  nameStyle,\n  upgradeIconStyle,\n} from \"./style\"\n\nexport const ComponentItem: FC<ComponentItemProps> = memo(\n  (props: ComponentItemProps) => {\n    const { widgetName, widgetType, icon, displayName, isPremiumWidget } = props\n\n    const isEditMode = useSelector(getIsILLAEditMode)\n    const isGuideOpen = useSelector(getGuideStatus)\n    const teamInfo = useSelector(getCurrentTeamInfo)!\n\n    const [, dragRef] = useDrag<DragInfo, DropResultInfo>(\n      () => ({\n        type: \"components\",\n        canDrag: () => {\n          return isEditMode\n        },\n        end: (draggedItem, monitor) => {\n          const dropResultInfo = monitor.getDropResult()\n          const { draggedComponents } = draggedItem\n          sendShadowMessageHandler(-1, \"\", [], 0, 0, 0, 0, 0, 0, 0, 0)\n          endDragMultiNodes(\n            draggedComponents,\n            !!dropResultInfo?.isDropOnCanvas,\n            true,\n          )\n        },\n        item: () => {\n          const widgetLayoutInfo = generateWidgetLayoutInfo(\n            widgetType,\n            displayName,\n          )\n          if (!widgetLayoutInfo) {\n            return {\n              draggedComponents: [],\n              dragEffect: DRAG_EFFECT.ADD,\n              draggedDisplayName: \"\",\n              unitWWhenDragged: 0,\n              columnNumberWhenDragged: DEFAULT_BODY_COLUMNS_NUMBER,\n            }\n          }\n          const rootState = store.getState()\n          let allWidgetLayoutInfo = getClientWidgetLayoutInfo(rootState)\n          illaSnapshot.setSnapshot(allWidgetLayoutInfo)\n          startDragMultiNodes([widgetLayoutInfo])\n          return {\n            draggedComponents: [widgetLayoutInfo],\n            dragEffect: DRAG_EFFECT.ADD,\n            draggedDisplayName: widgetLayoutInfo.displayName,\n            unitWWhenDragged: 0,\n            columnNumberWhenDragged: DEFAULT_BODY_COLUMNS_NUMBER,\n          }\n        },\n      }),\n      [isEditMode],\n    )\n\n    return (\n      <div\n        css={itemContainerStyle}\n        ref={dragRef}\n        {...(isGuideOpen ? { \"data-onboarding-element\": widgetType } : {})}\n      >\n        <span\n          css={iconStyle}\n          {...(isGuideOpen ? { \"data-onboarding-icon\": widgetType } : {})}\n        >\n          {isPremiumWidget &&\n            isCloudVersion &&\n            !isSubscribeForUseDrive(teamInfo) && (\n              <span css={upgradeIconStyle}>\n                <UpgradeIcon />\n              </span>\n            )}\n          {icon}\n        </span>\n        <span css={nameStyle}>{widgetName}</span>\n      </div>\n    )\n  },\n)\n\nComponentItem.displayName = \"ComponentItem\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ComponentPanel/ComponentSession.tsx",
    "content": "import { memo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getGuideStatus } from \"@/redux/guide/guideSelector\"\nimport { ComponentItem } from \"./ComponentItem\"\nimport { ComponentSessionProps } from \"./interface\"\nimport {\n  componentListContainerStyle,\n  sessionContainerStyle,\n  sessionTitleStyle,\n} from \"./style\"\n\nexport const ComponentSession = memo((props: ComponentSessionProps) => {\n  const { sessionTitle, widgetCardInfos, sessionType } = props\n  const isGuideOpen = useSelector(getGuideStatus)\n\n  return widgetCardInfos.length > 0 ? (\n    <div\n      css={sessionContainerStyle}\n      {...(isGuideOpen ? { \"data-onboarding-session\": sessionType } : {})}\n    >\n      <span css={sessionTitleStyle}>{sessionTitle}</span>\n      <div css={componentListContainerStyle}>\n        {widgetCardInfos.map((item) => (\n          <ComponentItem\n            key={item.id}\n            icon={item.icon}\n            widgetType={item.widgetType}\n            widgetName={item.widgetName}\n            displayName={item.displayName}\n            isPremiumWidget={item.isPremiumWidget}\n          />\n        ))}\n      </div>\n    </div>\n  ) : null\n})\n\nComponentSession.displayName = \"ComponentSession\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ComponentPanel/componentListBuilder.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport {\n  ComponentSessionProps,\n  TypeMapComponent,\n  WidgetCardInfo,\n} from \"@/page/App/components/ComponentPanel/interface\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\nimport {\n  WidgetType,\n  WidgetTypeList,\n  widgetBuilder,\n} from \"@/widgetLibrary/widgetBuilder\"\n\nexport const DEPRECATED_WIDGETS = [\"CHART\", \"TABLE_WIDGET\"]\nexport const PREMIUM_WIDGETS = [\"DRIVE_PICKER_WIDGET\"]\n\nexport type SessionType = keyof typeof sessionTypeMapSessionNameKey\n\nexport const sessionTypeMapSessionNameKey = {\n  COMMON: i18n.t(\"editor.widget_picker.sessions.commonly\"),\n  INPUTS: i18n.t(\"editor.widget_picker.sessions.inputs\"),\n  SELECT: i18n.t(\"editor.widget_picker.sessions.selects\"),\n  ILLA_DRIVE: i18n.t(\"editor.widget_picker.sessions.drive\"),\n  CALENDAR: i18n.t(\"editor.widget_picker.sessions.calendar\"),\n  PRESENTATION: i18n.t(\"editor.widget_picker.sessions.presentation\"),\n  DATA: i18n.t(\"editor.widget_picker.sessions.data\"),\n  CONTAINER: i18n.t(\"editor.widget_picker.sessions.container\"),\n  NAVIGATION: i18n.t(\"editor.widget_picker.sessions.navigation\"),\n}\n\nconst COMMONLY_WIDGET = new Set([\n  \"DATA_GRID_WIDGET\",\n  \"TEXT_WIDGET\",\n  \"BUTTON_WIDGET\",\n  \"INPUT_WIDGET\",\n  \"NUMBER_INPUT_WIDGET\",\n  \"DRIVE_PICKER_WIDGET\",\n  \"CONTAINER_WIDGET\",\n  \"FORM_WIDGET\",\n  \"MODAL_WIDGET\",\n  \"CHART_WIDGET\",\n  \"IMAGE_WIDGET\",\n  \"NAVIGATION_WIDGET\",\n])\n\nconst getListItemConfig = (type: WidgetType): WidgetConfig => {\n  return widgetBuilder(type).config\n}\n\nconst translateChildren = (componentConfigs: WidgetConfig[]) => {\n  const sessionConfigs: TypeMapComponent = {\n    COMMON: [],\n    INPUTS: [],\n    ILLA_DRIVE: [],\n    SELECT: [],\n    CALENDAR: [],\n    DATA: [],\n    CONTAINER: [],\n    NAVIGATION: [],\n    PRESENTATION: [],\n  }\n  componentConfigs.forEach((item) => {\n    const { sessionType = \"COMMON\", type, displayName, widgetName } = item\n    if (!sessionConfigs[sessionType]) {\n      sessionConfigs[sessionType] = []\n    }\n    const childrenConfig: WidgetCardInfo = {\n      id: `${sessionType}-${type}-${displayName}`,\n      keywords: item.keywords as string[],\n      widgetType: type,\n      widgetName,\n      icon: item.icon,\n      displayName,\n      isPremiumWidget: PREMIUM_WIDGETS.includes(type),\n    }\n    if (COMMONLY_WIDGET.has(type as string)) {\n      sessionConfigs.COMMON.push(childrenConfig)\n    }\n    sessionConfigs[sessionType].push(childrenConfig)\n  })\n  return sessionConfigs\n}\n\nexport const buildComponentConfigs = () => {\n  return WidgetTypeList.filter(\n    (type) => !DEPRECATED_WIDGETS.includes(type),\n  ).map((item) => {\n    return getListItemConfig(item) as WidgetConfig\n  }) as WidgetConfig[]\n}\n\nconst buildSessionTypeMapComponentConfig = (): TypeMapComponent => {\n  const componentConfigs = buildComponentConfigs()\n  return translateChildren(componentConfigs)\n}\n\nexport const buildComponentList = (): ComponentSessionProps[] => {\n  const configs = buildSessionTypeMapComponentConfig()\n  const keys = Object.keys(configs) as SessionType[]\n  return keys.map((key) => {\n    return {\n      sessionType: key,\n      sessionTitle: sessionTypeMapSessionNameKey[key],\n      widgetCardInfos: configs[key],\n    }\n  })\n}\n\nexport const buildInitDragInfo = (type: WidgetType) => {\n  const componentConfigs = buildComponentConfigs()\n  const currentComponentConfig = componentConfigs.find(\n    (config) => config.type === type,\n  )\n  return currentComponentConfig\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ComponentPanel/components/SuggestComponent/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button, CommentIcon } from \"@illa-design/react\"\nimport {\n  columnSessionTitleStyle,\n  columnSuggestComponentContainerStyle,\n  rowSuggestComponentContainerStyle,\n  sessionTitleStyle,\n} from \"./style\"\n\nconst clickSuggest = () => {\n  window.open(\n    \"https://builder.illacloud.com/illacloud/deploy/app/ILAbx4p1C7QZ\",\n    \"_blank\",\n  )\n}\n\nexport const RowSuggestComponent: FC = () => {\n  const { t } = useTranslation()\n  return (\n    <div css={rowSuggestComponentContainerStyle}>\n      <h6 css={sessionTitleStyle}>{t(\"editor.action.form.title.feedback\")}</h6>\n      <Button\n        leftIcon={<CommentIcon />}\n        colorScheme=\"grayBlue\"\n        variant=\"outline\"\n        onClick={clickSuggest}\n      >\n        {t(\"editor.action.form.option.tell_us\")}\n      </Button>\n    </div>\n  )\n}\n\nexport const ColumnSuggestComponent: FC = () => {\n  const { t } = useTranslation()\n  return (\n    <div css={columnSuggestComponentContainerStyle}>\n      <h6 css={columnSessionTitleStyle}>\n        {t(\"editor.action.form.title.feedback\")}\n      </h6>\n      <Button\n        leftIcon={<CommentIcon />}\n        colorScheme=\"grayBlue\"\n        variant=\"outline\"\n        onClick={clickSuggest}\n      >\n        {t(\"editor.action.form.option.tell_us\")}\n      </Button>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ComponentPanel/components/SuggestComponent/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const rowSuggestComponentContainerStyle = css`\n  width: 100%;\n  padding: 16px 0;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n`\n\nexport const columnSuggestComponentContainerStyle = css`\n  width: 100%;\n  padding: 16px 0;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const sessionTitleStyle = css`\n  line-height: 22px;\n  width: 100%;\n  font-size: 14px;\n  font-weight: 500;\n  align-items: center;\n  margin: 0;\n  padding: 0;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const columnSessionTitleStyle = css`\n  ${sessionTitleStyle};\n  text-align: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ComponentPanel/index.tsx",
    "content": "import { FC, useCallback, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Search } from \"@illa-design/react\"\nimport { buildComponentList } from \"@/page/App/components/ComponentPanel/componentListBuilder\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { ComponentSession } from \"./ComponentSession\"\nimport {\n  ColumnSuggestComponent,\n  RowSuggestComponent,\n} from \"./components/SuggestComponent\"\nimport { ComponentPanelProps, ComponentSessionProps } from \"./interface\"\nimport {\n  componentContainerStyle,\n  emptyContainerStyle,\n  searchWrapperStyle,\n  sessionListContainerStyle,\n} from \"./style\"\nimport { getMatchComponent } from \"./utils\"\n\nconst ComponentPanel: FC<ComponentPanelProps> = (props) => {\n  const { t } = useTranslation()\n\n  const defaultList: ComponentSessionProps[] = buildComponentList()\n  const { className, componentList = defaultList } = props\n  const [searchInput, setSearchInput] = useState(\"\")\n\n  const [searchRes, setSearchRes] = useState<\n    ComponentSessionProps[] | undefined\n  >(componentList)\n\n  const handleOnChange = useCallback(\n    (value: string) => {\n      setSearchInput(value)\n      const res = getMatchComponent(value, componentList)\n      setSearchRes(res)\n    },\n    [componentList],\n  )\n\n  return (\n    <div\n      className={className}\n      css={componentContainerStyle}\n      onClick={() => {\n        FocusManager.switchFocus(\"widget_picker\")\n      }}\n    >\n      <div css={searchWrapperStyle}>\n        <Search\n          value={searchInput}\n          colorScheme=\"purple\"\n          variant=\"fill\"\n          placeholder={t(\"editor.widget_picker.search_placeholder\")}\n          onChange={handleOnChange}\n        />\n      </div>\n      <div css={sessionListContainerStyle}>\n        {searchRes && searchRes.length ? (\n          searchRes\n            .map((session) => (\n              <ComponentSession\n                key={\"session-\" + session.sessionTitle}\n                {...session}\n              />\n            ))\n            .concat(<RowSuggestComponent key=\"suggest\" />)\n        ) : (\n          <div css={emptyContainerStyle}>\n            <ColumnSuggestComponent />\n          </div>\n        )}\n      </div>\n    </div>\n  )\n}\n\nComponentPanel.displayName = \"ComponentPanel\"\nexport default ComponentPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ComponentPanel/interface.ts",
    "content": "import { HTMLAttributes, ReactNode } from \"react\"\nimport { SessionType } from \"@/page/App/components/ComponentPanel/componentListBuilder\"\n\nexport interface ComponentPanelProps extends HTMLAttributes<HTMLDivElement> {\n  componentList?: ComponentSessionProps[]\n}\n\nexport interface WidgetCardInfo {\n  id: string\n  keywords: string[]\n  displayName: string\n  widgetName: string\n  widgetType: string\n  icon: ReactNode\n  isPremiumWidget: boolean\n}\n\nexport type ComponentSessionProps = {\n  sessionTitle: string\n  sessionType: SessionType\n  widgetCardInfos: WidgetCardInfo[]\n}\n\nexport type TypeMapComponent = {\n  [key in SessionType]: WidgetCardInfo[]\n}\n\nexport interface ComponentItemProps {\n  widgetName: string\n  displayName: string\n  widgetType: string\n  icon: ReactNode\n  isPremiumWidget: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ComponentPanel/style.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const componentContainerStyle = css`\n  border-top: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  width: 100%;\n  height: 100%;\n  padding-bottom: 40px;\n  overflow-y: hidden;\n  display: flex;\n  flex-direction: column;\n`\nexport const searchWrapperStyle = css`\n  padding: 16px 16px 8px 16px;\n`\n\nexport const sessionListContainerStyle = css`\n  ${searchWrapperStyle};\n  padding-top: 0;\n  padding-bottom: 0;\n  height: 100%;\n  overflow-y: auto;\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n`\n\nexport const sessionContainerStyle = css`\n  width: 100%;\n  display: inline-flex;\n  flex-direction: column;\n\n  &:not(:nth-of-type(1)) {\n    margin-top: 8px;\n  }\n`\n\nexport const sessionTitleStyle = css`\n  height: 38px;\n  width: 100%;\n  font-size: 14px;\n  font-weight: 500;\n  display: inline-flex;\n  align-items: center;\n`\n\nexport const componentListContainerStyle = css`\n  width: 100%;\n  display: grid;\n  grid-template-columns: repeat(3, 88px);\n  gap: 16px 8px;\n`\n\nexport const itemContainerStyle = css`\n  display: flex;\n  flex: 1 1 auto;\n  flex-direction: column;\n  align-items: center;\n  position: relative;\n  width: 88px;\n`\n\nexport const iconStyle = css`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  cursor: grab;\n  border-radius: 4px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  transition: background-color 200ms ease-in-out;\n  padding: 8px;\n  position: relative;\n  overflow: hidden;\n  &:hover {\n    background-color: ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  }\n`\n\nexport const nameStyle = css`\n  font-size: 12px;\n  width: 100%;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-03`)};\n  text-overflow: ellipsis;\n  box-sizing: border-box;\n  padding: 4px 4px 0 4px;\n  overflow: hidden;\n  text-align: center;\n  line-height: 14px;\n`\n\nexport const emptyContainerStyle = css`\n  width: 100%;\n  height: 319px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n\nexport const upgradeIconStyle = css`\n  position: absolute;\n  padding: 2px 8px;\n  top: 0;\n  left: 0;\n  color: ${getColor(\"techPurple\", \"03\")};\n  background-color: ${getColor(\"techPurple\", \"08\")};\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ComponentPanel/utils.tsx",
    "content": "import { sessionTypeMapSessionNameKey } from \"@/page/App/components/ComponentPanel/componentListBuilder\"\nimport { ComponentSessionProps } from \"./interface\"\n\nexport function getMatchComponent(\n  value?: string,\n  options?: ComponentSessionProps[],\n) {\n  if (!value || value.length === 0) return options\n  const valueArr = value.split(\"\")\n  let regKey = \".*\"\n  valueArr.forEach((s) => {\n    regKey += s.toLocaleLowerCase() + \".*\"\n  })\n  const reg = RegExp(regKey)\n\n  const newSessionList: ComponentSessionProps[] = []\n  const removeCommonlyOptions = options?.filter((option) => {\n    return option.sessionTitle !== sessionTypeMapSessionNameKey.COMMON\n  })\n  removeCommonlyOptions?.forEach((session) => {\n    const res = session.widgetCardInfos.filter((widgetCardInfo) => {\n      const keyword = widgetCardInfo?.keywords\n      return keyword\n        ? keyword.some((key) => key.toLocaleLowerCase().match(reg))\n        : widgetCardInfo.widgetName.toLocaleLowerCase().match(reg)\n    })\n    if (res.length > 0) {\n      newSessionList.push({ ...session, widgetCardInfos: res })\n    }\n  })\n  return newSessionList\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ConfigPanel/index.tsx",
    "content": "import { FC, HTMLAttributes, lazy } from \"react\"\nimport { Divider } from \"@illa-design/react\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { configPanelStyle } from \"./style\"\n\ninterface ConfigPanelProps extends HTMLAttributes<HTMLDivElement> {}\n\nconst InspectPanel = lazy(() => import(\"@/page/App/components/InspectPanel\"))\n\nconst ConfigPanel: FC<ConfigPanelProps> = (props) => {\n  const { className } = props\n\n  return (\n    <div\n      className={className}\n      css={configPanelStyle}\n      onClick={() => {\n        FocusManager.switchFocus(\"components_config\")\n      }}\n    >\n      <Divider />\n      <InspectPanel />\n    </div>\n  )\n}\n\nConfigPanel.displayName = \"ConfigPanel\"\nexport default ConfigPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ConfigPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const configPanelStyle = css`\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n  padding-bottom: 48px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Debugger/components/ErrorItem/index.tsx",
    "content": "import { motion } from \"framer-motion\"\nimport { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CaretRightIcon, ErrorCircleIcon } from \"@illa-design/react\"\nimport { JsonView } from \"@/page/App/components/Debugger/components/JsonView\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { getDisplayNameAndPropertyPath } from \"@/utils/executionTreeHelper/utils\"\nimport { ErrorItemProps } from \"./interface\"\nimport {\n  applyExpandIconStyle,\n  errorContainerStyle,\n  errorExpandStyle,\n  errorIconStyle,\n  errorInfoStyle,\n  errorItemContentStyle,\n  errorItemStyle,\n  errorMessageStyle,\n  jsonContentAnimation,\n  jsonStyle,\n  nameStyle,\n  sourceStyle,\n} from \"./style\"\n\nexport const ErrorItem: FC<ErrorItemProps> = (props) => {\n  const { item, pathName } = props\n  const dispatch = useDispatch()\n  const components = useSelector(getComponentMap)\n  const [isExpanded, setIsExpanded] = useState(false)\n\n  const { displayName, attrPath } = getDisplayNameAndPropertyPath(pathName)\n\n  const attrValue = useMemo(() => {\n    const node = searchComponentFromMap(components, displayName)\n    if (node) {\n      return get(node?.props, attrPath)\n    }\n    return undefined\n  }, [components, displayName, attrPath])\n\n  const handleComponentSelect = useCallback(() => {\n    const selectedComponent = searchComponentFromMap(components, displayName)\n    if (selectedComponent) {\n      dispatch(\n        configActions.updateSelectedComponent([selectedComponent.displayName]),\n      )\n    }\n  }, [components, displayName, dispatch])\n\n  return (\n    <div css={errorContainerStyle}>\n      <div css={errorItemStyle}>\n        <div css={errorItemContentStyle}>\n          <ErrorCircleIcon size={\"16px\"} css={errorIconStyle} />\n          <span\n            css={[errorExpandStyle, applyExpandIconStyle(isExpanded)]}\n            onClick={() => {\n              setIsExpanded(!isExpanded)\n            }}\n          >\n            <CaretRightIcon />\n          </span>\n          <span css={nameStyle} onClick={handleComponentSelect}>\n            [{displayName}]\n          </span>\n          <span css={errorInfoStyle}>The value at {attrPath} is invalid</span>\n        </div>\n        <div css={sourceStyle} onClick={handleComponentSelect}>\n          {pathName}\n        </div>\n      </div>\n      <motion.div\n        css={jsonStyle}\n        variants={jsonContentAnimation}\n        role=\"region\"\n        animate={isExpanded ? \"enter\" : \"exit\"}\n        initial={false}\n        transition={{ duration: 0.2 }}\n      >\n        <div css={errorMessageStyle}>\n          {item?.errorName}: {item?.errorMessage}\n        </div>\n        <JsonView key={attrPath} name={attrPath} value={attrValue} />\n      </motion.div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Debugger/components/ErrorItem/interface.ts",
    "content": "import { HTMLAttributes } from \"react\"\nimport { ErrorShape } from \"@/redux/currentApp/executionTree/executionState\"\n\nexport interface ErrorItemProps extends HTMLAttributes<HTMLDivElement> {\n  pathName: string\n  item: ErrorShape\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Debugger/components/ErrorItem/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { Variants } from \"framer-motion\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const errorContainerStyle = css`\n  background-color: ${globalColor(`--${illaPrefix}-techPink-08`)};\n`\n\nexport const errorItemStyle = css`\n  display: flex;\n  justify-content: space-between;\n  align-items: start;\n  padding: 8px 16px;\n  font-weight: 400;\n  font-size: 14px;\n  line-height: 22px;\n  min-height: 38px;\n  z-index: 1;\n`\n\nexport const errorItemContentStyle = css`\n  display: flex;\n  align-items: start;\n`\n\nexport const nameStyle = css`\n  cursor: pointer;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-03`)};\n  margin-right: 8px;\n`\n\nexport const errorInfoStyle = css`\n  word-break: break-word;\n`\n\nexport const sourceStyle = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-03`)};\n  text-decoration-line: underline;\n  cursor: pointer;\n\n  &:hover {\n    color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  }\n`\n\nexport const errorIconStyle = css`\n  flex-shrink: 0;\n  color: ${globalColor(`--${illaPrefix}-red-03`)};\n  margin-top: 3px;\n`\n\nexport const errorExpandStyle = css`\n  padding: 2px 4px;\n  margin: 5px 4px;\n`\n\nexport function applyExpandIconStyle(expanded?: boolean): SerializedStyles {\n  const rotate = expanded ? 90 : 0\n  return css`\n    display: inline-flex;\n    font-size: 8px;\n    line-height: 0;\n    cursor: pointer;\n    transform-origin: center;\n    transform: rotate(${rotate}deg);\n    transition: transform 200ms;\n  `\n}\n\nexport const jsonStyle = css`\n  padding-left: 56px;\n  font-weight: 400;\n  font-size: 14px;\n  line-height: 22px;\n`\n\nexport const errorMessageStyle = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  text-decoration-line: underline;\n  cursor: pointer;\n`\n\nexport const jsonContentAnimation: Variants = {\n  enter: {\n    height: \"unset\",\n    opacity: 1,\n    visibility: \"visible\",\n    display: \"inherit\",\n  },\n  exit: {\n    height: 0,\n    opacity: 0,\n    visibility: \"hidden\",\n    transitionEnd: {\n      display: \"none\",\n    },\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Debugger/components/JsonView/index.tsx",
    "content": "import { motion } from \"framer-motion\"\nimport { FC, useState } from \"react\"\nimport { CaretRightIcon, isArray, isObject, isString } from \"@illa-design/react\"\nimport { applyJsonValueColorStyle } from \"@/page/App/Module/DataWorkspace/style\"\nimport {\n  applyExpandIconStyle,\n  jsonContentAnimation,\n} from \"@/page/App/components/Debugger/components/ErrorItem/style\"\nimport { JsonViewProps } from \"./interface\"\nimport {\n  applyLevelStyle,\n  itemDescStyle,\n  jsonExpandStyle,\n  jsonStyle,\n} from \"./style\"\n\nexport const JsonView: FC<JsonViewProps> = (props) => {\n  const { name, value, level = 0 } = props\n  const [isExpanded, setIsExpanded] = useState(false)\n\n  const type = typeof value\n  if (isObject(value) || isArray(value)) {\n    const keyArr = Object.keys(value).filter((item) => !item.startsWith(\"$\"))\n    return (\n      <>\n        <div css={jsonStyle}>\n          <span\n            css={[jsonExpandStyle, applyExpandIconStyle(isExpanded)]}\n            onClick={() => {\n              setIsExpanded(!isExpanded)\n            }}\n          >\n            <CaretRightIcon />\n          </span>\n          <span css={applyJsonValueColorStyle(\"string\")}>{`\"${name}\"`}</span>:\n          <label css={itemDescStyle}>\n            {`${isObject(value) ? \"{}\" : \"[]\"}`}&nbsp;{keyArr.length}\n            {keyArr.length > 1 ? \"keys\" : \"key\"}\n          </label>\n        </div>\n        <motion.div\n          variants={jsonContentAnimation}\n          role=\"region\"\n          animate={isExpanded ? \"enter\" : \"exit\"}\n          initial={false}\n          transition={{ duration: 0.2 }}\n        >\n          {keyArr.map((name) => (\n            <JsonView\n              key={name}\n              name={name}\n              value={value[name] as Record<string, unknown>}\n              level={level + 1}\n            />\n          ))}\n        </motion.div>\n      </>\n    )\n  }\n\n  return (\n    <div css={[jsonStyle, applyLevelStyle(level + 1)]}>\n      <span css={applyJsonValueColorStyle(\"string\")}>{`\"${name}\"`}</span>:\n      <span>\n        {isString(value) ? (\n          <span css={applyJsonValueColorStyle(type)}>{`\"${value}\"`}</span>\n        ) : (\n          <span css={applyJsonValueColorStyle(type)}>{`${value}`}</span>\n        )}\n      </span>\n    </div>\n  )\n}\n\nJsonView.displayName = \"JsonView\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Debugger/components/JsonView/interface.ts",
    "content": "import { HTMLAttributes } from \"react\"\n\nexport interface JsonViewProps extends HTMLAttributes<HTMLDivElement> {\n  name: string\n  value: Record<string, unknown>\n  level?: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Debugger/components/JsonView/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const jsonStyle = css`\n  font-family: \"Fira Code\", monospace;\n  padding-top: 4px;\n  padding-bottom: 6px;\n  font-size: 14px;\n  line-height: 22px;\n`\n\nexport const itemDescStyle: SerializedStyles = css`\n  display: inline-block;\n  vertical-align: bottom;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  margin-left: 8px;\n`\n\nexport const jsonExpandStyle = css`\n  margin-right: 8px;\n`\n\nexport function applyLevelStyle(level: number): SerializedStyles {\n  return css`\n    margin-left: ${level * 16}px;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Debugger/index.tsx",
    "content": "import { FC, HTMLAttributes, useCallback, useRef } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { CloseIcon, Divider, isArray } from \"@illa-design/react\"\nimport { DragBar } from \"@/page/App/components/Actions/DragBar\"\nimport { ErrorItem } from \"@/page/App/components/Debugger/components/ErrorItem\"\nimport { isOpenDebugger } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getExecutionError } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport {\n  applyDebuggerStyle,\n  containerStyle,\n  errorContentStyle,\n  titleStyle,\n} from \"./style\"\n\nconst DebuggerDefaultHeight = 300\n\nexport const Debugger: FC<HTMLAttributes<HTMLDivElement>> = (props) => {\n  const dispatch = useDispatch()\n  const panelRef = useRef<HTMLDivElement>(null)\n  const debuggerData = useSelector(getExecutionError)\n  const debuggerVisible = useSelector(isOpenDebugger)\n\n  const handleClickDebuggerIcon = useCallback(() => {\n    dispatch(configActions.updateDebuggerVisible(!debuggerVisible))\n  }, [debuggerVisible, dispatch])\n\n  return (\n    <div\n      className={props.className}\n      css={applyDebuggerStyle(DebuggerDefaultHeight)}\n      ref={panelRef}\n    >\n      <DragBar resizeRef={panelRef} minHeight={DebuggerDefaultHeight} />\n      <Divider direction=\"horizontal\" />\n      <div css={titleStyle}>\n        <span>Errors</span>\n        <CloseIcon onClick={handleClickDebuggerIcon} />\n      </div>\n      <div css={containerStyle}>\n        <div css={errorContentStyle}>\n          {Object.keys(debuggerData)?.map((name, index) => {\n            const error = debuggerData[name]\n\n            if (isArray(error) && error.length > 0) {\n              return error?.map((item) => {\n                return <ErrorItem key={index} pathName={name} item={item} />\n              })\n            } else {\n              return null\n            }\n          })}\n        </div>\n      </div>\n    </div>\n  )\n}\n\nDebugger.displayName = \"Debugger\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Debugger/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport function applyDebuggerStyle(h: number) {\n  return css`\n    position: relative;\n    width: 100%;\n    height: ${h}px;\n    display: flex;\n    flex-direction: column;\n  `\n}\n\nexport const containerStyle = css`\n  height: 100%;\n  overflow: auto;\n  display: flex;\n  flex-direction: column;\n  position: relative;\n`\n\nexport const titleStyle = css`\n  display: flex;\n  justify-content: space-between;\n  padding: 13px 16px 13px 12px;\n  box-shadow: inset 0px -1px 1px #e5e6eb;\n  font-weight: 500;\n  font-size: 14px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const errorContentStyle = css`\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/calc.ts",
    "content": "import { ComponentMapNode } from \"@illa-public/public-types\"\n\ninterface ItemPosition {\n  x: number\n  y: number\n}\n\nexport interface CanvasPosition {\n  x: number\n  y: number\n}\n\ninterface NodeWidthAndHeight {\n  w: number\n  h: number\n}\n\ninterface CenterPointPosition {\n  x: number\n  y: number\n}\n\nexport function calcRectCenterPointPosition(\n  itemPosition: ItemPosition,\n  canvasPosition: CanvasPosition,\n  nodeWidthAndHeight: NodeWidthAndHeight,\n): CenterPointPosition {\n  const { x: itemX, y: itemY } = itemPosition\n  const { x: canvasX, y: canvasY } = canvasPosition\n  const { w: nodeW, h: nodeH } = nodeWidthAndHeight\n  const pointX = itemX - canvasX\n  const pointY = itemY - canvasY\n  const centerX = pointX - nodeW / 2\n  const centerY = pointY - nodeH / 2\n  return {\n    x: centerX,\n    y: centerY,\n  }\n}\n\ninterface RectShape {\n  rectTop: number\n  rectRight: number\n  rectBottom: number\n  rectLeft: number\n}\n\nexport function calcRectShapeByCenterPoint(\n  centerPointPosition: CenterPointPosition,\n  nodeWidthAndHeight: NodeWidthAndHeight,\n): RectShape {\n  const rectTop = centerPointPosition.y\n  const rectLeft = centerPointPosition.x\n  const rectRight = rectLeft + nodeWidthAndHeight.w\n  const rectBottom = rectTop + nodeWidthAndHeight.h\n  return {\n    rectTop,\n    rectLeft,\n    rectRight,\n    rectBottom,\n  }\n}\n\nexport interface LandingPosition {\n  isOverstep: boolean\n  landingX: number\n  landingY: number\n  relativeLandingX: number\n  relativeLandingY: number\n}\n\nexport function calcLadingPosition(\n  rectPosition: RectShape,\n  unitWidth: number,\n  unitHeight: number,\n  canvasWidth: number,\n  canvasHeight: number,\n  canResizeY: boolean,\n): LandingPosition {\n  const { rectLeft, rectTop, rectRight, rectBottom } = rectPosition\n  const relativeLandingX = Math.round(rectLeft / unitWidth)\n  const relativeLandingY = Math.round(rectTop / unitHeight)\n  let landingX = relativeLandingX * unitWidth\n  let landingY = relativeLandingY * unitHeight\n  let isOverstep = true\n  if (rectTop < 0) {\n    landingY = 0\n    isOverstep = false\n  }\n  if (rectLeft < 0) {\n    landingX = 0\n    isOverstep = false\n  }\n  if (rectRight > canvasWidth) {\n    const overRight =\n      Math.round(rectRight / unitWidth) * unitWidth - canvasWidth\n    landingX = landingX - overRight\n    isOverstep = false\n  }\n  if (rectBottom > canvasHeight && !canResizeY) {\n    const overBottom =\n      Math.round(rectBottom / unitHeight) * unitHeight - canvasHeight\n    landingY = landingY - overBottom\n    isOverstep = false\n  }\n  return {\n    isOverstep,\n    landingX,\n    landingY,\n    relativeLandingX,\n    relativeLandingY,\n  }\n}\n\nexport type RectangleType = {\n  left: number\n  right: number\n  top: number\n  bottom: number\n}\n\nconst sortComponentNodesOnlyY = (componentNodes: ComponentMapNode[]) => {\n  return componentNodes.sort((node1, node2) => {\n    if (node1.y < node2.y) {\n      return -1\n    }\n    if (node1.y > node2.y) {\n      return 1\n    }\n    return 0\n  })\n}\n\nexport const sortComponentNodes = (componentNodes: ComponentMapNode[]) => {\n  return componentNodes.sort((node1, node2) => {\n    if (node1.y < node2.y) {\n      return -1\n    }\n    if (node1.y > node2.y) {\n      return 1\n    }\n    if (node1.y === node2.y) {\n      if (node1.x > node2.x) {\n        return 1\n      }\n      if (node1.x < node2.x) {\n        return -1\n      }\n    }\n    return 0\n  })\n}\n\nconst getComponentRect = (component: ComponentMapNode): RectangleType => {\n  const { x, y, w, h } = component\n  return {\n    left: x,\n    right: x + w,\n    top: y,\n    bottom: y + h,\n  }\n}\n\nexport const isCrossing = (\n  otherNode: ComponentMapNode,\n  mainNode: ComponentMapNode,\n) => {\n  const otherRect = getComponentRect(otherNode)\n  const mainRect = getComponentRect(mainNode)\n  return !(\n    mainRect.left >= otherRect.right ||\n    mainRect.right <= otherRect.left ||\n    mainRect.top >= otherRect.bottom ||\n    mainRect.bottom <= otherRect.top\n  )\n}\n\nexport const isNearingAtY = (\n  otherNode: ComponentMapNode,\n  mainNode: ComponentMapNode,\n) => {\n  const otherRect = getComponentRect(otherNode)\n  const mainRect = getComponentRect(mainNode)\n  return (\n    (mainRect.left <= otherRect.right || mainRect.right >= otherRect.left) &&\n    mainRect.bottom === otherRect.top\n  )\n}\n\nexport const getCrossingNodeNewPosition = (\n  currentNode: ComponentMapNode,\n  allComponentNode: ComponentMapNode[],\n) => {\n  let otherComponents = allComponentNode.filter(\n    (curNode) => curNode.displayName !== currentNode.displayName,\n  )\n\n  let res: Map<string, ComponentMapNode> = new Map(),\n    queue: ComponentMapNode[] = []\n\n  queue.push(currentNode)\n  while (queue.length !== 0) {\n    let length = queue.length\n    otherComponents = otherComponents.filter(\n      (curNode) => curNode.displayName !== queue[0].displayName,\n    )\n    const walkedSet = new Set()\n    for (let i = 0; i < length; i++) {\n      let node = queue.shift() as ComponentMapNode\n      for (let i = 0; i < otherComponents.length; i++) {\n        if (otherComponents[i].displayName === node.displayName) {\n          continue\n        }\n        if (isCrossing(otherComponents[i], node)) {\n          otherComponents[i] = {\n            ...otherComponents[i],\n            y: node.y + node.h,\n          }\n          walkedSet.add(otherComponents[i].displayName)\n          res.set(otherComponents[i].displayName, otherComponents[i])\n          const index = queue.findIndex(\n            (node) => node.displayName === otherComponents[i].displayName,\n          )\n          if (index > -1) {\n            queue.splice(index, 1, otherComponents[i])\n          } else {\n            queue.push(otherComponents[i])\n          }\n        }\n      }\n    }\n  }\n  return res\n}\n\nexport const getNearingNodes = (\n  currentNode: ComponentMapNode,\n  allComponentNode: ComponentMapNode[],\n) => {\n  let otherComponents = allComponentNode.filter(\n    (cur) => cur.displayName !== currentNode.displayName,\n  )\n\n  let res: Map<string, ComponentMapNode> = new Map(),\n    queue: ComponentMapNode[] = []\n\n  queue.push(currentNode)\n  while (queue.length !== 0) {\n    let length = queue.length\n\n    otherComponents = otherComponents.filter(\n      (cur) => cur.displayName !== queue[0].displayName,\n    )\n\n    const walkedSet = new Set()\n    for (let i = 0; i < length; i++) {\n      let node = queue.shift() as ComponentMapNode\n      for (let i = 0; i < otherComponents.length; i++) {\n        if (otherComponents[i].displayName === node.displayName) {\n          continue\n        }\n        if (isNearingAtY(otherComponents[i], node)) {\n          walkedSet.add(otherComponents[i].displayName)\n          res.set(otherComponents[i].displayName, otherComponents[i])\n          const index = queue.findIndex(\n            (node) => node.displayName === otherComponents[i].displayName,\n          )\n          if (index > -1) {\n            queue.splice(index, 1, otherComponents[i])\n          } else {\n            queue.push(otherComponents[i])\n          }\n        }\n      }\n    }\n  }\n  return res\n}\n\nexport const applyEffectMapToComponentNodes = (\n  effectMap: Map<string, ComponentMapNode>,\n  componentNodes: ComponentMapNode[],\n) => {\n  return componentNodes.map((node) => {\n    if (effectMap.has(node.displayName)) {\n      return effectMap.get(node.displayName) as ComponentMapNode\n    }\n    return node\n  })\n}\n\nexport const getReflowResult = (\n  currentNode: ComponentMapNode,\n  allComponentNodes: ComponentMapNode[],\n  exceptSelf: boolean = true,\n) => {\n  const sortedComponentNodes = sortComponentNodes(allComponentNodes)\n  const effectResultMap = getCrossingNodeNewPosition(\n    currentNode,\n    sortedComponentNodes,\n  )\n  let finalState = applyEffectMapToComponentNodes(\n    effectResultMap,\n    sortedComponentNodes,\n  )\n\n  if (exceptSelf) {\n    finalState = finalState.filter(\n      (node) => node.displayName !== currentNode.displayName,\n    )\n  }\n  return {\n    effectResultMap,\n    finalState,\n  }\n}\n\nexport const getNearComponentNodes = (\n  currentNode: ComponentMapNode,\n  allComponentNodes: ComponentMapNode[],\n) => {\n  const sortedComponentNodes = sortComponentNodesOnlyY(allComponentNodes)\n  return getNearingNodes(currentNode, sortedComponentNodes)\n}\n\nexport const isAddAction = (\n  x: number,\n  y: number,\n  oldParentDisplayName: string | null,\n  currentParentDisplayName: string,\n) => {\n  return (\n    (x === -1 && y === -1) || oldParentDisplayName !== currentParentDisplayName\n  )\n}\n\nexport function getMousePointerPosition(\n  mouseOffsetX: number,\n  mouseOffsetY: number,\n  unitWidth: number,\n  unitHeight: number,\n  containerMaxWidthDotNumber: number,\n): number[] {\n  let preX = Math.floor(mouseOffsetX / unitWidth)\n  preX = Math.min(preX, containerMaxWidthDotNumber)\n  let preY = Math.floor(mouseOffsetY / unitHeight)\n  return [preX, preY]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Canvas/interface.ts",
    "content": "export interface RenderComponentCanvasContainerProps {\n  displayName: string\n  containerPadding: string\n  columnNumber?: number\n  isRootCanvas?: boolean\n  canResizeCanvas?: boolean\n  safeRowNumber?: number\n  handleUpdateHeight?: (height: number) => void\n  minHeight?: number\n  background?: string\n  shadowSize?: \"none\" | \"small\" | \"medium\" | \"large\"\n}\n\nexport interface DropCollectedProps {\n  isOver: boolean\n}\n\nexport interface DropResultInfo {\n  isDropOnCanvas: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Canvas/renderComponentCanvasContainer.tsx",
    "content": "import {\n  FC,\n  MouseEventHandler,\n  memo,\n  useCallback,\n  useEffect,\n  useRef,\n  useState,\n} from \"react\"\nimport { useDrop } from \"react-dnd\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useScroll } from \"react-use\"\nimport useMeasure from \"react-use-measure\"\nimport { useMessage } from \"@illa-design/react\"\nimport { getMousePointerPosition } from \"@/page/App/components/DotPanel/calc\"\nimport ComponentParser from \"@/page/App/components/DotPanel/components/ComponentParser\"\nimport DragPreview from \"@/page/App/components/DotPanel/components/DragPreview\"\nimport { DragShadowPreview } from \"@/page/App/components/DotPanel/components/DragShadowPreview\"\nimport { MousePreview } from \"@/page/App/components/DotPanel/components/MousePreview\"\nimport { MultiSelectCanvas } from \"@/page/App/components/DotPanel/components/MultiSelectCanvas\"\nimport MultiSelectedScaleSquare from \"@/page/App/components/DotPanel/components/MultiSelectedContainer\"\nimport {\n  ADD_ROWS,\n  DEFAULT_BODY_COLUMNS_NUMBER,\n  SAFE_ROWS,\n  SCROLL_CONTAINER_PADDING,\n  UNIT_HEIGHT,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport {\n  removeScrollBarContainerControllerByDisplayName,\n  setScrollBarContainerController,\n} from \"@/page/App/components/DotPanel/context/scrollBarContext\"\nimport { useMousePositionAsync } from \"@/page/App/components/DotPanel/hooks/useMousePostionAsync\"\nimport { clamWidgetShape } from \"@/page/App/components/DotPanel/utils/getDragShadow\"\nimport { getLayoutInfosWithRelativeCombineShape } from \"@/page/App/components/DotPanel/utils/getDropResult\"\nimport { sendMousePositionHandler } from \"@/page/App/components/DotPanel/utils/sendBinaryMessage\"\nimport {\n  DRAG_EFFECT,\n  DragInfo,\n} from \"@/page/App/components/ScaleSquare/components/DragContainer/interface\"\nimport { useResizingUpdateRealTime } from \"@/page/App/components/ScaleSquare/components/ResizingAndDragContainer/ResizeHandler/hooks\"\nimport {\n  getIsILLAEditMode,\n  getIsLikeProductMode,\n  getSelectedComponentDisplayNames,\n  isShowDot,\n} from \"@/redux/config/configSelector\"\nimport {\n  getContainerListDisplayNameMappedChildrenNodeDisplayName,\n  searchDSLByDisplayName,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport {\n  getCurrentPageDisplayName,\n  getIsDragging,\n  getIsResizing,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { newGenerateComponentNode } from \"@/utils/generators/generateComponentNode\"\nimport { getPaddingShape } from \"@/utils/styleUtils/padding\"\nimport { ContainerEmptyState } from \"@/widgetLibrary/ContainerWidget/emptyState\"\nimport { useAutoUpdateCanvasHeight } from \"@/widgetLibrary/PublicSector/utils/autoUpdateHeight\"\nimport {\n  DropCollectedProps,\n  DropResultInfo,\n  RenderComponentCanvasContainerProps,\n} from \"./interface\"\nimport {\n  applyComponentCanvasStyle,\n  componentCanvasContainerStyle,\n  containerShapeStyle,\n  dropZoneStyle,\n  outerComponentCanvasContainerStyle,\n  selectoSelectionStyle,\n} from \"./style\"\n\nconst RenderComponentCanvasContainer: FC<\n  RenderComponentCanvasContainerProps\n> = (props) => {\n  const {\n    columnNumber = DEFAULT_BODY_COLUMNS_NUMBER,\n    isRootCanvas,\n    displayName,\n    containerPadding,\n    canResizeCanvas = false,\n    safeRowNumber = SAFE_ROWS,\n    minHeight,\n    background,\n    shadowSize = \"none\",\n    handleUpdateHeight,\n  } = props\n\n  const containerListMapChildName = useSelector(\n    getContainerListDisplayNameMappedChildrenNodeDisplayName,\n  )\n\n  const scrollContainerRef = useRef<HTMLDivElement | null>(null)\n  const firstDragRef = useRef(true)\n  const dragStartScrollTop = useRef(0)\n  const { y: scrollContainerScrollTop } = useScroll(scrollContainerRef)\n  const currentPageDisplayName = useSelector(getCurrentPageDisplayName)\n  const [canvasRef, bounds] = useMeasure()\n  const messageHandler = useMessage()\n  const innerCanvasRef = useRef<HTMLDivElement | null>(null)\n  const { t } = useTranslation()\n  const paddings = getPaddingShape(containerPadding)\n  const fixedBounds = {\n    top: bounds.top + paddings.paddingTop + SCROLL_CONTAINER_PADDING,\n    left: bounds.left + paddings.paddingLeft + SCROLL_CONTAINER_PADDING,\n    width:\n      bounds.width -\n      (paddings.paddingLeft +\n        paddings.paddingRight +\n        SCROLL_CONTAINER_PADDING * 2),\n    height:\n      bounds.height -\n      (paddings.paddingTop +\n        paddings.paddingBottom +\n        SCROLL_CONTAINER_PADDING * 2),\n  }\n\n  const canShowDot = useSelector(isShowDot)\n  const unitWidth = fixedBounds.width / columnNumber\n\n  const [canvasHeight, setCanvasHeight] = useState<number>(fixedBounds.height)\n  const widgetLayoutInfo = useSelector(getClientWidgetLayoutInfo)\n  const childWidgetLayoutInfo = Object.values(widgetLayoutInfo).filter(\n    (item) => item.parentNode === displayName,\n  )\n  const selectedComponents = useSelector(getSelectedComponentDisplayNames)\n  const dispatch = useDispatch()\n  const isDraggingGlobal = useSelector(getIsDragging)\n  const isResizingGlobal = useSelector(getIsResizing)\n  const isLikeProductMode = useSelector(getIsLikeProductMode)\n\n  const isEditMode = useSelector(getIsILLAEditMode)\n\n  const currentLayoutInfo = widgetLayoutInfo[displayName]\n\n  const [collectedProps, dropRef] = useDrop<\n    DragInfo,\n    DropResultInfo,\n    DropCollectedProps\n  >(\n    () => ({\n      accept: [\"components\"],\n      canDrop: () => {\n        return isEditMode\n      },\n      drop: (dropItem, monitor) => {\n        const didDrop = monitor.didDrop()\n        if (\n          !monitor.isOver({\n            shallow: true,\n          }) &&\n          didDrop\n        ) {\n          return {\n            isDropOnCanvas: !!monitor.getDropResult()?.isDropOnCanvas,\n          }\n        }\n\n        const { draggedComponents, dropResult, dragEffect } = dropItem\n        const originParentNode = draggedComponents[0].parentNode\n\n        if (dropResult && !dropResult.shape && !dropResult.canDrop) {\n          messageHandler.error({\n            content: t(\"frame.message.session.error\"),\n          })\n          return {\n            isDropOnCanvas: false,\n          }\n        }\n\n        if (!dropResult || !dropResult.shape) {\n          return {\n            isDropOnCanvas: false,\n          }\n        }\n\n        const hasTable = draggedComponents.some(\n          (components) => components.widgetType === \"TABLE_WIDGET\",\n        )\n        const isListChildrenCanvas = Object.values(\n          containerListMapChildName,\n        ).some((childDisplayNames) => childDisplayNames.includes(displayName))\n\n        if (hasTable && isListChildrenCanvas) {\n          messageHandler.error({\n            content: t(\"editor.inspect.setter_tips.list.table_disallowed\"),\n          })\n          return {\n            isDropOnCanvas: false,\n          }\n        }\n\n        const {\n          shape: dropResultShape,\n          columnNumberWhenDrag,\n          columnNumberWhenDrop,\n        } = dropResult\n\n        if (draggedComponents.length === 1) {\n          switch (dragEffect) {\n            case DRAG_EFFECT.ADD: {\n              const newComponentNode = newGenerateComponentNode(\n                dropResultShape.x,\n                dropResultShape.y,\n                dropResultShape.w,\n                draggedComponents[0].widgetType,\n                draggedComponents[0].displayName,\n                displayName,\n                [],\n                columnNumberWhenDrop / columnNumberWhenDrag,\n              )\n\n              if (newComponentNode.type === \"MODAL_WIDGET\") {\n                dispatch(\n                  componentsActions.addModalComponentReducer({\n                    currentPageDisplayName,\n                    modalComponentNode: newComponentNode,\n                  }),\n                )\n              } else {\n                dispatch(\n                  componentsActions.addComponentReducer([newComponentNode]),\n                )\n              }\n\n              break\n            }\n            case DRAG_EFFECT.UPDATE: {\n              const updateSlices = [\n                {\n                  displayName: draggedComponents[0].displayName,\n                  x: dropResultShape.x,\n                  y: dropResultShape.y,\n                  w: dropResultShape.w,\n                  h: draggedComponents[0].layoutInfo.h,\n                },\n              ]\n              dispatch(\n                componentsActions.updateComponentPositionReducer({\n                  oldParentNodeDisplayName: originParentNode,\n                  newParentNodeDisplayName: displayName,\n                  updateSlices,\n                  columnNumberWhenDrag,\n                  columnNumberWhenDrop,\n                }),\n              )\n            }\n          }\n        }\n\n        if (draggedComponents.length > 1 && dragEffect === DRAG_EFFECT.UPDATE) {\n          const relativeLayoutInfo =\n            getLayoutInfosWithRelativeCombineShape(draggedComponents)\n          const updateSlices = relativeLayoutInfo.map((item) => {\n            const shape = clamWidgetShape(\n              {\n                x: item.layoutInfo.x + dropResultShape.x,\n                y: item.layoutInfo.y + dropResultShape.y,\n                w: item.layoutInfo.w,\n                h: item.layoutInfo.h,\n              },\n              columnNumber,\n              draggedComponents.length > 1,\n            )\n            return {\n              ...shape,\n              h: shape.previewH,\n              displayName: item.displayName,\n            }\n          })\n          dispatch(\n            componentsActions.updateComponentPositionReducer({\n              oldParentNodeDisplayName: originParentNode,\n              newParentNodeDisplayName: displayName,\n              updateSlices,\n              columnNumberWhenDrag,\n              columnNumberWhenDrop,\n            }),\n          )\n        }\n\n        const mousePosition = cursorPositionRef.current\n        sendMousePositionHandler(\n          displayName,\n          mousePosition.xInteger,\n          mousePosition.yInteger,\n          mousePosition.xMod,\n          mousePosition.yMod,\n        )\n\n        return {\n          isDropOnCanvas: true,\n        }\n      },\n      collect: (monitor) => {\n        return {\n          isOver: monitor.isOver({ shallow: true }),\n        }\n      },\n    }),\n    [\n      isEditMode,\n      unitWidth,\n      fixedBounds,\n      scrollContainerScrollTop,\n      displayName,\n      containerListMapChildName,\n    ],\n  )\n\n  const autoScrollTimeID = useRef<number>(0)\n\n  setScrollBarContainerController(displayName, scrollContainerRef)\n\n  useEffect(() => {\n    return () => {\n      removeScrollBarContainerControllerByDisplayName(displayName)\n    }\n  }, [displayName])\n\n  useEffect(() => {\n    const scrollContainer = scrollContainerRef.current\n    if (!scrollContainer) return\n    const autoScroll = (e: MouseEvent) => {\n      if (\n        (!collectedProps.isOver &&\n          scrollContainer.dataset.isDraggingOver !== \"true\") ||\n        !scrollContainer ||\n        !isRootCanvas\n      ) {\n        return\n      }\n      const { top, bottom } = scrollContainer.getBoundingClientRect()\n      const { clientY } = e\n      window.clearInterval(autoScrollTimeID.current)\n      autoScrollTimeID.current = window.setInterval(() => {\n        if (clientY < top + UNIT_HEIGHT * safeRowNumber) {\n          scrollContainer!.scrollBy({\n            top: -8,\n          })\n        }\n        if (clientY > bottom - UNIT_HEIGHT * safeRowNumber) {\n          scrollContainer!.scrollBy({\n            top: 8,\n          })\n        }\n      }, 160)\n    }\n    scrollContainer?.addEventListener(\"mousemove\", autoScroll)\n    return () => {\n      if (scrollContainer) {\n        scrollContainer?.removeEventListener(\"mousemove\", autoScroll)\n      }\n      window.clearInterval(autoScrollTimeID.current)\n    }\n  }, [collectedProps.isOver, isResizingGlobal, isRootCanvas, safeRowNumber])\n\n  const isDraggingOver =\n    scrollContainerRef.current?.dataset.isDraggingOver === \"true\"\n\n  const prevMaxHeight = useRef<number>(0)\n  const maxHeight = Math.max(\n    ...childWidgetLayoutInfo.map(\n      (item) => item.layoutInfo.y + item.layoutInfo.h,\n    ),\n  )\n  useEffect(() => {\n    if (\n      isDraggingOver &&\n      isFinite(maxHeight) &&\n      maxHeight > prevMaxHeight.current\n    ) {\n      prevMaxHeight.current = maxHeight\n    }\n\n    if (!isDraggingOver) {\n      prevMaxHeight.current = maxHeight\n    }\n  }, [isDraggingOver, maxHeight])\n\n  useEffect(() => {\n    const innerCanvasDOM = innerCanvasRef.current\n    if (!innerCanvasDOM) return\n    const innerCanvasDOMRect = innerCanvasDOM.getBoundingClientRect()\n\n    if (\n      isFinite(maxHeight) &&\n      prevMaxHeight.current > maxHeight &&\n      isResizingGlobal\n    ) {\n      return\n    }\n\n    if (canResizeCanvas) {\n      if (isFinite(maxHeight)) {\n        setCanvasHeight(maxHeight * UNIT_HEIGHT)\n      } else {\n        setCanvasHeight(minHeight as number)\n      }\n      return\n    }\n\n    if (maxHeight * UNIT_HEIGHT < fixedBounds.height) {\n      setCanvasHeight(fixedBounds.height)\n      return\n    }\n\n    if (\n      maxHeight * UNIT_HEIGHT >=\n      innerCanvasDOMRect.height - UNIT_HEIGHT * ADD_ROWS\n    ) {\n      if (isEditMode && isRootCanvas) {\n        setCanvasHeight(maxHeight * UNIT_HEIGHT + UNIT_HEIGHT * ADD_ROWS)\n      } else {\n        setCanvasHeight(maxHeight * UNIT_HEIGHT)\n      }\n      return\n    }\n\n    setCanvasHeight(maxHeight * UNIT_HEIGHT)\n  }, [\n    canResizeCanvas,\n    fixedBounds.height,\n    isEditMode,\n    isResizingGlobal,\n    isRootCanvas,\n    maxHeight,\n    minHeight,\n  ])\n\n  useEffect(() => {\n    if (firstDragRef.current && isDraggingGlobal) {\n      firstDragRef.current = false\n      dragStartScrollTop.current = scrollContainerScrollTop\n      return\n    }\n    if (!isDraggingGlobal) {\n      firstDragRef.current = true\n      dragStartScrollTop.current = scrollContainerScrollTop\n    }\n  }, [isDraggingGlobal, scrollContainerScrollTop])\n\n  const canvasUpdateHeightHandler = useCallback(\n    (height: number) => {\n      if (!handleUpdateHeight) return\n      handleUpdateHeight(\n        height +\n          SCROLL_CONTAINER_PADDING * 2 +\n          paddings.paddingTop +\n          paddings.paddingBottom,\n      )\n    },\n    [handleUpdateHeight, paddings.paddingBottom, paddings.paddingTop],\n  )\n\n  useAutoUpdateCanvasHeight(\n    canvasUpdateHeightHandler,\n    innerCanvasRef.current,\n    canResizeCanvas,\n  )\n\n  const { cursorPositionRef } = useMousePositionAsync(\n    scrollContainerRef,\n    unitWidth,\n    displayName,\n    isRootCanvas,\n    scrollContainerRef,\n  )\n\n  const handleClickOnCanvas: MouseEventHandler<HTMLDivElement> = useCallback(\n    (event) => {\n      if (selectedComponents.length > 1) {\n        // calc group position\n        let leftTopX = Number.MAX_SAFE_INTEGER\n        let leftTopY = Number.MAX_SAFE_INTEGER\n        let maxRightBottomX = Number.MIN_SAFE_INTEGER\n        let maxRightBottomY = Number.MIN_SAFE_INTEGER\n\n        selectedComponents.forEach((nodeName) => {\n          const node = searchDSLByDisplayName(nodeName)\n          if (node) {\n            leftTopX = Math.min(leftTopX, node.x)\n            leftTopY = Math.min(leftTopY, node.y)\n            maxRightBottomX = Math.max(maxRightBottomX, node.x + node.w)\n            maxRightBottomY = Math.max(maxRightBottomY, node.y + node.h)\n          }\n        })\n        FocusManager.switchFocus(\"canvas\", {\n          displayName: displayName,\n          type: \"group\",\n          // x, y, w, h\n          clickPosition: [\n            leftTopX,\n            leftTopY,\n            maxRightBottomX - leftTopX,\n            maxRightBottomY - leftTopY,\n          ],\n        })\n      } else {\n        FocusManager.switchFocus(\"canvas\", {\n          displayName: displayName,\n          type: \"inner_container\",\n          clickPosition: getMousePointerPosition(\n            event.clientX - event.currentTarget.getBoundingClientRect().x,\n            event.clientY - event.currentTarget.getBoundingClientRect().y,\n            unitWidth,\n            UNIT_HEIGHT,\n            columnNumber,\n          ),\n        })\n      }\n    },\n    [columnNumber, displayName, selectedComponents, unitWidth],\n  )\n\n  useResizingUpdateRealTime(isDraggingOver)\n\n  return (\n    <div\n      css={outerComponentCanvasContainerStyle(\n        containerPadding,\n        background,\n        shadowSize,\n      )}\n      data-outer-canvas-container={displayName}\n      ref={canvasRef}\n    >\n      <div\n        css={componentCanvasContainerStyle}\n        ref={scrollContainerRef}\n        data-scroll-container={displayName}\n        data-column-number={columnNumber}\n        data-unit-width={unitWidth}\n        data-is-dragging-over={false}\n        className=\"scroll-container\"\n      >\n        <div\n          ref={(node) => {\n            dropRef(node)\n            innerCanvasRef.current = node\n          }}\n          css={dropZoneStyle(canvasHeight)}\n          onClick={handleClickOnCanvas}\n        >\n          <div\n            css={[\n              applyComponentCanvasStyle(unitWidth, canShowDot),\n              selectoSelectionStyle,\n            ]}\n            onClick={handleClickOnCanvas}\n            data-isroot={isRootCanvas}\n            data-canvas-container={displayName}\n            data-column-number={columnNumber}\n            data-unit-width={unitWidth}\n            data-list-widget-container\n          >\n            {isEditMode && (\n              <DragShadowPreview\n                unitW={unitWidth}\n                parentDisplayName={displayName}\n                columns={columnNumber}\n              />\n            )}\n            {isEditMode && (\n              <MousePreview unitW={unitWidth} displayName={displayName} />\n            )}\n            {currentLayoutInfo?.childrenNode?.length > 0 ? (\n              currentLayoutInfo?.childrenNode?.map((childName) => {\n                return (\n                  <ComponentParser\n                    key={`${displayName}-${childName}`}\n                    displayName={childName}\n                    unitW={unitWidth}\n                    parentNodeDisplayName={displayName}\n                    columnNumber={columnNumber}\n                  />\n                )\n              })\n            ) : isRootCanvas ? null : (\n              <ContainerEmptyState\n                isInner\n                containerPadding={containerPadding}\n              />\n            )}\n            {collectedProps.isOver && isEditMode && (\n              <DragPreview\n                unitW={unitWidth}\n                parentNodeDisplayName={displayName}\n                columnNumber={columnNumber}\n              />\n            )}\n            {!isLikeProductMode && isRootCanvas && (\n              <MultiSelectCanvas\n                scrollContainerRef={scrollContainerRef}\n                canvasNodeDisplayName={displayName}\n              />\n            )}\n            {!isDraggingGlobal && !isLikeProductMode && (\n              <MultiSelectedScaleSquare\n                unitW={unitWidth}\n                containerDisplayName={displayName}\n              />\n            )}\n          </div>\n        </div>\n      </div>\n      {canShowDot && <div css={containerShapeStyle(containerPadding)} />}\n    </div>\n  )\n}\n\nRenderComponentCanvasContainer.displayName = \"RenderComponentCanvasContainer\"\nexport default memo(RenderComponentCanvasContainer)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Canvas/renderComponentCanvasContainerWithJson.tsx",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { FC, ReactNode, useMemo } from \"react\"\nimport useMeasure from \"react-use-measure\"\nimport { DEFAULT_BODY_COLUMNS_NUMBER } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport ScaleSquareWithJSON from \"@/page/App/components/ScaleSquare/scaleSquareWithJSON\"\nimport { outerComponentCanvasContainerWithJsonStyle } from \"./style\"\n\nexport const RenderComponentCanvasWithJson: FC<{\n  componentNode: ComponentTreeNode\n  containerPadding: number\n  columnNumber?: number\n  canAutoScroll?: boolean\n  displayNamePrefix?: string\n}> = (props) => {\n  const {\n    componentNode,\n    columnNumber = DEFAULT_BODY_COLUMNS_NUMBER,\n    displayNamePrefix,\n    containerPadding,\n  } = props\n\n  const [canvasRef, bounds] = useMeasure()\n\n  const unitWidth = useMemo(() => {\n    return bounds.width / columnNumber\n  }, [columnNumber, bounds.width])\n\n  const componentTree = useMemo<ReactNode>(() => {\n    const childrenNode = componentNode.childrenNode\n    return childrenNode?.map<ReactNode>((item) => {\n      switch (item.containerType) {\n        case \"EDITOR_SCALE_SQUARE\":\n          return (\n            <ScaleSquareWithJSON\n              key={item.displayName}\n              componentNode={item}\n              unitW={unitWidth}\n              columnNumber={columnNumber}\n              displayNamePrefix={displayNamePrefix}\n            />\n          )\n        default:\n          return null\n      }\n    })\n  }, [columnNumber, componentNode.childrenNode, displayNamePrefix, unitWidth])\n\n  return (\n    <div\n      css={outerComponentCanvasContainerWithJsonStyle(containerPadding)}\n      ref={canvasRef}\n      data-list-widget-container\n    >\n      {componentTree}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Canvas/renderModalCanvasContainer.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport useMeasure from \"react-use-measure\"\nimport ComponentParser from \"@/page/App/components/DotPanel/components/ComponentParser\"\nimport { DEFAULT_BODY_COLUMNS_NUMBER } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { RenderComponentCanvasContainerProps } from \"./interface\"\nimport { maskStyle, outerModalCanvasContainerStyle } from \"./style\"\n\nexport const RenderModalCanvasContainer: FC<\n  RenderComponentCanvasContainerProps\n> = (props) => {\n  const {\n    columnNumber = DEFAULT_BODY_COLUMNS_NUMBER,\n    displayName,\n    containerPadding,\n  } = props\n\n  const executionResult = useSelector(getExecutionResult)\n\n  const dispatch = useDispatch()\n\n  const [canvasRef, bounds] = useMeasure()\n\n  const unitWidth = bounds.width / columnNumber\n\n  const layoutInfos = useSelector(getClientWidgetLayoutInfo)\n\n  const currentLayoutInfo = layoutInfos[displayName]\n\n  const currentModalDisplayName = currentLayoutInfo.childrenNode?.find(\n    (childName) => {\n      const childNode = executionResult[childName]\n      return childNode?.isVisible\n    },\n  )\n\n  const currentModal = executionResult[currentModalDisplayName ?? \"\"] ?? {}\n\n  const onClickMaskToClose = useCallback(() => {\n    if (currentModal?.clickMaskClose && currentModalDisplayName) {\n      dispatch(\n        executionActions.updateModalDisplayReducer({\n          display: false,\n          displayName: currentModalDisplayName,\n        }),\n      )\n    }\n  }, [currentModal?.clickMaskClose, currentModalDisplayName, dispatch])\n\n  if (!currentModal?.isVisible) {\n    return null\n  }\n\n  return (\n    <div\n      css={outerModalCanvasContainerStyle(containerPadding)}\n      ref={canvasRef}\n      onClick={onClickMaskToClose}\n    >\n      {currentModal && (\n        <ComponentParser\n          key={`${displayName}-${currentModal.displayName}}`}\n          displayName={currentModal.displayName}\n          unitW={unitWidth}\n          parentNodeDisplayName={displayName}\n          columnNumber={columnNumber}\n        />\n      )}\n      <div css={maskStyle} />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Canvas/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport {\n  BORDER_WIDTH,\n  SCROLL_CONTAINER_PADDING,\n  UNIT_HEIGHT,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getPaddingShape } from \"@/utils/styleUtils/padding\"\nimport { getShadowStyle } from \"@/utils/styleUtils/shadow\"\n\nexport const outerComponentCanvasContainerStyle = (\n  padding: string,\n  background: string = \"transparent\",\n  shadowSize: \"none\" | \"small\" | \"medium\" | \"large\",\n  dividerColor?: string,\n) => {\n  const { paddingTop, paddingBottom, paddingLeft, paddingRight } =\n    getPaddingShape(padding)\n  return css`\n    height: 100%;\n    width: 100%;\n    padding: ${paddingTop}px ${paddingRight}px ${paddingBottom}px\n      ${paddingLeft}px;\n    position: relative;\n    overflow: hidden;\n    background: ${background};\n    box-shadow: ${getShadowStyle(shadowSize)};\n    border: ${dividerColor ? `1px solid ${dividerColor}` : \"unset\"};\n  `\n}\n\nexport const outerModalCanvasContainerStyle = (padding: string) => {\n  const { paddingTop, paddingBottom, paddingLeft, paddingRight } =\n    getPaddingShape(padding)\n  return css`\n    height: 100%;\n    width: 100%;\n    padding: ${paddingTop}px ${paddingRight}px ${paddingBottom}px\n      ${paddingLeft}px;\n    position: relative;\n    overflow: hidden;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n  `\n}\n\nexport const outerComponentCanvasContainerWithJsonStyle = (\n  padding: number,\n) => css`\n  height: 100%;\n  width: 100%;\n  padding: ${padding}px;\n  position: relative;\n  overflow: hidden auto;\n`\n\nexport const componentCanvasContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  position: relative;\n  padding: ${SCROLL_CONTAINER_PADDING}px;\n  overflow: hidden auto;\n`\n\nexport const containerShapeStyle = (padding: string) => {\n  const { paddingTop, paddingBottom, paddingLeft, paddingRight } =\n    getPaddingShape(padding)\n  return css`\n    top: ${paddingTop}px;\n    bottom: ${paddingBottom}px;\n    left: ${paddingLeft}px;\n    right: ${paddingRight}px;\n    position: absolute;\n    border: ${BORDER_WIDTH}px solid ${getColor(\"grayBlue\", \"09\")};\n    pointer-events: none;\n  `\n}\n\nexport const dropZoneStyle = (canvasHeight?: number) => css`\n  width: 100%;\n  height: ${canvasHeight ? `${canvasHeight}px` : \"130vh\"};\n`\n\nexport const applyComponentCanvasStyle = (\n  unitWidth: number,\n  showDot: boolean = false,\n) => {\n  return css`\n    width: 100%;\n    height: 100%;\n    ${showDot\n      ? applyDotBackgroundStyle(unitWidth)\n      : normalCanvasBackgroundStyle}\n    position: relative;\n  `\n}\n\nconst normalCanvasBackgroundStyle = css`\n  background: unset;\n`\n\nconst applyDotBackgroundStyle = (unitWidth: number) => {\n  return css`\n    background-image: radial-gradient(\n      circle at 1px 1px,\n      ${getColor(\"grayBlue\", \"08\")} 1px,\n      transparent 0px\n    );\n    background-repeat: repeat;\n    background-size: ${unitWidth}px ${UNIT_HEIGHT}px;\n  `\n}\n\nexport const selectoSelectionStyle = css`\n  > .selecto-selection {\n    position: absolute !important;\n    transform: translate(\n      var(--illa-select-area-left, 0),\n      var(--illa-select-area-top, 0)\n    ) !important;\n    width: var(--illa-select-area-width, 0) !important;\n    height: var(--illa-select-area-height, 0) !important;\n    background: rgba(101, 74, 236, 0.08) !important;\n    border: 1px solid ${getColor(\"techPurple\", \"03\")} !important;\n  }\n`\n\nexport const maskStyle = css`\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background-color: ${getColor(\"blackAlpha\", \"04\")};\n  z-index: -1;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/ComponentParser/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport ScaleSquare from \"@/page/App/components/ScaleSquare\"\nimport { ModalScaleSquare } from \"@/page/App/components/ScaleSquare/modalScaleSquare\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { ComponentParserProps } from \"./interface\"\n\nconst ComponentParser: FC<ComponentParserProps> = (props) => {\n  const { displayName, unitW, parentNodeDisplayName, columnNumber } = props\n\n  const widgetLayoutInfo = useSelector(getClientWidgetLayoutInfo)\n  const currentWidgetLayoutInfo = widgetLayoutInfo[displayName]\n  const containerType = currentWidgetLayoutInfo.containerType\n  const widgetType = currentWidgetLayoutInfo.widgetType\n\n  switch (containerType) {\n    case \"EDITOR_SCALE_SQUARE\":\n      if (widgetType === \"MODAL_WIDGET\") {\n        return (\n          <ModalScaleSquare\n            displayName={displayName}\n            widgetType={widgetType}\n            unitW={unitW}\n            parentNodeDisplayName={parentNodeDisplayName}\n            columnNumber={columnNumber}\n          />\n        )\n      }\n\n      return (\n        <ScaleSquare\n          displayName={displayName}\n          widgetType={widgetType}\n          unitW={unitW}\n          parentNodeDisplayName={parentNodeDisplayName}\n          columnNumber={columnNumber}\n        />\n      )\n\n    default:\n      return null\n  }\n}\n\nComponentParser.displayName = \"ComponentParser\"\n\nexport default memo(ComponentParser)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/ComponentParser/interface.ts",
    "content": "export interface ComponentParserProps {\n  displayName: string\n  unitW: number\n  parentNodeDisplayName: string\n  columnNumber: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/DragPreview/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { useDragLayer } from \"react-dnd\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getDragPreview } from \"@/page/App/components/DotPanel/utils/getDragShadow\"\nimport { DragInfo } from \"@/page/App/components/ScaleSquare/components/DragContainer/interface\"\nimport { DragCollectedProps, DragPreviewProps } from \"./interface\"\nimport { dragPreviewStyle } from \"./style\"\n\nconst DragPreview: FC<DragPreviewProps> = (props) => {\n  const { unitW, parentNodeDisplayName, columnNumber } = props\n\n  const collectedProps = useDragLayer<DragCollectedProps, DragInfo>(\n    (monitor) => {\n      return {\n        isDragging: monitor.isDragging(),\n        item: monitor.getItem(),\n        clientOffset: monitor.getClientOffset(),\n        differenceFromInitialOffset: monitor.getDifferenceFromInitialOffset(),\n        initialClientOffset: monitor.getInitialClientOffset(),\n        initialSourceClientOffset: monitor.getInitialSourceClientOffset(),\n      }\n    },\n  )\n\n  const mousePositionInfo = getDragPreview(\n    parentNodeDisplayName,\n    unitW,\n    collectedProps,\n    columnNumber,\n  )\n\n  if (!mousePositionInfo) return null\n  const { shape, canDrop } = mousePositionInfo\n  return (\n    <div\n      css={dragPreviewStyle(\n        shape.y * UNIT_HEIGHT,\n        shape.x * unitW,\n        shape.w * unitW,\n        shape.previewH * UNIT_HEIGHT,\n        canDrop,\n      )}\n    />\n  )\n}\n\nexport default memo(DragPreview)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/DragPreview/interface.ts",
    "content": "import { XYCoord } from \"react-dnd\"\nimport { DragInfo } from \"@/page/App/components/ScaleSquare/components/DragContainer/interface\"\n\nexport interface DragPreviewProps {\n  unitW: number\n  parentNodeDisplayName: string\n  columnNumber: number\n}\n\nexport interface DragCollectedProps {\n  isDragging: boolean\n  item: DragInfo\n  clientOffset: XYCoord | null\n  differenceFromInitialOffset: XYCoord | null\n  initialClientOffset: XYCoord | null\n  initialSourceClientOffset: XYCoord | null\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/DragPreview/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const dragPreviewStyle = (\n  top: number,\n  left: number,\n  width: number,\n  height: number,\n  canDrop: boolean,\n) => css`\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: ${width}px;\n  height: ${height}px;\n  transform: translate(${left}px, ${top - 1}px);\n  background-color: ${canDrop\n    ? `rgba(101, 74, 236, 0.1)`\n    : `rgba(255, 71, 71, 0.1)`};\n  border-top: 3px solid\n    ${canDrop ? getColor(\"techPurple\", \"03\") : getColor(\"red\", \"03\")};\n  z-index: 10;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/DragShadowPreview/Shadow/index.tsx",
    "content": "import { motion } from \"framer-motion\"\nimport { FC, useCallback } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { FixedCursor } from \"@/page/App/components/DotPanel/components/MousePreview/Cursor\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { dragShadowActions } from \"@/redux/currentApp/dragShadow/dragShadowSlice\"\nimport { dotLintRectangleStyle, rectangleStyle } from \"./style\"\nimport { fixedPosition } from \"./utils\"\n\ninterface DragShadowPreviewProps {\n  x: number\n  y: number\n  landingX: number\n  landingY: number\n  unitW: number\n  status: number\n  parentDisplayName: string\n  displayNames: string\n  userID: string\n  columns: number\n  nickname: string\n  integerPartX: number\n  integerPartY: number\n  decimalPartX: number\n  decimalPartY: number\n}\n\nexport const ShadowPreview: FC<DragShadowPreviewProps> = (props) => {\n  const {\n    x,\n    y,\n    landingX,\n    landingY,\n    status,\n    userID,\n    unitW,\n    columns,\n    nickname,\n    integerPartX,\n    integerPartY,\n    decimalPartX,\n    decimalPartY,\n  } = props\n\n  const dispatch = useDispatch()\n\n  const onAnimationComplete = useCallback(() => {\n    if (status === -1) {\n      dispatch(dragShadowActions.deleteDragShadowInfoReducer(userID))\n    } else {\n      dispatch(\n        dragShadowActions.removeAnimationEndDragShadowInfoReducer(userID),\n      )\n    }\n  }, [dispatch, status, userID])\n\n  const fixedXAndY = fixedPosition(x, y, landingX, columns)\n\n  return (\n    <>\n      <motion.div\n        css={dotLintRectangleStyle}\n        initial={{\n          x: fixedXAndY.x * unitW,\n          y: fixedXAndY.y * UNIT_HEIGHT,\n          width: landingX * unitW,\n          height: landingY * UNIT_HEIGHT,\n        }}\n        animate={{\n          x: fixedXAndY.x * unitW,\n          y: fixedXAndY.y * UNIT_HEIGHT,\n          width: landingX * unitW,\n          height: landingY * UNIT_HEIGHT,\n        }}\n        transition={{ duration: 0.16 }}\n        onAnimationComplete={onAnimationComplete}\n      >\n        <div css={rectangleStyle} />\n        {status !== 2 && (\n          <FixedCursor\n            userID={userID}\n            nickName={nickname}\n            integerPartX={integerPartX}\n            integerPartY={integerPartY}\n            decimalPartX={decimalPartX}\n            decimalPartY={decimalPartY}\n            status={status}\n            unitW={unitW}\n          />\n        )}\n      </motion.div>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/DragShadowPreview/Shadow/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const dotLintRectangleStyle = css`\n  border: 1px dashed ${getColor(\"techPurple\", \"03\")};\n  position: absolute;\n  z-index: 6;\n  pointer-events: none;\n`\n\nexport const applyResizingDotLintRectangleStyle = (\n  w: number,\n  h: number,\n  x: number,\n  y: number,\n) => {\n  return css`\n    width: ${w}px;\n    height: ${h}px;\n    top: 0;\n    left: 0;\n    transform: translate(${x}px, ${y}px);\n    border: 1px dashed ${getColor(\"techPurple\", \"03\")};\n    position: absolute;\n    z-index: 6;\n    pointer-events: none;\n  `\n}\n\nexport const rectangleStyle = css`\n  width: 100%;\n  height: 100%;\n  background-color: ${getColor(\"techPurple\", \"03\")};\n  opacity: 0.16;\n  pointer-events: none;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/DragShadowPreview/Shadow/utils.ts",
    "content": "export const fixedPosition = (\n  x: number,\n  y: number,\n  width: number,\n  columns: number,\n) => {\n  return {\n    x: x < 0 ? 0 : x + width > columns ? columns - width : x,\n    y: y < 0 ? 0 : y,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/DragShadowPreview/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getDragShadowInfoArray } from \"@/redux/currentApp/dragShadow/dragShadowSelector\"\nimport { ShadowPreview } from \"./Shadow\"\nimport { DragShadowPreviewProps } from \"./interface\"\n\nexport const DragShadowPreview: FC<DragShadowPreviewProps> = (props) => {\n  const { unitW, parentDisplayName, columns } = props\n\n  const dragShadowInfoArray = useSelector(getDragShadowInfoArray)\n\n  return (\n    <>\n      {dragShadowInfoArray.map((item) => {\n        const currentItem = item[0]\n        return (\n          currentItem?.parentDisplayName === parentDisplayName && (\n            <ShadowPreview\n              key={currentItem.userID}\n              x={currentItem.rectX}\n              y={currentItem.rectY}\n              landingX={currentItem.rectW}\n              landingY={currentItem.rectH}\n              unitW={unitW}\n              displayNames={currentItem.displayNames}\n              userID={currentItem.userID}\n              status={currentItem.status}\n              parentDisplayName={currentItem.parentDisplayName}\n              columns={columns}\n              integerPartX={currentItem.xInteger}\n              integerPartY={currentItem.yInteger}\n              decimalPartX={currentItem.xMod}\n              decimalPartY={currentItem.yMod}\n              nickname={currentItem.nickname}\n            />\n          )\n        )\n      })}\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/DragShadowPreview/interface.ts",
    "content": "export interface DragShadowPreviewProps {\n  unitW: number\n  parentDisplayName: string\n  columns: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/MousePreview/Cursor/index.tsx",
    "content": "import { getColorByString } from \"@illa-public/utils\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { FC, useCallback, useEffect } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch } from \"react-redux\"\nimport CursorIcon from \"@/assets/public/cursor.svg?react\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { cursorActions } from \"@/redux/currentApp/cursor/cursorSlice\"\nimport { CursorProps, NickNameContainerProps } from \"./interface\"\nimport { applyCursorContainerStyle, nickNameContainerStyle } from \"./style\"\n\nexport const Cursor: FC<CursorProps> = (props) => {\n  const {\n    userID,\n    nickName,\n    integerPartX,\n    integerPartY,\n    decimalPartX,\n    decimalPartY,\n    unitW,\n    status,\n  } = props\n\n  const realX = (integerPartX + decimalPartX) * unitW\n  const realY = integerPartY + decimalPartY\n  const color = getColorByString(userID)\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n\n  const onAnimationComplete = useCallback(() => {\n    dispatch(cursorActions.removeAnimationEndCursorInfo(userID))\n  }, [dispatch, userID])\n  const isLeave = status === -1\n\n  useEffect(() => {\n    if (isLeave) {\n      dispatch(cursorActions.leaveContainerReducer(userID))\n    }\n  }, [dispatch, isLeave, userID])\n\n  return (\n    <AnimatePresence>\n      <motion.span\n        css={applyCursorContainerStyle(color)}\n        initial={{ x: realX - 6, y: realY - 8.5 }}\n        animate={{ x: realX - 6, y: realY - 8.5 }}\n        transition={{ duration: 0.16 }}\n        onAnimationComplete={onAnimationComplete}\n      >\n        <CursorIcon />\n        <NickNameContainer\n          nickName={\n            nickName?.trim() !== \"\"\n              ? nickName\n              : t(\"widget.collaborative.no_name\")\n          }\n          bgColor={color}\n        />\n      </motion.span>\n    </AnimatePresence>\n  )\n}\n\nexport const NickNameContainer: FC<NickNameContainerProps> = (props) => {\n  const { nickName, bgColor } = props\n  return <div css={nickNameContainerStyle(bgColor)}>{nickName}</div>\n}\n\nexport const FixedCursor: FC<CursorProps> = (props) => {\n  const {\n    userID,\n    nickName,\n    integerPartX,\n    integerPartY,\n    decimalPartX,\n    decimalPartY,\n    unitW,\n  } = props\n\n  const realX = (integerPartX + decimalPartX) * unitW\n  const realY = (integerPartY + decimalPartY) * UNIT_HEIGHT\n  const color = getColorByString(userID)\n  const { t } = useTranslation()\n\n  return (\n    <AnimatePresence>\n      <motion.span\n        css={applyCursorContainerStyle(color)}\n        initial={{ x: realX, y: realY }}\n        animate={{ x: realX, y: realY }}\n        transition={{ duration: 0.16 }}\n      >\n        <CursorIcon />\n        <NickNameContainer\n          nickName={\n            nickName?.trim() !== \"\"\n              ? nickName\n              : t(\"widget.collaborative.no_name\")\n          }\n          bgColor={color}\n        />\n      </motion.span>\n    </AnimatePresence>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/MousePreview/Cursor/interface.ts",
    "content": "export interface NickNameContainerProps {\n  bgColor: string\n  nickName: string\n}\n\nexport interface CursorProps {\n  userID: string\n  nickName: string\n  integerPartX: number\n  integerPartY: number\n  decimalPartX: number\n  decimalPartY: number\n  status: number\n  unitW: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/MousePreview/Cursor/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const nickNameContainerStyle = (bgColor: string) => css`\n  min-width: 32px;\n  max-width: 102px;\n  padding: 4px 8px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  background-color: ${bgColor};\n  border: 1px solid ${getColor(\"white\", \"01\")};\n  border-radius: 4px;\n  color: ${getColor(\"white\", \"01\")};\n  font-size: 12px;\n  font-weight: 500;\n`\n\nexport const applyCursorContainerStyle = (color: string) => css`\n  color: ${color};\n  z-index: 10;\n  position: absolute;\n  user-select: none;\n  pointer-events: none;\n  top: 0;\n  left: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/MousePreview/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getCursorArray } from \"@/redux/currentApp/cursor/cursorSelector\"\nimport { Cursor } from \"./Cursor\"\nimport { MousePreviewProps } from \"./interface\"\n\nexport const MousePreview: FC<MousePreviewProps> = (props) => {\n  const { unitW, displayName } = props\n\n  const cursorArray = useSelector(getCursorArray)\n\n  return (\n    <>\n      {cursorArray.map((item) => {\n        const currentItem = item[0]\n        return (\n          currentItem?.parentDisplayName === displayName && (\n            <Cursor\n              key={currentItem.userID}\n              nickName={currentItem.nickname}\n              userID={currentItem.userID}\n              decimalPartX={currentItem.xMod}\n              decimalPartY={currentItem.yMod}\n              integerPartX={currentItem.xInteger}\n              integerPartY={currentItem.yInteger}\n              status={currentItem.status}\n              unitW={unitW}\n            />\n          )\n        )\n      })}\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/MousePreview/interface.ts",
    "content": "export interface MousePreviewProps {\n  unitW: number\n  displayName: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/MultiSelectCanvas/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { getOverlapPoints } from \"overlap-area\"\nimport { FC, useEffect, useRef } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport Selecto, { OnDragStart, SelectoEvents } from \"react-selecto\"\nimport {\n  getIsILLAProductMode,\n  getSelectedComponentDisplayNames,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { MultiSelectCanvasProps } from \"./interface\"\n\nconst transSelectableComponentPointsToIllAPosition = (\n  points: number[][],\n  scrollTop: number,\n  containerX: number,\n  containerY: number,\n) => {\n  const left = points[0][0]\n  const top = points[0][1]\n  const right = points[1][0]\n  const bottom = points[2][1]\n  return [\n    [left - containerX, top - containerY + scrollTop],\n    [right - containerX, top - containerY + scrollTop],\n    [right - containerX, bottom - containerY + scrollTop],\n    [left - containerX, bottom - containerY + scrollTop],\n  ]\n}\n\nexport const MultiSelectCanvas: FC<MultiSelectCanvasProps> = (props) => {\n  const { scrollContainerRef, canvasNodeDisplayName } = props\n  const containerClientRect =\n    scrollContainerRef.current?.getBoundingClientRect()\n\n  const selectStartPositionRef = useRef([0, 0])\n  const prevSelectedComponent = useRef<string[]>([])\n  const prevSelectorStatus = useRef(false)\n  const prevContainerScrollTop = useRef<number | undefined>(undefined)\n  const startScrollTop = useRef<number>(0)\n  const selectoRef = useRef<Selecto | null>(null)\n\n  const selectedComponents = useSelector(getSelectedComponentDisplayNames)\n  const isProductionMode = useSelector(getIsILLAProductMode)\n  const dispatch = useDispatch()\n\n  const onScrollHandler = (e: SelectoEvents[\"scroll\"]) => {\n    const { direction } = e\n    scrollContainerRef.current!.scrollBy(0, direction[1] * 10)\n  }\n\n  const dragConditionHandler = (e: OnDragStart<unknown>) => {\n    const triggerTarget = e.inputEvent.target\n    const isRoot = triggerTarget.getAttribute(\"data-isroot\")\n    return isRoot === \"true\"\n  }\n\n  const onDragStartHandler = (e: SelectoEvents[\"dragStart\"]) => {\n    const scrollTop = scrollContainerRef.current?.scrollTop ?? 0\n    const startX = e.clientX - (containerClientRect?.x ?? 0)\n    const startY = e.clientY - (containerClientRect?.y ?? 0) + scrollTop\n    prevContainerScrollTop.current = scrollTop\n    startScrollTop.current = scrollTop\n    let currentCanvasStyle: CSSStyleDeclaration | undefined =\n      scrollContainerRef.current?.style\n    selectStartPositionRef.current = [startX, startY]\n    currentCanvasStyle?.setProperty(\"--illa-select-area-left\", `${startX}px`)\n    currentCanvasStyle?.setProperty(\"--illa-select-area-top\", `${startY}px`)\n    prevSelectedComponent.current = selectedComponents\n  }\n\n  const onDraggingHandler = (e: SelectoEvents[\"drag\"]) => {\n    prevSelectorStatus.current = true\n    const { rect, distX, clientY } = e\n    let currentCanvasStyle: CSSStyleDeclaration | undefined =\n      scrollContainerRef.current?.style\n    const containerY = containerClientRect?.y ?? 0\n    const containerX = containerClientRect?.x ?? 0\n    const scrollTop = scrollContainerRef.current?.scrollTop ?? 0\n    const currentY = clientY - (containerClientRect?.y ?? 0) + scrollTop\n    const startAndDraggingDiff = currentY - selectStartPositionRef.current[1]\n    const dir = scrollTop - startScrollTop.current > 0 ? 1 : -1\n    const diff = scrollTop - startScrollTop.current!\n    const currentHeight =\n      Math.abs(currentY - selectStartPositionRef.current[1]) +\n      (dir === -1 ? -diff : 0)\n\n    let currentXOrigin = selectStartPositionRef.current[0]\n    let currentYOrigin = selectStartPositionRef.current[1]\n    if (distX < 0) {\n      currentXOrigin += distX\n    }\n    if (startAndDraggingDiff < 0) {\n      currentYOrigin = currentY\n    }\n    currentCanvasStyle?.setProperty(\n      \"--illa-select-area-left\",\n      `${currentXOrigin}px`,\n    )\n    currentCanvasStyle?.setProperty(\n      \"--illa-select-area-top\",\n      `${currentYOrigin}px`,\n    )\n    currentCanvasStyle?.setProperty(\n      \"--illa-select-area-width\",\n      `${rect.width}px`,\n    )\n    currentCanvasStyle?.setProperty(\n      \"--illa-select-area-height\",\n      `${currentHeight}px`,\n    )\n    const updatedSelectedComponents: string[] = []\n\n    const targets = e.currentTarget.getSelectableElements()\n    const rectPoints = [\n      // [left,top],[right,top],[right,bottom],[left,bottom]\n      [currentXOrigin, currentYOrigin],\n      [currentXOrigin + rect.width, currentYOrigin],\n      [currentXOrigin + rect.width, currentYOrigin + currentHeight],\n      [currentXOrigin, currentYOrigin + currentHeight],\n    ]\n    targets.forEach((target) => {\n      const targetOriginPoints = e.currentTarget.getElementPoints(target)\n      const targetPoints = transSelectableComponentPointsToIllAPosition(\n        targetOriginPoints,\n        scrollTop,\n        containerX,\n        containerY,\n      )\n      const points = getOverlapPoints(targetPoints, rectPoints)\n      if (points.length > 0) {\n        const displayName = target.getAttribute(\"data-displayname\")\n\n        if (displayName) {\n          updatedSelectedComponents.push(displayName)\n        }\n      }\n    })\n    let isEqual = false\n    if (\n      updatedSelectedComponents.length === prevSelectedComponent.current.length\n    ) {\n      isEqual = updatedSelectedComponents.every(\n        (value, index) => value === prevSelectedComponent.current[index],\n      )\n    }\n    if (!isEqual) {\n      prevSelectedComponent.current = updatedSelectedComponents\n      dispatch(configActions.updateSelectedComponent(updatedSelectedComponents))\n    }\n  }\n\n  const onDragEndHandler = () => {\n    if (\n      !prevSelectorStatus.current &&\n      !isProductionMode &&\n      selectedComponents.length > 0\n    ) {\n      dispatch(configActions.updateSelectedComponent([]))\n    } else {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SELECT, {\n        element: \"component\",\n        parameter1: \"drag\",\n      })\n    }\n    prevSelectorStatus.current = false\n    prevContainerScrollTop.current = undefined\n    startScrollTop.current = 0\n  }\n\n  useEffect(() => {\n    const containerRefValue = scrollContainerRef.current\n    if (!containerRefValue || !selectoRef.current) return\n\n    const scrollHandler = () => {\n      if (!prevSelectorStatus.current) return\n      selectoRef.current?.checkScroll()\n    }\n    containerRefValue.addEventListener(\"scroll\", scrollHandler)\n\n    return () => {\n      containerRefValue?.removeEventListener(\"scroll\", scrollHandler)\n    }\n  }, [\n    containerClientRect?.x,\n    containerClientRect?.y,\n    scrollContainerRef,\n    dispatch,\n  ])\n\n  return (\n    <Selecto\n      ref={selectoRef}\n      container={scrollContainerRef.current}\n      dragContainer={scrollContainerRef.current as Element}\n      selectableTargets={[`div[data-parentnode='${canvasNodeDisplayName}']`]}\n      onScroll={onScrollHandler}\n      scrollOptions={{\n        container: scrollContainerRef.current!,\n        getScrollPosition: () => {\n          return [\n            scrollContainerRef.current!.scrollLeft,\n            scrollContainerRef.current!.scrollTop,\n          ]\n        },\n        throttleTime: 30,\n        threshold: 0,\n      }}\n      dragCondition={dragConditionHandler}\n      onDragStart={onDragStartHandler}\n      onDrag={onDraggingHandler}\n      onDragEnd={onDragEndHandler}\n    />\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/MultiSelectCanvas/interface.ts",
    "content": "import { RefObject } from \"react\"\n\nexport interface MultiSelectCanvasProps {\n  scrollContainerRef: RefObject<HTMLDivElement>\n  canvasNodeDisplayName: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/MultiSelectedContainer/index.tsx",
    "content": "import { FC, memo, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getLargeItemShapeWithNodeScale } from \"@/page/App/components/DotPanel/utils\"\nimport { getSelectedComponentDisplayNames } from \"@/redux/config/configSelector\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport {\n  MultiSelectedScaleSquareProps,\n  SelectedComponentWithShape,\n} from \"./interface\"\nimport { applyMultiSelectedScaleSquareStyle } from \"./style\"\n\nconst MultiSelectedScaleSquare: FC<MultiSelectedScaleSquareProps> = (props) => {\n  const { unitW, containerDisplayName } = props\n  const selectedComponents = useSelector(getSelectedComponentDisplayNames)\n  const widgetExecutionResult = useSelector(getClientWidgetLayoutInfo)\n  const selectedComponentsWithShape: SelectedComponentWithShape[] =\n    useMemo(() => {\n      let result: SelectedComponentWithShape[] = []\n      selectedComponents.forEach((componentDisplayName) => {\n        const currentItem = widgetExecutionResult[componentDisplayName]\n        if (!currentItem) return null\n        result.push({\n          ...widgetExecutionResult[componentDisplayName].layoutInfo,\n          parentNode: widgetExecutionResult[componentDisplayName].parentNode,\n        })\n      })\n      return result\n    }, [selectedComponents, widgetExecutionResult])\n\n  const isSameParentNode = selectedComponentsWithShape.every(\n    (node) => node.parentNode === containerDisplayName,\n  )\n\n  const scaleItem = getLargeItemShapeWithNodeScale(selectedComponentsWithShape)\n  if (selectedComponents.length <= 1 || !isSameParentNode) return null\n\n  return (\n    <div\n      css={applyMultiSelectedScaleSquareStyle(\n        scaleItem.w * unitW,\n        scaleItem.h * UNIT_HEIGHT,\n        scaleItem.x * unitW,\n        scaleItem.y * UNIT_HEIGHT,\n      )}\n    />\n  )\n}\n\nMultiSelectedScaleSquare.displayName = \"MultiSelectedScaleSquare\"\n\nexport default memo(MultiSelectedScaleSquare)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/MultiSelectedContainer/interface.ts",
    "content": "import { LayoutInfo } from \"@/redux/currentApp/components/componentsPayload\"\n\nexport interface MultiSelectedScaleSquareProps {\n  unitW: number\n  containerDisplayName: string\n}\n\nexport interface SelectedComponentWithShape extends LayoutInfo {\n  parentNode: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/MultiSelectedContainer/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const applyMultiSelectedScaleSquareStyle = (\n  width: number,\n  height: number,\n  left: number,\n  top: number,\n) => {\n  return css`\n    position: absolute;\n    border: 1px dashed ${getColor(\"techPurple\", \"03\")};\n    width: ${width}px;\n    height: ${height}px;\n    left: 0;\n    top: 0;\n    transform: translate(${left}px, ${top}px);\n    pointer-events: none;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Page/emptyState.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { emptyContainerStyle } from \"./style\"\n\nexport const EmptyState: FC = () => {\n  const { t } = useTranslation()\n  return <div css={emptyContainerStyle}>{t(\"widget.page.tips.blank_view\")}</div>\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Page/interface.ts",
    "content": "export interface RenderPageProps {\n  currentPageDisplayName: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Page/renderPage.tsx",
    "content": "import { SECTION_POSITION } from \"@illa-public/public-types\"\nimport {\n  FC,\n  useEffect,\n  useLayoutEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport useMeasure from \"react-use-measure\"\nimport {\n  DEFAULT_ASIDE_COLUMNS_NUMBER,\n  DEFAULT_BODY_COLUMNS_NUMBER,\n  LEFT_MIN_WIDTH,\n  RIGHT_MIN_WIDTH,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getCanvasShape, getIllaMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport {\n  getCurrentPageExecutionResult,\n  getPageLoadingActions,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport store from \"@/store\"\nimport {\n  IExecutionActions,\n  runActionWithDelay,\n  runActionWithExecutionResult,\n} from \"@/utils/action/runAction\"\nimport { PageLoading } from \"../PageLoading/pageLoading\"\nimport {\n  RenderBodySection,\n  RenderFooterSection,\n  RenderHeaderSection,\n  RenderLeftSection,\n  RenderModalSection,\n  RenderRightSection,\n} from \"../Section\"\nimport { RenderPageProps } from \"./interface\"\nimport {\n  applyCanvasContainerWrapperStyle,\n  pageContainerWrapperStyle,\n} from \"./style\"\n\nconst getLeftAndRightWidth = (\n  canvasSize: \"auto\" | \"fixed\",\n  width: number,\n  containerWidth: number,\n) => {\n  if (canvasSize === \"fixed\") {\n    return width\n  } else {\n    return (width / 100) * containerWidth\n  }\n}\n\nexport const RenderPage: FC<RenderPageProps> = (props) => {\n  const { currentPageDisplayName } = props\n  const containerWrapperRef = useRef<HTMLDivElement>(null)\n  const [containerRef, bounds] = useMeasure()\n  const canvasShape = useSelector(getCanvasShape)\n  const mode = useSelector(getIllaMode)\n  const dispatch = useDispatch()\n  const pageNode = useSelector(getCurrentPageExecutionResult)\n\n  const {\n    canvasSize,\n    canvasWidth,\n    hasLeft,\n    hasRight,\n    hasFooter,\n    hasHeader,\n    leftPosition,\n    rightPosition,\n    leftWidth,\n    rightWidth,\n    topHeight,\n    bottomHeight,\n    showLeftFoldIcon,\n    showRightFoldIcon,\n    leftColumns,\n    rightColumns,\n    headerColumns,\n    footerColumns,\n    bodyColumns,\n  } = pageNode\n\n  const [isLeftFold, setIsLeftFold] = useState(false)\n  const [isRightFold, setIsRightFold] = useState(false)\n\n  useLayoutEffect(() => {\n    if (\n      canvasShape.canvasHeight !== bounds.height ||\n      canvasShape.canvasWidth !== bounds.width\n    ) {\n      dispatch(\n        configActions.updateCanvasShapeReducer({\n          canvasHeight: bounds.height,\n          canvasWidth: bounds.width,\n        }),\n      )\n    }\n  }, [\n    bounds.height,\n    bounds.width,\n    canvasShape.canvasHeight,\n    canvasShape.canvasWidth,\n    dispatch,\n  ])\n  const realLeftWidth = useMemo(() => {\n    const leftWidthPX = getLeftAndRightWidth(\n      canvasSize,\n      leftWidth,\n      bounds.width,\n    )\n    return hasLeft\n      ? leftWidthPX <= LEFT_MIN_WIDTH\n        ? LEFT_MIN_WIDTH\n        : leftWidthPX\n      : 0\n  }, [bounds.width, canvasSize, hasLeft, leftWidth])\n\n  const realRightWidth = useMemo(() => {\n    const rightWidthPX = getLeftAndRightWidth(\n      canvasSize,\n      rightWidth,\n      bounds.width,\n    )\n    return hasRight\n      ? rightWidthPX <= RIGHT_MIN_WIDTH\n        ? RIGHT_MIN_WIDTH\n        : rightWidthPX\n      : 0\n  }, [bounds.width, canvasSize, hasRight, rightWidth])\n\n  const calcLeftWidth = useMemo(() => {\n    const leftWidthPX = getLeftAndRightWidth(\n      canvasSize,\n      leftWidth,\n      bounds.width,\n    )\n    return hasLeft\n      ? isLeftFold\n        ? 40\n        : leftWidthPX <= LEFT_MIN_WIDTH\n        ? LEFT_MIN_WIDTH\n        : leftWidthPX\n      : 0\n  }, [bounds.width, canvasSize, hasLeft, isLeftFold, leftWidth])\n\n  const calcRightWidth = useMemo(() => {\n    const rightWidthPX = getLeftAndRightWidth(\n      canvasSize,\n      rightWidth,\n      bounds.width,\n    )\n    return hasRight\n      ? isRightFold\n        ? 40\n        : rightWidthPX <= RIGHT_MIN_WIDTH\n        ? RIGHT_MIN_WIDTH\n        : rightWidthPX\n      : 0\n  }, [bounds.width, canvasSize, hasRight, isRightFold, rightWidth])\n\n  useLayoutEffect(() => {\n    if (bounds.width <= 0) return\n    let headerLeft = 0\n    let headerWidth = bounds.width\n    let leftTop = 0\n    let leftHeight = bounds.height\n    let rightTop = 0\n    let rightHeight = bounds.height\n    let footerLeft = 0\n    let footerWidth = bounds.width\n    let bodyWidth = bounds.width\n    let bodyTop = 0\n    let bodyLeft = 0\n    let bodyHeight = bounds.height\n    if (hasLeft) {\n      bodyWidth -= calcLeftWidth\n      bodyLeft = calcLeftWidth\n      switch (leftPosition) {\n        case SECTION_POSITION.TOP: {\n          headerLeft = calcLeftWidth\n          headerWidth -= calcLeftWidth\n          leftHeight -= bottomHeight\n          break\n        }\n        case SECTION_POSITION.FULL: {\n          headerLeft = calcLeftWidth\n          headerWidth -= calcLeftWidth\n          footerLeft = calcLeftWidth\n          footerWidth -= calcLeftWidth\n          break\n        }\n        case SECTION_POSITION.BOTTOM: {\n          footerLeft = calcLeftWidth\n          footerWidth -= calcLeftWidth\n          leftTop = topHeight\n          leftHeight -= topHeight\n          break\n        }\n        case SECTION_POSITION.CENTER: {\n          leftTop = topHeight\n          leftHeight = leftHeight - topHeight - bottomHeight\n        }\n      }\n    }\n\n    if (hasRight) {\n      bodyWidth -= calcRightWidth\n      switch (rightPosition) {\n        case SECTION_POSITION.TOP: {\n          headerWidth -= calcRightWidth\n          rightHeight -= bottomHeight\n          break\n        }\n        case SECTION_POSITION.FULL: {\n          headerWidth -= calcRightWidth\n          footerWidth -= calcRightWidth\n          break\n        }\n        case SECTION_POSITION.BOTTOM: {\n          footerWidth -= calcRightWidth\n          rightTop = topHeight\n          rightHeight -= topHeight\n          break\n        }\n        case SECTION_POSITION.CENTER: {\n          rightTop = topHeight\n          rightHeight = rightHeight - bottomHeight - topHeight\n        }\n      }\n    }\n    if (hasHeader) {\n      bodyTop = topHeight\n      bodyHeight -= topHeight\n    }\n\n    if (hasFooter) {\n      bodyHeight -= bottomHeight\n    }\n    let containerWrapperStyle: CSSStyleDeclaration | undefined =\n      containerWrapperRef.current?.style\n\n    if (hasLeft && containerWrapperStyle) {\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-left-height\",\n        `${leftHeight}px`,\n      )\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-left-top\",\n        `${leftTop}px`,\n      )\n    }\n    if (hasRight && containerWrapperStyle) {\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-right-height\",\n        `${rightHeight}px`,\n      )\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-right-top\",\n        `${rightTop}px`,\n      )\n    }\n    if (hasHeader && containerWrapperStyle) {\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-header-width\",\n        `${headerWidth}px`,\n      )\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-header-left\",\n        `${headerLeft}px`,\n      )\n    }\n    if (hasFooter && containerWrapperStyle) {\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-footer-width\",\n        `${footerWidth}px`,\n      )\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-footer-left\",\n        `${footerLeft}px`,\n      )\n    }\n\n    if (containerWrapperStyle) {\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-body-width\",\n        `${bodyWidth}px`,\n      )\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-body-left\",\n        `${bodyLeft}px`,\n      )\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-body-top\",\n        `${bodyTop}px`,\n      )\n      containerWrapperStyle.setProperty(\n        \"--illa-canvas-body-height\",\n        `${bodyHeight}px`,\n      )\n    }\n  }, [\n    bottomHeight,\n    bounds,\n    calcLeftWidth,\n    calcRightWidth,\n    canvasSize,\n    hasFooter,\n    hasHeader,\n    hasLeft,\n    hasRight,\n    leftPosition,\n    leftWidth,\n    realLeftWidth,\n    realRightWidth,\n    rightPosition,\n    rightWidth,\n    topHeight,\n  ])\n\n  const [isPageLoading, setIsPageLoading] = useState(false)\n  useEffect(() => {\n    const abortController = new AbortController()\n    const rootState = store.getState()\n    const pageLoadingActions = getPageLoadingActions(rootState)\n    const currentPageActions = pageLoadingActions.filter(\n      (action) =>\n        action.config?.advancedConfig.pages.includes(currentPageDisplayName),\n    )\n    const canShowPageActions = currentPageActions.filter(\n      (action) => action?.config.advancedConfig.displayLoadingPage,\n    )\n    if (canShowPageActions.length > 0) {\n      setIsPageLoading(true)\n    }\n    const requests = currentPageActions.map((action) => {\n      if (action.config.advancedConfig.delayWhenLoaded > 0) {\n        return runActionWithDelay(\n          action as IExecutionActions,\n          abortController.signal,\n        )\n      } else {\n        return runActionWithExecutionResult(\n          action as IExecutionActions,\n          true,\n          abortController.signal,\n        )\n      }\n    })\n    Promise.all(requests)\n      .catch((_e) => {})\n      .finally(() => {\n        setIsPageLoading(false)\n      })\n\n    return () => {\n      abortController.abort()\n    }\n  }, [currentPageDisplayName])\n\n  if (isPageLoading) {\n    return <PageLoading />\n  }\n\n  if (!pageNode || pageNode.$widgetType !== \"PAGE_NODE\") return null\n\n  const finalCanvasWidth =\n    canvasSize === \"fixed\" ? `${canvasWidth}px` : `${canvasWidth}%`\n\n  return (\n    <div\n      css={applyCanvasContainerWrapperStyle(finalCanvasWidth, mode)}\n      ref={containerWrapperRef}\n    >\n      <div css={pageContainerWrapperStyle} ref={containerRef}>\n        {hasHeader && currentPageDisplayName && (\n          <RenderHeaderSection\n            topHeight={topHeight}\n            footerHeight={hasFooter ? bottomHeight : 0}\n            containerHeight={bounds.height}\n            currentPageDisplayName={currentPageDisplayName}\n            columnNumber={headerColumns ?? DEFAULT_BODY_COLUMNS_NUMBER}\n          />\n        )}\n        {hasLeft && currentPageDisplayName && (\n          <RenderLeftSection\n            leftWidth={realLeftWidth}\n            showFoldIcon={showLeftFoldIcon}\n            isFold={isLeftFold}\n            setIsLeftFold={setIsLeftFold}\n            columnNumber={leftColumns ?? DEFAULT_ASIDE_COLUMNS_NUMBER}\n          />\n        )}\n        {currentPageDisplayName && (\n          <RenderBodySection\n            columnNumber={bodyColumns ?? DEFAULT_BODY_COLUMNS_NUMBER}\n          />\n        )}\n        {hasRight && currentPageDisplayName && (\n          <RenderRightSection\n            showFoldIcon={showRightFoldIcon}\n            isFold={isRightFold}\n            rightWidth={realRightWidth}\n            setIsRightFold={setIsRightFold}\n            columnNumber={rightColumns ?? DEFAULT_ASIDE_COLUMNS_NUMBER}\n          />\n        )}\n        {hasFooter && currentPageDisplayName && (\n          <RenderFooterSection\n            bottomHeight={bottomHeight}\n            containerHeight={bounds.height}\n            headerHeight={hasHeader ? topHeight : 0}\n            currentPageDisplayName={currentPageDisplayName}\n            columnNumber={footerColumns ?? DEFAULT_BODY_COLUMNS_NUMBER}\n          />\n        )}\n      </div>\n      <RenderModalSection\n        columnNumber={bodyColumns ?? DEFAULT_BODY_COLUMNS_NUMBER}\n      />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Page/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { IllaMode } from \"@/redux/config/configState\"\n\nexport const applyCanvasContainerWrapperStyle = (\n  width: string,\n  mode: IllaMode,\n) => {\n  const borderStyle =\n    mode === \"edit\" && width !== \"100%\"\n      ? css`\n          border-left: 1px solid ${getColor(\"grayBlue\", \"09\")};\n          border-right: 1px solid ${getColor(\"grayBlue\", \"09\")};\n        `\n      : null\n  return css`\n    width: ${width};\n    height: 100%;\n    position: relative;\n    background-color: ${getColor(\"white\", \"01\")};\n    flex: none;\n    margin: 0 auto;\n    ${borderStyle};\n  `\n}\n\nexport const pageContainerWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n`\n\nexport const emptyContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 14px;\n  padding: 0 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/PageLoading/pageLoading.tsx",
    "content": "import { FC } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { pageLoadingStyle } from \"./style\"\n\nexport const PageLoading: FC = () => {\n  return (\n    <div css={pageLoadingStyle}>\n      <Loading colorScheme=\"techPurple\" />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/PageLoading/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const pageLoadingStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/BodySection/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport RenderComponentCanvasContainer from \"@/page/App/components/DotPanel/components/Canvas/renderComponentCanvasContainer\"\nimport { EmptyState } from \"@/page/App/components/DotPanel/components/Page/emptyState\"\nimport { BASIC_CANVAS_PADDING } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getCurrentDisplayName } from \"@/page/App/components/DotPanel/hooks/sectionUtils\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport { getCurrentPageBodySection } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { containerWrapperStyle } from \"../style\"\nimport { RenderSectionProps } from \"./interface\"\nimport { bodySectionWrapperStyle } from \"./style\"\n\nexport const RenderBodySection: FC<RenderSectionProps> = (props) => {\n  const { columnNumber } = props\n  let { viewPath } = useParams()\n  const isProductionMode = useSelector(getIsILLAProductMode)\n  const bodySection = useSelector(getCurrentPageBodySection)\n  if (!bodySection) return null\n\n  const {\n    viewSortedKey,\n    currentViewIndex,\n    defaultViewKey,\n    sectionViewConfigs,\n    style,\n  } = bodySection\n  const { padding, background = \"white\" } = style ?? {}\n  const currentViewDisplayName = getCurrentDisplayName(\n    sectionViewConfigs,\n    viewSortedKey,\n    defaultViewKey,\n    isProductionMode,\n    viewPath,\n    currentViewIndex,\n  )\n\n  const componentNode = bodySection.$childrenNode?.find(\n    (node: string) => node === currentViewDisplayName,\n  )\n\n  return (\n    <div css={bodySectionWrapperStyle(background)}>\n      <div css={containerWrapperStyle}>\n        {componentNode ? (\n          <RenderComponentCanvasContainer\n            displayName={componentNode}\n            containerPadding={padding?.size ?? `${BASIC_CANVAS_PADDING}`}\n            columnNumber={columnNumber}\n            isRootCanvas\n          />\n        ) : (\n          <EmptyState />\n        )}\n      </div>\n    </div>\n  )\n}\n\nRenderBodySection.displayName = \"RenderBodySection\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/BodySection/interface.ts",
    "content": "import { RenderBasicSectionProps } from \"../interface\"\n\nexport type RenderSectionProps = RenderBasicSectionProps\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/BodySection/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\n\nexport const bodySectionWrapperStyle = (background: string) => css`\n  position: absolute;\n  width: var(--illa-canvas-body-width, 100%);\n  left: var(--illa-canvas-body-left, 0);\n  top: var(--illa-canvas-body-top, 0);\n  height: var(--illa-canvas-body-height);\n  background: ${getSpecialThemeColor(background)};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/FooterSection/index.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport RenderComponentCanvasContainer from \"@/page/App/components/DotPanel/components/Canvas/renderComponentCanvasContainer\"\nimport { EmptyState } from \"@/page/App/components/DotPanel/components/Page/emptyState\"\nimport {\n  BASIC_CANVAS_PADDING,\n  BODY_MIN_HEIGHT,\n  FOOTER_MIN_HEIGHT,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getCurrentDisplayName } from \"@/page/App/components/DotPanel/hooks/sectionUtils\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getCurrentPageFooterSection } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { containerWrapperStyle } from \"../style\"\nimport { RenderFooterSectionProps } from \"./interface\"\nimport { applyFooterSectionWrapperStyle } from \"./style\"\n\nexport const RenderFooterSection: FC<RenderFooterSectionProps> = (props) => {\n  const {\n    bottomHeight,\n    containerHeight,\n    headerHeight,\n    currentPageDisplayName,\n    columnNumber,\n  } = props\n\n  const dispatch = useDispatch()\n\n  const isProductionMode = useSelector(getIsILLAProductMode)\n  const footerNode = useSelector(getCurrentPageFooterSection)\n  let { viewPath } = useParams()\n\n  const {\n    viewSortedKey,\n    currentViewIndex,\n    defaultViewKey,\n    sectionViewConfigs,\n    style,\n  } = footerNode ?? {}\n  const {\n    padding,\n    background = \"white\",\n    shadowSize = \"none\",\n    dividerColor,\n  } = style ?? {}\n  const handleUpdateHeight = useCallback(\n    (height: number) => {\n      let currentWrapperHeight = height\n      const tmpBodyHeight =\n        containerHeight - headerHeight - currentWrapperHeight\n      if (currentWrapperHeight < FOOTER_MIN_HEIGHT) {\n        currentWrapperHeight = FOOTER_MIN_HEIGHT\n      }\n\n      if (tmpBodyHeight < BODY_MIN_HEIGHT) {\n        let bodyHeight = BODY_MIN_HEIGHT\n        currentWrapperHeight = containerHeight - headerHeight - bodyHeight\n      }\n\n      dispatch(\n        componentsActions.updateTargetPagePropsReducer({\n          pageName: currentPageDisplayName,\n          newProps: {\n            bottomHeight: currentWrapperHeight,\n          },\n          notUseUndoRedo: true,\n        }),\n      )\n    },\n    [containerHeight, currentPageDisplayName, dispatch, headerHeight],\n  )\n\n  if (!footerNode) return null\n\n  const currentViewDisplayName = getCurrentDisplayName(\n    sectionViewConfigs,\n    viewSortedKey,\n    defaultViewKey,\n    isProductionMode,\n    viewPath,\n    currentViewIndex,\n  )\n\n  const componentNode = footerNode.$childrenNode?.find(\n    (displayName: string) => displayName === currentViewDisplayName,\n  )\n\n  return (\n    <div\n      css={applyFooterSectionWrapperStyle(\n        `${bottomHeight}px`,\n        \"240px\",\n        \"500px\",\n        dividerColor,\n        background,\n      )}\n    >\n      <div css={containerWrapperStyle}>\n        {componentNode ? (\n          <RenderComponentCanvasContainer\n            displayName={componentNode}\n            containerPadding={padding?.size ?? `${BASIC_CANVAS_PADDING}`}\n            columnNumber={columnNumber}\n            isRootCanvas\n            safeRowNumber={0}\n            handleUpdateHeight={handleUpdateHeight}\n            canResizeCanvas\n            minHeight={FOOTER_MIN_HEIGHT}\n            shadowSize={shadowSize}\n          />\n        ) : (\n          <EmptyState />\n        )}\n      </div>\n    </div>\n  )\n}\nRenderFooterSection.displayName = \"RenderHeaderSection\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/FooterSection/interface.ts",
    "content": "import { RenderBasicSectionProps } from \"../interface\"\n\nexport interface RenderFooterSectionProps extends RenderBasicSectionProps {\n  bottomHeight: number\n  containerHeight: number\n  headerHeight: number\n  currentPageDisplayName: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/FooterSection/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\nimport { FOOTER_MIN_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\n\nexport const applyFooterSectionWrapperStyle = (\n  height: string,\n  left: string = \"0px\",\n  width: string = \"0px\",\n  dividerColor?: string,\n  background: string = \"transparent\",\n) => css`\n  position: absolute;\n  bottom: 0;\n  left: var(--illa-canvas-footer-left, ${left});\n  width: var(--illa-canvas-footer-width, ${width});\n  height: ${height};\n  display: flex;\n  flex-direction: column-reverse;\n  min-height: ${FOOTER_MIN_HEIGHT}px;\n  border-top: ${dividerColor\n    ? `1px solid ${getSpecialThemeColor(dividerColor)}`\n    : \"unset\"};\n  background: ${getSpecialThemeColor(background)};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/HeaderSection/index.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport RenderComponentCanvasContainer from \"@/page/App/components/DotPanel/components/Canvas/renderComponentCanvasContainer\"\nimport { EmptyState } from \"@/page/App/components/DotPanel/components/Page/emptyState\"\nimport {\n  BASIC_CANVAS_PADDING,\n  BODY_MIN_HEIGHT,\n  HEADER_MIN_HEIGHT,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getCurrentDisplayName } from \"@/page/App/components/DotPanel/hooks/sectionUtils\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getCurrentPageHeaderSection } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { containerWrapperStyle } from \"../style\"\nimport { RenderHeaderSectionProps } from \"./interface\"\nimport { applyHeaderSectionWrapperStyle } from \"./style\"\n\nexport const RenderHeaderSection: FC<RenderHeaderSectionProps> = (props) => {\n  const {\n    topHeight,\n    containerHeight,\n    footerHeight,\n    currentPageDisplayName,\n    columnNumber,\n  } = props\n\n  const dispatch = useDispatch()\n\n  let { viewPath } = useParams()\n  const isProductionMode = useSelector(getIsILLAProductMode)\n  const headerNode = useSelector(getCurrentPageHeaderSection)\n  const {\n    viewSortedKey,\n    currentViewIndex,\n    defaultViewKey,\n    sectionViewConfigs,\n    style,\n  } = headerNode ?? {}\n  const {\n    padding,\n    background = \"white\",\n    shadowSize,\n    dividerColor,\n  } = style ?? {}\n  const currentViewDisplayName = getCurrentDisplayName(\n    sectionViewConfigs,\n    viewSortedKey,\n    defaultViewKey,\n    isProductionMode,\n    viewPath,\n    currentViewIndex,\n  )\n\n  const handleUpdateHeight = useCallback(\n    (height: number) => {\n      let currentWrapperHeight = height\n      const tmpBodyHeight =\n        containerHeight - footerHeight - currentWrapperHeight\n\n      if (tmpBodyHeight < BODY_MIN_HEIGHT) {\n        let bodyHeight = BODY_MIN_HEIGHT\n        currentWrapperHeight = containerHeight - footerHeight - bodyHeight\n      }\n\n      if (currentWrapperHeight < HEADER_MIN_HEIGHT) {\n        currentWrapperHeight = HEADER_MIN_HEIGHT\n      }\n      dispatch(\n        componentsActions.updateTargetPagePropsReducer({\n          pageName: currentPageDisplayName,\n          newProps: {\n            topHeight: currentWrapperHeight,\n          },\n          notUseUndoRedo: true,\n        }),\n      )\n    },\n    [containerHeight, currentPageDisplayName, dispatch, footerHeight],\n  )\n\n  if (!headerNode) return null\n\n  const componentNode = headerNode.$childrenNode?.find(\n    (node: string) => node === currentViewDisplayName,\n  )\n\n  return (\n    <div\n      css={applyHeaderSectionWrapperStyle(\n        `${topHeight}px`,\n        \"240px\",\n        \"500px\",\n        dividerColor,\n        background,\n      )}\n    >\n      <div css={containerWrapperStyle}>\n        {componentNode ? (\n          <RenderComponentCanvasContainer\n            displayName={componentNode}\n            containerPadding={padding?.size ?? `${BASIC_CANVAS_PADDING}`}\n            columnNumber={columnNumber}\n            isRootCanvas\n            safeRowNumber={0}\n            handleUpdateHeight={handleUpdateHeight}\n            canResizeCanvas\n            minHeight={HEADER_MIN_HEIGHT}\n            shadowSize={shadowSize}\n          />\n        ) : (\n          <EmptyState />\n        )}\n      </div>\n    </div>\n  )\n}\nRenderHeaderSection.displayName = \"RenderHeaderSection\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/HeaderSection/interface.ts",
    "content": "import { RenderBasicSectionProps } from \"../interface\"\n\nexport interface RenderHeaderSectionProps extends RenderBasicSectionProps {\n  topHeight: number\n  containerHeight: number\n  footerHeight: number\n  currentPageDisplayName: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/HeaderSection/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\nimport { HEADER_MIN_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\n\nexport const applyHeaderSectionWrapperStyle = (\n  height: string,\n  left: string = \"0px\",\n  width: string = \"0px\",\n  dividerColor?: string,\n  background: string = \"transparent\",\n) => css`\n  position: absolute;\n  top: 0;\n  left: var(--illa-canvas-header-left, ${left});\n  width: var(--illa-canvas-header-width, ${width});\n  height: ${height};\n  display: flex;\n  flex-direction: column;\n  min-height: ${HEADER_MIN_HEIGHT}px;\n  border-bottom: ${dividerColor\n    ? `1px solid ${getSpecialThemeColor(dividerColor)}`\n    : \"unset\"};\n  background: ${getSpecialThemeColor(background)};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/LeftSection/index.tsx",
    "content": "import { AnimatePresence, motion } from \"framer-motion\"\nimport { FC, useCallback } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { NextIcon } from \"@illa-design/react\"\nimport RenderComponentCanvasContainer from \"@/page/App/components/DotPanel/components/Canvas/renderComponentCanvasContainer\"\nimport { EmptyState } from \"@/page/App/components/DotPanel/components/Page/emptyState\"\nimport { BASIC_CANVAS_PADDING } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getCurrentDisplayName } from \"@/page/App/components/DotPanel/hooks/sectionUtils\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport { getCurrentPageLeftSection } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport {\n  applyCloseFoldPositionStyle,\n  applyHorizontalAnimationWrapperStyle,\n  applyNoBottomPaddingStyle,\n  applyOpenFoldPositionStyle,\n  containerWrapperStyle,\n  openFoldWrapperStyle,\n  rotaIconStyle,\n} from \"../style\"\nimport { RenderLeftSectionProps } from \"./interface\"\nimport { applyLeftSectionWrapperStyle } from \"./style\"\n\nexport const RenderLeftSection: FC<RenderLeftSectionProps> = (props) => {\n  const { showFoldIcon, isFold, leftWidth, setIsLeftFold, columnNumber } = props\n\n  const isProductionMode = useSelector(getIsILLAProductMode)\n  const leftSectionNode = useSelector(getCurrentPageLeftSection)\n  let { viewPath } = useParams()\n\n  const {\n    viewSortedKey,\n    currentViewIndex,\n    defaultViewKey,\n    sectionViewConfigs,\n    style,\n  } = leftSectionNode ?? {}\n  const {\n    padding,\n    background = \"white\",\n    shadowSize = \"none\",\n    dividerColor,\n  } = style ?? {}\n  const currentViewDisplayName = getCurrentDisplayName(\n    sectionViewConfigs,\n    viewSortedKey,\n    defaultViewKey,\n    isProductionMode,\n    viewPath,\n    currentViewIndex,\n  )\n\n  const componentNode = leftSectionNode?.$childrenNode?.find(\n    (node: string) => node === currentViewDisplayName,\n  )\n\n  const handleOnClickFoldIcon = useCallback(() => {\n    setIsLeftFold(!isFold)\n  }, [isFold, setIsLeftFold])\n\n  if (!leftSectionNode) return null\n\n  return (\n    <div\n      css={applyLeftSectionWrapperStyle(\n        `${isFold ? 40 : leftWidth}px`,\n        \"0px\",\n        isFold,\n        dividerColor,\n        background,\n      )}\n    >\n      <div css={applyHorizontalAnimationWrapperStyle(isFold, \"left\")}>\n        <div\n          css={[containerWrapperStyle, applyNoBottomPaddingStyle(showFoldIcon)]}\n        >\n          {componentNode ? (\n            <RenderComponentCanvasContainer\n              displayName={componentNode}\n              containerPadding={padding?.size ?? `${BASIC_CANVAS_PADDING}`}\n              columnNumber={columnNumber}\n              isRootCanvas\n              shadowSize={shadowSize}\n            />\n          ) : (\n            <EmptyState />\n          )}\n\n          <AnimatePresence>\n            {showFoldIcon && !isFold && (\n              <motion.div\n                css={[openFoldWrapperStyle, applyCloseFoldPositionStyle]}\n                onClick={handleOnClickFoldIcon}\n                initial={{ x: 34 }}\n                animate={{ x: 0 }}\n                exit={{ x: 34 }}\n                transition={{ duration: 0.3 }}\n              >\n                <NextIcon css={rotaIconStyle} />\n              </motion.div>\n            )}\n          </AnimatePresence>\n        </div>\n      </div>\n\n      <AnimatePresence>\n        {isFold && (\n          <motion.div\n            css={[openFoldWrapperStyle, applyOpenFoldPositionStyle(\"left\")]}\n            onClick={handleOnClickFoldIcon}\n            initial={{ x: -34 }}\n            animate={{ x: 0 }}\n            exit={{ x: -34 }}\n            transition={{ duration: 0.3 }}\n          >\n            <NextIcon />\n          </motion.div>\n        )}\n      </AnimatePresence>\n    </div>\n  )\n}\nRenderLeftSection.displayName = \"RenderLeftSection\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/LeftSection/interface.ts",
    "content": "import { RenderBasicSectionProps } from \"../interface\"\n\nexport interface RenderLeftSectionProps extends RenderBasicSectionProps {\n  leftWidth: number\n  showFoldIcon: boolean\n  isFold: boolean\n  setIsLeftFold: (isFold: boolean) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/LeftSection/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\nimport { LEFT_MIN_WIDTH } from \"@/page/App/components/DotPanel/constant/canvas\"\n\nexport const applyLeftSectionWrapperStyle = (\n  width: string,\n  top: string = \"0px\",\n  isFold: boolean,\n  dividerColor?: string,\n  background: string = \"transparent\",\n) => css`\n  position: absolute;\n  top: var(--illa-canvas-left-top, ${top});\n  left: 0;\n  height: var(--illa-canvas-left-height, 100%);\n  width: ${width};\n  display: flex;\n  flex-direction: row;\n  min-width: ${isFold ? 0 : `${LEFT_MIN_WIDTH}px`};\n  border-right: ${dividerColor\n    ? `1px solid ${getSpecialThemeColor(dividerColor)}`\n    : \"unset\"};\n  background: ${getSpecialThemeColor(background)};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/ModalSection/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { RenderModalCanvasContainer } from \"@/page/App/components/DotPanel/components/Canvas/renderModalCanvasContainer\"\nimport { BASIC_CANVAS_PADDING } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport {\n  getCurrentPageModalSection,\n  getExecutionResult,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RenderModalSectionProps } from \"./interface\"\nimport { modalWrapperStyle } from \"./style\"\n\nexport const RenderModalSection: FC<RenderModalSectionProps> = (props) => {\n  const { columnNumber } = props\n  const executionResult = useSelector(getExecutionResult)\n  const modalSection = useSelector(getCurrentPageModalSection)\n\n  if (\n    !modalSection ||\n    !Array.isArray(modalSection.$childrenNode) ||\n    modalSection.$childrenNode.length === 0\n  )\n    return null\n\n  const currentModalDisplayName = modalSection.$childrenNode?.find(\n    (childName: string) => {\n      const childNode = executionResult[childName]\n      return childNode?.isVisible\n    },\n  )\n\n  if (!currentModalDisplayName) return null\n\n  return (\n    <div css={modalWrapperStyle}>\n      <RenderModalCanvasContainer\n        displayName={modalSection.displayName}\n        containerPadding={`${BASIC_CANVAS_PADDING}`}\n        columnNumber={columnNumber}\n      />\n    </div>\n  )\n}\n\nRenderModalSection.displayName = \"RenderModalSection\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/ModalSection/interface.ts",
    "content": "export interface RenderModalSectionProps {\n  columnNumber: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/ModalSection/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const modalWrapperStyle = css`\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  z-index: 8;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/RightSection/index.tsx",
    "content": "import { AnimatePresence, motion } from \"framer-motion\"\nimport { FC, useCallback } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { NextIcon } from \"@illa-design/react\"\nimport RenderComponentCanvasContainer from \"@/page/App/components/DotPanel/components/Canvas/renderComponentCanvasContainer\"\nimport { EmptyState } from \"@/page/App/components/DotPanel/components/Page/emptyState\"\nimport { BASIC_CANVAS_PADDING } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getCurrentDisplayName } from \"@/page/App/components/DotPanel/hooks/sectionUtils\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport { getCurrentPageRightSection } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport {\n  applyHorizontalAnimationWrapperStyle,\n  applyNoBottomPaddingStyle,\n  applyOpenFoldPositionStyle,\n  containerWrapperStyle,\n  openFoldWrapperStyle,\n} from \"../style\"\nimport { RenderRightSectionProps } from \"./interface\"\nimport { applyRightSectionWrapperStyle } from \"./style\"\n\nexport const RenderRightSection: FC<RenderRightSectionProps> = (props) => {\n  const { showFoldIcon, isFold, rightWidth, setIsRightFold, columnNumber } =\n    props\n\n  const isProductionMode = useSelector(getIsILLAProductMode)\n  const rightSection = useSelector(getCurrentPageRightSection)\n  let { viewPath } = useParams()\n  const handleOnClickFoldIcon = useCallback(() => {\n    setIsRightFold(!isFold)\n  }, [isFold, setIsRightFold])\n  const {\n    viewSortedKey,\n    currentViewIndex,\n    defaultViewKey,\n    sectionViewConfigs,\n    style,\n  } = rightSection ?? {}\n  const {\n    padding,\n    background = \"white\",\n    shadowSize,\n    dividerColor,\n  } = style ?? {}\n  if (!rightSection) return null\n\n  const currentViewDisplayName = getCurrentDisplayName(\n    sectionViewConfigs,\n    viewSortedKey,\n    defaultViewKey,\n    isProductionMode,\n    viewPath,\n    currentViewIndex,\n  )\n\n  const componentNode = rightSection?.$childrenNode?.find(\n    (node: string) => node === currentViewDisplayName,\n  )\n\n  return (\n    <div\n      css={applyRightSectionWrapperStyle(\n        `${isFold ? 40 : rightWidth}px`,\n        \"0px\",\n        isFold,\n        dividerColor,\n        background,\n      )}\n    >\n      <div css={applyHorizontalAnimationWrapperStyle(isFold, \"right\")}>\n        <div\n          css={[containerWrapperStyle, applyNoBottomPaddingStyle(showFoldIcon)]}\n        >\n          {componentNode ? (\n            <RenderComponentCanvasContainer\n              displayName={componentNode}\n              containerPadding={padding?.size ?? `${BASIC_CANVAS_PADDING}`}\n              columnNumber={columnNumber}\n              isRootCanvas\n              shadowSize={shadowSize}\n            />\n          ) : (\n            <EmptyState />\n          )}\n          <AnimatePresence>\n            {showFoldIcon && !isFold && (\n              <motion.div\n                css={[\n                  openFoldWrapperStyle,\n                  applyOpenFoldPositionStyle(\"right\"),\n                ]}\n                onClick={handleOnClickFoldIcon}\n                initial={{ x: -34 }}\n                animate={{ x: 0 }}\n                exit={{ x: -34 }}\n                transition={{ duration: 0.3 }}\n              >\n                <NextIcon />\n              </motion.div>\n            )}\n          </AnimatePresence>\n        </div>\n      </div>\n\n      <AnimatePresence>\n        {isFold && (\n          <motion.div\n            css={[openFoldWrapperStyle, applyOpenFoldPositionStyle(\"right\")]}\n            onClick={handleOnClickFoldIcon}\n            initial={{ x: 34, rotate: 180 }}\n            animate={{ x: 0, rotate: 180 }}\n            exit={{ x: 34, rotate: 180 }}\n            transition={{ duration: 0.3 }}\n          >\n            <NextIcon />\n          </motion.div>\n        )}\n      </AnimatePresence>\n    </div>\n  )\n}\nRenderRightSection.displayName = \"RenderRightSection\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/RightSection/interface.ts",
    "content": "import { RenderBasicSectionProps } from \"../interface\"\n\nexport interface RenderRightSectionProps extends RenderBasicSectionProps {\n  rightWidth: number\n  showFoldIcon: boolean\n  isFold: boolean\n  setIsRightFold: (isFold: boolean) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/RightSection/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\nimport { RIGHT_MIN_WIDTH } from \"@/page/App/components/DotPanel/constant/canvas\"\n\nexport const applyRightSectionWrapperStyle = (\n  width: string,\n  top: string = \"0px\",\n  isFold: boolean,\n  dividerColor?: string,\n  background: string = \"transparent\",\n) => css`\n  position: absolute;\n  top: var(--illa-canvas-right-top, ${top});\n  right: 0;\n  height: var(--illa-canvas-right-height, 100%);\n  width: ${width};\n  display: flex;\n  flex-direction: row-reverse;\n  min-width: ${isFold ? 0 : `${RIGHT_MIN_WIDTH}px`};\n  border-left: ${dividerColor\n    ? `1px solid ${getSpecialThemeColor(dividerColor)}`\n    : \"unset\"};\n  background: ${getSpecialThemeColor(background)};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/index.ts",
    "content": "export { RenderBodySection } from \"./BodySection\"\nexport { RenderModalSection } from \"./ModalSection\"\nexport { RenderHeaderSection } from \"./HeaderSection\"\nexport { RenderFooterSection } from \"./FooterSection\"\nexport { RenderLeftSection } from \"./LeftSection\"\nexport { RenderRightSection } from \"./RightSection\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/interface.ts",
    "content": "export interface RenderBasicSectionProps {\n  columnNumber: number\n  dividerColor?: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/components/Section/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const containerWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  padding: 0;\n  display: flex;\n  flex-direction: column;\n  position: relative;\n  overflow: hidden;\n`\nexport const applyNoBottomPaddingStyle = (isShowFold: boolean) => {\n  return isShowFold\n    ? css`\n        padding-bottom: 0;\n      `\n    : null\n}\n\nexport const openFoldWrapperStyle = css`\n  width: 32px;\n  height: 32px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  background-color: ${getColor(\"white\", \"01\")};\n  box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.08);\n  border-radius: 0px 16px 16px 0px;\n  cursor: pointer;\n  font-size: 12px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const applyOpenFoldPositionStyle = (direction: \"left\" | \"right\") => {\n  return css`\n    position: absolute;\n    bottom: 8px;\n    transform: ${direction === \"right\" ? \"rotate(180deg)\" : \"unset\"};\n  `\n}\n\nexport const applyCloseFoldPositionStyle = css`\n  position: absolute;\n  right: 0;\n  bottom: 8px;\n  border-radius: 16px 0 0 16px;\n`\n\nexport const rotaIconStyle = css`\n  transform: rotate(180deg);\n`\n\nexport const applyHorizontalAnimationWrapperStyle = (\n  isFold: boolean,\n  direction: \"left\" | \"right\",\n) => css`\n  width: 100%;\n  height: 100%;\n  visibility: ${!isFold ? \"visible\" : \"hidden\"};\n  display: flex;\n  flex-direction: ${direction === \"right\" ? \"row-reverse\" : \"row\"};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/constant/canvas.ts",
    "content": "export const UNIT_HEIGHT = 8\n\nexport const DEFAULT_BODY_COLUMNS_NUMBER = 32\nexport const DEFAULT_ASIDE_COLUMNS_NUMBER = 8\n\nexport const HEADER_MIN_HEIGHT = 40\nexport const FOOTER_MIN_HEIGHT = 40\nexport const BODY_MIN_HEIGHT = 40\n\nexport const LEFT_MIN_WIDTH = 80\nexport const RIGHT_MIN_WIDTH = 80\nexport const BODY_MIN_WIDTH = 80\n\nexport const BASIC_CANVAS_PADDING = 8\nexport const SCROLL_CONTAINER_PADDING = 2\nexport const BORDER_WIDTH = 2\nexport const ADD_ROWS = 40\nexport const SAFE_ROWS = 10\n\nexport const DEFAULT_PERCENT_WIDTH = {\n  LEFT: 20,\n  RIGHT: 20,\n  CANVAS: 100,\n}\n\nexport const DEFAULT_PX_WIDTH = {\n  LEFT: 240,\n  RIGHT: 240,\n  CANVAS: 1440,\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/constant/snapshotNew.ts",
    "content": "import { WidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\n\nclass SnapShot {\n  snapshot: Record<string, WidgetLayoutInfo> = {}\n  isInit: boolean = false\n\n  constructor() {\n    this.snapshot = {}\n  }\n\n  setSnapshot(snapshot: Record<string, WidgetLayoutInfo>) {\n    this.isInit = true\n    this.snapshot = snapshot\n  }\n\n  getSnapshot() {\n    return this.snapshot\n  }\n\n  clearSnapshot() {\n    this.snapshot = {}\n  }\n  getSnapShotArray() {\n    return Object.values(this.snapshot)\n  }\n  getSnapShotArrayByParentDisplayName(parentDisplayName: string) {\n    return Object.values(this.snapshot).filter(\n      (item) => item.parentNode === parentDisplayName,\n    )\n  }\n}\n\nexport const illaSnapshot = new SnapShot()\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/context/mouseHoverContext.tsx",
    "content": "import { FC, ReactNode, createContext, useRef } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { configActions } from \"@/redux/config/configSlice\"\n\ninterface MouseHoverContextInjected {\n  hoveredWidgets: string[]\n  addHoverWidget: (widgetDisplayName: string) => void\n  deleteHoverWidget: (widgetDisplayName: string) => void\n  resetHoverWidget: () => void\n}\n\nexport const MouseHoverContext = createContext<MouseHoverContextInjected>(\n  {} as MouseHoverContextInjected,\n)\n\ninterface MouseHoverProviderProps {\n  children: ReactNode\n}\n\nexport const MouseHoverProvider: FC<MouseHoverProviderProps> = (props) => {\n  const { children } = props\n  const hoverWidgetsRef = useRef<string[]>([])\n  const dispatch = useDispatch()\n\n  const addHoverWidget = (widgetDisplayName: string) => {\n    hoverWidgetsRef.current.push(widgetDisplayName)\n    hoverWidgetsRef.current = Array.from(new Set(hoverWidgetsRef.current))\n    const currentHoverWidgets = [...hoverWidgetsRef.current]\n    dispatch(configActions.updateHoveredComponent(currentHoverWidgets))\n  }\n\n  const deleteHoverWidget = (widgetDisplayName: string) => {\n    const index = hoverWidgetsRef.current.indexOf(widgetDisplayName)\n    if (index === -1) return\n    hoverWidgetsRef.current.splice(index, 1)\n    const currentHoverWidgets = [...hoverWidgetsRef.current]\n    dispatch(configActions.updateHoveredComponent(currentHoverWidgets))\n  }\n  const resetHoverWidget = () => {\n    hoverWidgetsRef.current = []\n    dispatch(configActions.updateHoveredComponent([]))\n  }\n  const value = {\n    hoveredWidgets: hoverWidgetsRef.current,\n    addHoverWidget,\n    deleteHoverWidget,\n    resetHoverWidget,\n  }\n\n  return (\n    <MouseHoverContext.Provider value={value}>\n      {children}\n    </MouseHoverContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/context/mouseMoveContext.tsx",
    "content": "import { FC, ReactNode, createContext, useRef } from \"react\"\n\ninterface MouseMoveContextInjected {\n  hoveredWidgets: string[]\n  addHoverWidget: (widgetDisplayName: string) => void\n  deleteHoverWidget: (widgetDisplayName: string) => void\n  resetHoverWidget: () => void\n}\n\nexport const MouseMoveContext = createContext<MouseMoveContextInjected>(\n  {} as MouseMoveContextInjected,\n)\n\ninterface MouseMoveProviderProps {\n  children: ReactNode\n}\n\nexport const MouseMoveProvider: FC<MouseMoveProviderProps> = (props) => {\n  const { children } = props\n  const hoverWidgetsRef = useRef<string[]>([])\n\n  const addHoverWidget = (widgetDisplayName: string) => {\n    hoverWidgetsRef.current.push(widgetDisplayName)\n  }\n\n  const deleteHoverWidget = (widgetDisplayName: string) => {\n    const index = hoverWidgetsRef.current.indexOf(widgetDisplayName)\n    if (index === -1) return\n    hoverWidgetsRef.current.splice(index, 1)\n  }\n  const resetHoverWidget = () => {\n    hoverWidgetsRef.current = []\n  }\n  const value = {\n    hoveredWidgets: hoverWidgetsRef.current,\n    addHoverWidget,\n    deleteHoverWidget,\n    resetHoverWidget,\n  }\n\n  return (\n    <MouseMoveContext.Provider value={value}>\n      {children}\n    </MouseMoveContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/context/scrollBarContext.tsx",
    "content": "import { RefObject } from \"react\"\n\nconst scrollBarContainerController = new Map<\n  string,\n  RefObject<HTMLDivElement>\n>()\n\nexport const setScrollBarContainerController = (\n  displayName: string,\n  ref: RefObject<HTMLDivElement>,\n) => {\n  scrollBarContainerController.set(displayName, ref)\n}\n\nexport const removeScrollBarContainerControllerByDisplayName = (\n  displayName: string,\n) => {\n  scrollBarContainerController.delete(displayName)\n}\n\nexport const clearScrollBarContainerController = () => {\n  scrollBarContainerController.clear()\n}\n\nexport const getScrollBarContainerByDisplayName = (displayName: string) => {\n  return scrollBarContainerController.get(displayName)\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/hooks/sectionUtils.ts",
    "content": "export const getCurrentDisplayName = (\n  sectionViewConfigs: any[],\n  viewSortedKey: string[],\n  defaultViewPath: string,\n  isProduction: boolean,\n  viewPath: string | undefined,\n  currentViewIndex: number,\n) => {\n  if (!Array.isArray(sectionViewConfigs) || !Array.isArray(viewSortedKey))\n    return \"sub-page1\"\n  const defaultedViewConfig = sectionViewConfigs.find(\n    (item) => item.path === defaultViewPath,\n  )\n  const defaultedViewKey = viewSortedKey.includes(\n    defaultedViewConfig?.viewDisplayName,\n  )\n    ? defaultedViewConfig?.viewDisplayName\n    : viewSortedKey[0]\n\n  if (isProduction) {\n    let targetViewDisplayName = defaultedViewKey\n    if (viewPath) {\n      const targetViewName = sectionViewConfigs.find(\n        (config) => config.path === decodeURIComponent(viewPath),\n      )\n      targetViewDisplayName =\n        targetViewName?.viewDisplayName || defaultedViewKey\n    }\n\n    return targetViewDisplayName\n  } else {\n    return viewSortedKey[currentViewIndex] || defaultedViewKey\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/hooks/useMousePostionAsync.tsx",
    "content": "import { getCurrentUser } from \"@illa-public/user-data\"\nimport { RefObject, useCallback, useContext, useEffect, useRef } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { useWindowSize } from \"react-use\"\nimport { getIsDragging } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { MouseMoveContext } from \"../context/mouseMoveContext\"\nimport { getMousePositionWithIllaUnit } from \"../utils/calcMouse\"\nimport { sendMousePositionHandler } from \"../utils/sendBinaryMessage\"\n\ninterface CursorPosition {\n  xMod: number\n  yMod: number\n  xInteger: number\n  yInteger: number\n}\n\nexport const useMousePositionAsync = (\n  containerRef: RefObject<HTMLDivElement>,\n  unitWidth: number,\n  displayName: string,\n  isRoot: boolean = false,\n  wrapperRef: RefObject<HTMLDivElement>,\n) => {\n  const params = useParams()\n  const userInfo = useSelector(getCurrentUser)\n  const isDragging = useSelector(getIsDragging)\n  const { width, height } = useWindowSize()\n  const cursorPositionRef = useRef<CursorPosition>({\n    xInteger: 0,\n    yInteger: 0,\n    xMod: 0,\n    yMod: 0,\n  })\n\n  const mouseMoveContext = useContext(MouseMoveContext)\n  const mouseEnterHandler = useCallback(() => {\n    mouseMoveContext.addHoverWidget(displayName)\n  }, [displayName, mouseMoveContext])\n\n  const mouseLeaveHandler = useCallback(() => {\n    mouseMoveContext.deleteHoverWidget(displayName)\n    if (isRoot && !isDragging) {\n      sendMousePositionHandler(displayName, 0, 0, 0, 0, true)\n    }\n  }, [displayName, isDragging, isRoot, mouseMoveContext])\n\n  const mouseMoveAsyncHandler = useCallback(\n    (e: MouseEvent) => {\n      const { clientX, clientY } = e\n      if (\n        mouseMoveContext.hoveredWidgets.length === 0 ||\n        mouseMoveContext.hoveredWidgets.at(-1) !== displayName\n      )\n        return\n      const containerRect = containerRef.current?.getBoundingClientRect()\n      const containerPosition = {\n        x: containerRect?.left ?? 0,\n        y: containerRect?.top ?? 0,\n      }\n      const mousePosition = {\n        x: clientX,\n        y: clientY,\n      }\n      const { xInteger, xMod, yInteger, yMod } = getMousePositionWithIllaUnit(\n        unitWidth,\n        containerPosition,\n        mousePosition,\n        containerRef.current?.scrollTop,\n      )\n      cursorPositionRef.current = {\n        xInteger,\n        yInteger,\n        xMod,\n        yMod,\n      }\n      if (\n        Number.isInteger(xInteger) &&\n        Number.isInteger(yInteger) &&\n        !Number.isNaN(xMod) &&\n        !Number.isNaN(yMod) &&\n        !isDragging\n      ) {\n        sendMousePositionHandler(displayName, xInteger, yInteger, xMod, yMod)\n      }\n    },\n    [\n      containerRef,\n      displayName,\n      isDragging,\n      mouseMoveContext.hoveredWidgets,\n      unitWidth,\n    ],\n  )\n\n  const visibilityChangeHandler = useCallback(() => {\n    if (document.hidden) {\n      mouseLeaveHandler()\n    }\n  }, [mouseLeaveHandler])\n\n  const pageHideHandler = useCallback(() => {\n    mouseLeaveHandler()\n  }, [mouseLeaveHandler])\n\n  useEffect(() => {\n    const wrapperNode = wrapperRef.current\n    if (wrapperNode) {\n      wrapperNode.addEventListener(\"mouseenter\", mouseEnterHandler)\n      wrapperNode?.addEventListener(\"mousemove\", mouseMoveAsyncHandler)\n      wrapperNode?.addEventListener(\"mouseleave\", mouseLeaveHandler)\n    }\n    return () => {\n      if (wrapperNode) {\n        wrapperNode.removeEventListener(\"mouseenter\", mouseEnterHandler)\n        wrapperNode.removeEventListener(\"mousemove\", mouseMoveAsyncHandler)\n        wrapperNode.removeEventListener(\"mouseleave\", mouseLeaveHandler)\n      }\n    }\n  }, [\n    containerRef,\n    height,\n    mouseEnterHandler,\n    mouseLeaveHandler,\n    mouseMoveAsyncHandler,\n    params.appId,\n    unitWidth,\n    userInfo.nickname,\n    userInfo.userID,\n    width,\n    wrapperRef,\n  ])\n\n  useEffect(() => {\n    if (isRoot) {\n      window.addEventListener(\"blur\", mouseLeaveHandler)\n      window.addEventListener(\"visibilitychange\", visibilityChangeHandler)\n      window.addEventListener(\"pagehide\", pageHideHandler)\n    }\n\n    return () => {\n      if (isRoot) {\n        window.removeEventListener(\"blur\", mouseLeaveHandler)\n        window.removeEventListener(\"visibilitychange\", visibilityChangeHandler)\n        window.removeEventListener(\"pagehide\", pageHideHandler)\n      }\n    }\n  }, [isRoot, mouseLeaveHandler, pageHideHandler, visibilityChangeHandler])\n\n  return { cursorPositionRef }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, useEffect, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { applyViewportContainerWrapperStyle } from \"@/page/App/components/DotPanel/style\"\nimport {\n  getIllaMode,\n  getIsILLAPreviewMode,\n  getIsILLAProductMode,\n} from \"@/redux/config/configSelector\"\nimport { getViewportSizeSelector } from \"@/redux/currentApp/components/componentsSelector\"\nimport {\n  getAppLoadedActions,\n  getExecutionResult,\n  getIntervalActions,\n  getRootNodeExecutionResult,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport store from \"@/store\"\nimport {\n  IExecutionActions,\n  registerActionPeriod,\n  removeAllActionPeriod,\n  runActionWithDelay,\n  runActionWithExecutionResult,\n} from \"@/utils/action/runAction\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { RenderPage } from \"./components/Page/renderPage\"\nimport { MouseHoverProvider } from \"./context/mouseHoverContext\"\nimport { MouseMoveProvider } from \"./context/mouseMoveContext\"\n\nexport const DotPanel: FC = () => {\n  const rootExecutionProps = useSelector(getRootNodeExecutionResult)\n  const executionResult = useSelector(getExecutionResult)\n  const mode = useSelector(getIllaMode)\n  const isProductionMode = useSelector(getIsILLAProductMode)\n  const viewportSize = useSelector(getViewportSizeSelector)\n\n  const isPreviewMode = useSelector(getIsILLAPreviewMode)\n\n  const { currentPageIndex, pageSortedKey, homepageDisplayName } =\n    rootExecutionProps\n  let { pageName } = useParams()\n  const currentDisplayName = useMemo(() => {\n    if (isProductionMode) {\n      return (\n        pageName ||\n        homepageDisplayName ||\n        pageSortedKey[currentPageIndex] ||\n        \"page1\"\n      )\n    } else {\n      return pageSortedKey[currentPageIndex] || homepageDisplayName\n    }\n  }, [\n    currentPageIndex,\n    homepageDisplayName,\n    isProductionMode,\n    pageName,\n    pageSortedKey,\n  ])\n\n  const canRenders = !!executionResult.root\n\n  useEffect(() => {\n    if (canRenders) {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.INITIALIZE)\n    }\n  }, [canRenders])\n\n  useEffect(() => {\n    const rootState = store.getState()\n    const appLoadedAction = getAppLoadedActions(rootState)\n    const request = appLoadedAction\n      .filter((action) => !action.isRunning)\n      .map((action) => {\n        if (action.config.advancedConfig.delayWhenLoaded > 0) {\n          return runActionWithDelay(action as IExecutionActions)\n        } else {\n          return runActionWithExecutionResult(action as IExecutionActions)\n        }\n      })\n    Promise.all(request)\n  }, [])\n\n  useEffect(() => {\n    const rootState = store.getState()\n    const appLoadedAction = getIntervalActions(rootState)\n    appLoadedAction.forEach((action) => {\n      registerActionPeriod(action as IExecutionActions)\n    })\n\n    return () => {\n      removeAllActionPeriod()\n    }\n  })\n\n  if (!rootExecutionProps) return null\n\n  return (\n    <MouseHoverProvider>\n      <MouseMoveProvider>\n        <div\n          css={applyViewportContainerWrapperStyle(\n            mode,\n            isPreviewMode ? viewportSize.viewportWidth : undefined,\n            isPreviewMode ? viewportSize.viewportHeight : undefined,\n          )}\n        >\n          <RenderPage\n            key={currentDisplayName}\n            currentPageDisplayName={currentDisplayName}\n          />\n        </div>\n      </MouseMoveProvider>\n    </MouseHoverProvider>\n  )\n}\n\nDotPanel.displayName = \"DotPanel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/interface.ts",
    "content": "// return when drop collect trigger\nexport interface DropCollectedInfo {\n  isActive: boolean\n}\n\n// return when drag collect trigger\nexport interface DragCollectedInfo {\n  isDragging: boolean\n}\n\nexport interface PreviewPlaceholderProps {\n  canDrop: boolean\n  x: number\n  y: number\n  lunchX: number\n  lunchY: number\n  w: number\n  h: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\nimport { IllaMode } from \"@/redux/config/configState\"\n\nexport const applyComponentCanvasStyle = (\n  width: number,\n  height: number,\n  unitWidth: number,\n  unitHeight: number = 8,\n  showDot: boolean = false,\n  addHeight: number = 0,\n  minHeight?: number,\n) => {\n  const heightCss = minHeight\n    ? css`\n        height: ${addHeight}px;\n        min-height: ${minHeight}px;\n      `\n    : css`\n        min-height: 100vh;\n        height: ${addHeight}px;\n      `\n  return css`\n    width: 100%;\n    ${heightCss};\n    ${showDot\n      ? applyDotBackgroundStyle(width, height, unitWidth, unitHeight)\n      : normalCanvasBackgroundStyle}\n    position: relative;\n  `\n}\n\nconst normalCanvasBackgroundStyle = css`\n  background: unset;\n`\n\nconst applyDotBackgroundStyle = (\n  width: number,\n  height: number,\n  unitWidth: number,\n  unitHeight: number = 8,\n) => {\n  return css`\n    background-image: radial-gradient(\n        circle at 1px 1px,\n        ${globalColor(`--${illaPrefix}-grayBlue-08`)} 1px,\n        transparent 0px\n      ),\n      radial-gradient(\n        circle at ${width - 1}px 1px,\n        ${globalColor(`--${illaPrefix}-grayBlue-08`)} 1px,\n        transparent 0px\n      );\n    background-repeat: repeat;\n    background-size:\n      ${unitWidth}px ${unitHeight}px,\n      100% ${unitHeight}px;\n  `\n}\n\nexport const applyDotLintRectangleStyle = (\n  w: number,\n  h: number,\n  x: number = 0,\n  y: number = 0,\n) => {\n  return css`\n    width: ${w}px;\n    height: ${h}px;\n    border: 1px dashed ${globalColor(`--${illaPrefix}-techPurple-03`)};\n    position: absolute;\n    transform: translate(${x}px, ${y}px);\n    z-index: 6;\n    pointer-events: none;\n  `\n}\n\nexport const applyRectangleStyle = (\n  w: number,\n  h: number,\n  x: number,\n  y: number,\n  canDrop: boolean = false,\n) => {\n  return css`\n    width: ${w}px;\n    height: ${h}px;\n    background-color: ${canDrop\n      ? globalColor(`--${illaPrefix}-techPurple-03`)\n      : \"red\"};\n    opacity: 0.16;\n    position: absolute;\n    transform: translate(${x}px, ${y}px);\n    z-index: 6;\n    pointer-events: none;\n  `\n}\n\nexport const borderLineStyle = css`\n  width: 100%;\n  height: 100%;\n  border: 2px solid #f7f8fa;\n  pointer-events: none;\n`\n\nexport const applyFreezePlaceholderShapeStyle = (\n  top: number,\n  left: number,\n  height: number,\n  width: number,\n) => {\n  return css`\n    position: absolute;\n    left: ${left}px;\n    top: ${top}px;\n    width: ${width}px;\n    height: ${height}px;\n    border: 1px dashed ${globalColor(`--${illaPrefix}-techPurple-03`)};\n    z-index: 6;\n  `\n}\n\nexport const applyViewportContainerWrapperStyle = (\n  mode: IllaMode,\n  width?: number,\n  height?: number,\n) => {\n  const borderStyle =\n    mode === \"preview\" && width != undefined\n      ? css`\n          border: 1px solid ${getColor(\"grayBlue\", \"09\")};\n        `\n      : null\n  return css`\n    width: ${mode === \"production\"\n      ? \"100%\"\n      : width != undefined\n        ? `${width}px`\n        : \"100%\"};\n    height: ${mode === \"production\"\n      ? \"100%\"\n      : height != undefined\n        ? `${height}px`\n        : \"100%\"};\n    background-color: ${getColor(\"white\", \"01\")};\n    overflow: auto;\n    margin: 0 auto;\n    position: relative;\n    ${borderStyle}\n  `\n}\n\nexport const applyMultiSelectedScaleSquareStyle = (\n  width: number,\n  height: number,\n  left: number,\n  top: number,\n) => {\n  return css`\n    position: absolute;\n    border: 1px dashed ${getColor(\"techPurple\", \"03\")};\n    width: ${width}px;\n    height: ${height}px;\n    left: 0;\n    top: 0;\n    transform: translate(${left}px, ${top}px);\n    pointer-events: none;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/utils/calcMouse.ts",
    "content": "import { XYCoord } from \"react-dnd\"\n\nexport const getMouseRealPosition = (\n  clientOffSet: XYCoord,\n  containerScrollTop: number = 0,\n) => {\n  return {\n    x: clientOffSet.x,\n    y: clientOffSet.y + containerScrollTop,\n  }\n}\n\nexport const getMouseRelativePosition = (\n  canvasPosition: XYCoord,\n  mousePosition: XYCoord,\n  containerScrollTop: number = 0,\n) => {\n  const { x, y } = getMouseRealPosition(mousePosition, containerScrollTop)\n  return {\n    x: x - canvasPosition.x,\n    y: y - canvasPosition.y,\n  }\n}\n\nexport const getMousePositionWithIllaUnit = (\n  unitWidth: number,\n  canvasPosition: XYCoord,\n  mousePosition: XYCoord,\n  containerScrollTop: number = 0,\n) => {\n  const relativePosition = getMouseRelativePosition(\n    canvasPosition,\n    mousePosition,\n    containerScrollTop,\n  )\n  const realX = relativePosition.x / unitWidth\n  const integerPartX = Math.floor(realX)\n  const decimalPartX = realX - integerPartX\n  const integerPartY = Math.floor(relativePosition.y)\n  const decimalPartY = relativePosition.y - integerPartY\n  return {\n    xMod: decimalPartX,\n    yMod: decimalPartY,\n    xInteger: integerPartX,\n    yInteger: integerPartY,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/utils/crossingHelper.ts",
    "content": "import { WidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\nimport { illaSnapshot } from \"../constant/snapshotNew\"\n\nexport interface NodeShape {\n  x: number\n  y: number\n  w: number\n  h: number\n}\n\nexport const isNewCrossing = (mainNode: NodeShape, otherNode: NodeShape) => {\n  return (\n    mainNode.y < otherNode.y + otherNode.h &&\n    mainNode.y + mainNode.h > otherNode.y &&\n    mainNode.x < otherNode.x + otherNode.w &&\n    mainNode.x + mainNode.w > otherNode.x\n  )\n}\n\nexport const isOnlyCrossingY = (mainNode: NodeShape, otherNode: NodeShape) => {\n  return (\n    mainNode.y < otherNode.y + otherNode.h &&\n    mainNode.y + mainNode.h > otherNode.y\n  )\n}\n\nexport const getCrossingWidget = (\n  parentNodeDisplayName: string,\n  mainNode: NodeShape,\n  draggedDisplayNames: string[],\n) => {\n  const widgetLayoutArray = illaSnapshot.getSnapShotArrayByParentDisplayName(\n    parentNodeDisplayName,\n  )\n  const filteredWidgetLayoutArray = widgetLayoutArray.filter((item) => {\n    return !draggedDisplayNames.includes(item.displayName)\n  })\n  return filteredWidgetLayoutArray.filter((item) => {\n    return isNewCrossing(mainNode, item.layoutInfo)\n  })\n}\n\nexport const sortedRuleByYAndX = (\n  node1: WidgetLayoutInfo,\n  node2: WidgetLayoutInfo,\n) => {\n  if (node1.layoutInfo.y < node2.layoutInfo.y) {\n    return -1\n  }\n  if (node1.layoutInfo.y > node2.layoutInfo.y) {\n    return 1\n  }\n  if (node1.layoutInfo.y === node2.layoutInfo.y) {\n    if (node1.layoutInfo.x > node2.layoutInfo.x) {\n      return 1\n    }\n    if (node1.layoutInfo.x < node2.layoutInfo.x) {\n      return -1\n    }\n  }\n  return 0\n}\n\nexport const getNewPositionWithCrossing = (\n  mainSquare: NodeShape,\n  parentDisplayName: string,\n  effectedDisplayNames: string[],\n  realTimeLayout?: WidgetLayoutInfo[],\n) => {\n  const widgetLayoutArray = realTimeLayout\n    ? realTimeLayout\n    : illaSnapshot.getSnapShotArrayByParentDisplayName(parentDisplayName)\n  const filterWidgetLayoutArray = widgetLayoutArray.filter((item) => {\n    return !effectedDisplayNames.includes(item.displayName)\n  })\n\n  const newEffectedDisplayNames = [...effectedDisplayNames]\n\n  const sortedLayoutInfos = filterWidgetLayoutArray.sort(sortedRuleByYAndX)\n\n  const crossingWidgetInfos = sortedLayoutInfos.filter((item) => {\n    return isNewCrossing(mainSquare, item.layoutInfo)\n  })\n\n  if (crossingWidgetInfos.length > 0) {\n    const compareInfos = [\n      {\n        compareNode: {\n          displayName: \"root\",\n          ...mainSquare,\n        },\n        crossingWidgetInfos,\n      },\n    ]\n    const effectMap: Map<String, WidgetLayoutInfo> = new Map()\n    while (compareInfos.length > 0) {\n      const firstCompareInfo = compareInfos.shift()\n      if (firstCompareInfo) {\n        const { compareNode, crossingWidgetInfos } = firstCompareInfo\n\n        newEffectedDisplayNames.push(compareNode.displayName)\n        if (effectMap.get(compareNode.displayName)) {\n          compareNode.y =\n            effectMap.get(compareNode.displayName)?.layoutInfo.y ?? 0\n        }\n        crossingWidgetInfos.forEach((crossingItem) => {\n          if (isNewCrossing(compareNode, crossingItem.layoutInfo)) {\n            const newWidgetInfo = {\n              ...crossingItem,\n              layoutInfo: {\n                ...crossingItem.layoutInfo,\n                y: compareNode.y + compareNode.h,\n              },\n            }\n            effectMap.set(crossingItem.displayName, newWidgetInfo)\n          }\n        })\n\n        crossingWidgetInfos.forEach((crossingItem) => {\n          const newWidgetInfo = effectMap.get(crossingItem.displayName)!\n\n          const filterWidgetLayoutArray = widgetLayoutArray.filter((item) => {\n            return ![\n              ...newEffectedDisplayNames,\n              newWidgetInfo.displayName,\n            ].includes(item.displayName)\n          })\n          const crossingWidgetInfos = filterWidgetLayoutArray\n            .filter((item) => {\n              const newItemWidgetInfo = {\n                ...item.layoutInfo,\n              }\n\n              if (effectMap.get(item.displayName)) {\n                newItemWidgetInfo.y =\n                  effectMap.get(item.displayName)?.layoutInfo.y ?? 0\n              }\n              return isNewCrossing(newWidgetInfo.layoutInfo, newItemWidgetInfo)\n            })\n            .map((item) => {\n              const newItemWidgetInfo = {\n                ...item.layoutInfo,\n              }\n\n              if (effectMap.get(item.displayName)) {\n                newItemWidgetInfo.y =\n                  effectMap.get(item.displayName)?.layoutInfo.y ?? 0\n              }\n              return {\n                ...item,\n                layoutInfo: newItemWidgetInfo,\n              }\n            })\n            .sort(sortedRuleByYAndX)\n          if (crossingWidgetInfos.length > 0) {\n            const oldIndex = compareInfos.findIndex((item) => {\n              return item.compareNode.displayName === newWidgetInfo.displayName\n            })\n            if (oldIndex !== -1) {\n              compareInfos.splice(oldIndex, 1)\n            }\n            compareInfos.push({\n              compareNode: {\n                displayName: newWidgetInfo.displayName,\n                x: newWidgetInfo.layoutInfo.x,\n                y: newWidgetInfo.layoutInfo.y,\n                w: newWidgetInfo.layoutInfo.w,\n                h: newWidgetInfo.layoutInfo.h,\n              },\n              crossingWidgetInfos,\n            })\n          }\n        })\n      }\n    }\n    return effectMap\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/utils/getDragShadow.ts",
    "content": "import { clamp } from \"lodash-es\"\nimport { XYCoord } from \"react-dnd\"\nimport { DRAG_EFFECT } from \"@/page/App/components/ScaleSquare/components/DragContainer/interface\"\nimport { DEFAULT_MIN_COLUMN } from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { WidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\nimport { DragCollectedProps } from \"../components/DragPreview/interface\"\nimport { DEFAULT_BODY_COLUMNS_NUMBER, UNIT_HEIGHT } from \"../constant/canvas\"\nimport { getScrollBarContainerByDisplayName } from \"../context/scrollBarContext\"\nimport { NodeShape, getCrossingWidget, isOnlyCrossingY } from \"./crossingHelper\"\nimport { sendShadowMessageHandler } from \"./sendBinaryMessage\"\n\nexport const getRatio = (\n  initialClientOffSet: XYCoord | null,\n  initialSourceClientOffset: XYCoord | null,\n  unitWidth: number,\n) => {\n  const initOffSet = initialClientOffSet ?? { x: 0, y: 0 }\n  const initSourceOffSet = initialSourceClientOffset ?? { x: 0, y: 0 }\n  const xRatio = (initSourceOffSet.x - initOffSet.x) / unitWidth\n  const yRatio = (initSourceOffSet.y - initOffSet.y) / UNIT_HEIGHT\n  return {\n    xRatio,\n    yRatio,\n  }\n}\n\nexport const combineWidgetInfos = (layoutInfos: NodeShape[]) => {\n  const widgetXs = layoutInfos.map((info) => info.x)\n  const widgetYs = layoutInfos.map((info) => info.y)\n  const widgetRights = layoutInfos.map((info) => info.x + info.w)\n  const widgetBottoms = layoutInfos.map((info) => info.y + info.h)\n  const widgetX = Math.min(...widgetXs)\n  const widgetY = Math.min(...widgetYs)\n  const widgetRight = Math.max(...widgetRights)\n  const widgetBottom = Math.max(...widgetBottoms)\n  const widgetW = widgetRight - widgetX\n  const widgetH = widgetBottom - widgetY\n  return {\n    x: widgetX,\n    y: widgetY,\n    w: widgetW,\n    h: widgetH,\n  }\n}\n\nexport const getScrollTop = (displayName: string) => {\n  let scrollTop = 0\n  const ref = getScrollBarContainerByDisplayName(displayName)\n  if (ref && ref.current) {\n    return ref.current.scrollTop\n  }\n\n  return scrollTop\n}\n\nexport const getContainerTop = (displayName: string) => {\n  const ref = getScrollBarContainerByDisplayName(displayName)\n  if (ref && ref.current) {\n    return ref.current!.getBoundingClientRect().top\n  }\n\n  return 0\n}\n\nexport const getMousePositionInfo = (\n  initialClientOffSet: XYCoord | null,\n  initialSourceClientOffset: XYCoord | null,\n  mousePositionInViewport: XYCoord | null,\n  unitWidth: number,\n  containerTop: number,\n  containerLeft: number,\n  containerScrollTop: number,\n  yOffset: number = 0,\n  xOffset: number = 0,\n  wRatio: number = 1,\n  columnNumber: number = DEFAULT_BODY_COLUMNS_NUMBER,\n) => {\n  const { xRatio, yRatio } = getRatio(\n    initialClientOffSet,\n    initialSourceClientOffset,\n    unitWidth,\n  )\n\n  const mousePosition = mousePositionInViewport ?? {\n    x: 0,\n    y: 0,\n  }\n  const realRelativeMouseLeft = mousePosition.x - containerLeft\n  const realRelativeMouseTop =\n    mousePosition.y + containerScrollTop - containerTop\n  const realRelativeMouseX = realRelativeMouseLeft / unitWidth\n  const realRelativeMouseY = realRelativeMouseTop / UNIT_HEIGHT\n  const ratioRelativeMouseLeft =\n    xRatio * wRatio * unitWidth + mousePosition.x - containerLeft\n  const ratioRelativeMouseTop =\n    yRatio * UNIT_HEIGHT + mousePosition.y + containerScrollTop - containerTop\n  const ratioRelativeMouseY = ratioRelativeMouseTop / UNIT_HEIGHT\n  const ratioRelativeMouseX = ratioRelativeMouseLeft / unitWidth\n  const widgetX =\n    Math.min(Math.round(ratioRelativeMouseX), columnNumber - 1) - xOffset\n  const widgetY = Math.round(ratioRelativeMouseY) - yOffset\n  const mouseHoveredTopHalf = ratioRelativeMouseY % 1 >= 0.5\n\n  const mouseRealX = clamp(Math.floor(realRelativeMouseX), 0, columnNumber - 1)\n  const mouseRealY = Math.round(realRelativeMouseY)\n  const mouseRealTopHalf = realRelativeMouseY % 1 >= 0.5\n  return {\n    widgetY,\n    widgetX,\n    mouseHoveredTopHalf,\n    mouseRealY,\n    mouseRealX,\n    mouseRealTopHalf,\n  }\n}\n\nconst getLeftAndRightLimit = (\n  crossingWidgets: WidgetLayoutInfo[],\n  defaultLeft: number,\n  defaultRight: number,\n  mouseRealX = defaultLeft,\n) => {\n  let initDefaultLeft = defaultLeft,\n    initDefaultRight = defaultRight\n\n  crossingWidgets.forEach((widgetLayoutInfo) => {\n    const left = widgetLayoutInfo.layoutInfo.x,\n      right = widgetLayoutInfo.layoutInfo.x + widgetLayoutInfo.layoutInfo.w\n    if (left <= mouseRealX) {\n      initDefaultLeft = Math.max(initDefaultLeft, right)\n    }\n    if (right > mouseRealX) {\n      initDefaultRight = Math.min(initDefaultRight, left)\n    }\n  })\n  return {\n    leftLimit: initDefaultLeft,\n    rightLimit: initDefaultRight,\n  }\n}\n\nconst getDragResult = (\n  parentDisplayName: string,\n  relativeMainNode: NodeShape,\n  draggedDisplayNames: string[],\n  mouseRealY = relativeMainNode.y,\n  mouseRealX = relativeMainNode.x,\n  mouseHoveredTopHalf: boolean = true,\n  minWidth = DEFAULT_MIN_COLUMN,\n) => {\n  const { h, w, x, y } = relativeMainNode\n  let finalY = y\n  const unitWShape = {\n    ...relativeMainNode,\n    h: mouseRealY - finalY,\n    x: mouseRealX,\n    w: 1,\n  }\n\n  const crossingWidgetBottoms = getCrossingWidget(\n    parentDisplayName,\n    unitWShape,\n    draggedDisplayNames,\n  )\n    .filter((widgetLayout) => widgetLayout.layoutInfo.y <= mouseRealY)\n    .map(\n      (widgetLayout) => widgetLayout.layoutInfo.y + widgetLayout.layoutInfo.h,\n    )\n  if (crossingWidgetBottoms.length > 0) {\n    const maxBottomWithCrossingWidget = Math.max(...crossingWidgetBottoms)\n    if (maxBottomWithCrossingWidget) {\n      finalY = Math.min(maxBottomWithCrossingWidget, mouseRealY)\n      mouseHoveredTopHalf = false\n    }\n  }\n\n  let unitHeightShape = {\n    ...relativeMainNode,\n    y: finalY,\n    h: 1,\n  }\n\n  if (minWidth === 1) {\n    unitHeightShape = {\n      ...unitHeightShape,\n      w: 1,\n      x: mouseRealX,\n    }\n  }\n\n  const crossWithCursorLeftWidget = getCrossingWidget(\n    parentDisplayName,\n    unitHeightShape,\n    draggedDisplayNames,\n  )\n\n  const { leftLimit, rightLimit } = getLeftAndRightLimit(\n    crossWithCursorLeftWidget,\n    relativeMainNode.x,\n    relativeMainNode.x + relativeMainNode.w,\n    mouseRealX,\n  )\n\n  if (rightLimit - leftLimit < minWidth) {\n    mouseHoveredTopHalf = true\n    const minCrossingY = crossWithCursorLeftWidget.reduce((prev, current) => {\n        return (current?.layoutInfo?.y ?? 0) < prev?.layoutInfo?.y\n          ? current\n          : prev\n      }).layoutInfo.y,\n      maxCrossingBottom = Math.max(\n        ...crossWithCursorLeftWidget.map(\n          (widgetLayout) =>\n            widgetLayout.layoutInfo.y + widgetLayout.layoutInfo.h,\n        ),\n      )\n    if (minCrossingY != undefined && maxCrossingBottom != undefined) {\n      finalY =\n        mouseRealY - minCrossingY < maxCrossingBottom - mouseRealY\n          ? minCrossingY\n          : maxCrossingBottom\n    }\n  }\n\n  const tempH = mouseHoveredTopHalf ? 0 : 1\n  const finalYShape = {\n    ...relativeMainNode,\n    h: tempH,\n    y: finalY,\n  }\n\n  const crossingWidgetWithFinalYShape = getCrossingWidget(\n    parentDisplayName,\n    finalYShape,\n    draggedDisplayNames,\n  )\n\n  let finalX = x,\n    finalW = w\n  if (crossingWidgetWithFinalYShape.length > 0) {\n    const { leftLimit, rightLimit } = getLeftAndRightLimit(\n      crossingWidgetWithFinalYShape,\n      relativeMainNode.x,\n      relativeMainNode.x + relativeMainNode.w,\n      mouseRealX,\n    )\n    if (rightLimit - leftLimit < minWidth) return null\n    if (leftLimit !== relativeMainNode.x && leftLimit > x) {\n      finalX = leftLimit\n      finalW -= leftLimit - x\n    }\n    if (\n      rightLimit !== relativeMainNode.x + relativeMainNode.w &&\n      rightLimit < finalX + finalW\n    ) {\n      finalW = rightLimit - finalX\n    }\n  }\n  const finalShape = {\n      ...relativeMainNode,\n      x: finalX,\n      w: finalW,\n      y: finalY,\n    },\n    crossingWidgetWithFinalShape = getCrossingWidget(\n      parentDisplayName,\n      finalShape,\n      draggedDisplayNames,\n    )\n  let minY = h\n  if (crossingWidgetWithFinalShape.length > 0) {\n    minY = crossingWidgetWithFinalShape.reduce((prev, current) => {\n      return current?.layoutInfo?.y < prev?.layoutInfo?.y ? current : prev\n    })?.layoutInfo?.y\n  }\n\n  return {\n    y: finalY,\n    x: finalX,\n    w: finalW,\n    previewH:\n      crossingWidgetWithFinalShape.length > 0\n        ? minY - finalY > 0\n          ? h\n          : 0\n        : minY,\n  }\n}\n\nexport const clamWidgetShape = (\n  dragPreview: NodeShape,\n  columnNumber: number,\n  isMultiDrag: boolean,\n) => {\n  const { x, w, y, h } = dragPreview\n  if (isMultiDrag) {\n    const newW = clamp(w, 1, columnNumber)\n    const newX = clamp(x, 0, columnNumber - newW)\n    const newY = Math.max(y, 0)\n\n    return {\n      x: newX,\n      w: newW,\n      y: newY,\n      previewH: h,\n    }\n  }\n  const newX = clamp(x, 0, columnNumber)\n  const newW = clamp(w, 1, columnNumber - newX)\n  const newY = Math.max(y, 0)\n  return {\n    x: newX,\n    w: newW,\n    y: newY,\n    previewH: h,\n  }\n}\n\nconst transWidgetW = (\n  originWidth: number,\n  originUnitW: number,\n  newUnitW: number,\n  newColumnNumber: number,\n  minW: number = 1,\n) => {\n  const newW = Math.round((originWidth * originUnitW) / newUnitW)\n  return clamp(newW, minW, newColumnNumber)\n}\n\nexport const canCrossDifferenceColumnNumber = (draggedShapes: NodeShape[]) => {\n  if (draggedShapes.length <= 1) {\n    return true\n  }\n\n  const sortedLayoutInfoByY = draggedShapes.sort((node1, node2) => {\n    if (node1.y < node2.y) {\n      return -1\n    }\n    if (node1.y > node2.y) {\n      return 1\n    }\n    return 0\n  })\n\n  for (let i = 0; i < sortedLayoutInfoByY.length; i++) {\n    for (let j = i + 1; j < sortedLayoutInfoByY.length; j++) {\n      if (isOnlyCrossingY(sortedLayoutInfoByY[i], sortedLayoutInfoByY[j])) {\n        return false\n      }\n    }\n  }\n\n  return true\n}\n\nexport const getDragPreview = (\n  parentNodeDisplayName: string,\n  unitW: number,\n  dragCollectedProps: DragCollectedProps,\n  columnNumber: number,\n) => {\n  const { initialClientOffset, initialSourceClientOffset, clientOffset, item } =\n    dragCollectedProps\n\n  if (!item) return null\n\n  const outerContainerElement = document.querySelector(\n    `[data-outer-canvas-container=\"${parentNodeDisplayName}\"]`,\n  ) as HTMLDivElement\n\n  const outerContainerStyle = window.getComputedStyle(outerContainerElement!)\n  const outerContainerLeft = parseFloat(\n    outerContainerStyle.getPropertyValue(\"padding-left\"),\n  )\n\n  const containerLeft =\n    outerContainerElement!.getBoundingClientRect().left + outerContainerLeft\n\n  const containerTop = getContainerTop(parentNodeDisplayName)\n  const {\n    draggedComponents,\n    draggedDisplayName,\n    alignTop,\n    dragEffect,\n    unitWWhenDragged,\n    columnNumberWhenDragged,\n  } = item\n\n  const totalScrollTop = getScrollTop(parentNodeDisplayName)\n\n  const canDrop = canCrossDifferenceColumnNumber(\n    draggedComponents.map((item) => item.layoutInfo),\n  )\n\n  const draggedDisplayNames = draggedComponents.map((item) => item.displayName)\n  const combineWidget = combineWidgetInfos(\n    draggedComponents.map((item) => item.layoutInfo),\n  )\n  const currentWidgetLayoutInfo = draggedComponents.find(\n    (item) => item.displayName === draggedDisplayName,\n  )\n  if (!currentWidgetLayoutInfo) {\n    return null\n  }\n\n  let finalEffect =\n    parentNodeDisplayName !== draggedComponents[0].parentNode\n      ? DRAG_EFFECT.ADD\n      : dragEffect\n\n  const yOffset = currentWidgetLayoutInfo.layoutInfo.y - combineWidget.y\n  const xOffset = currentWidgetLayoutInfo.layoutInfo.x - combineWidget.x\n\n  const newW =\n    dragEffect === DRAG_EFFECT.ADD || draggedDisplayNames.length > 1\n      ? combineWidget.w\n      : transWidgetW(combineWidget.w, unitWWhenDragged, unitW, columnNumber)\n\n  const mousePositionInfo = getMousePositionInfo(\n    initialClientOffset,\n    initialSourceClientOffset,\n    clientOffset,\n    unitW,\n    containerTop,\n    containerLeft,\n    totalScrollTop,\n    yOffset,\n    xOffset,\n    1,\n    columnNumber,\n  )\n\n  const moveEffect = {\n    y:\n      alignTop || finalEffect === DRAG_EFFECT.ADD\n        ? mousePositionInfo.mouseRealY - combineWidget.y\n        : mousePositionInfo.widgetY - combineWidget.y,\n    x:\n      finalEffect === DRAG_EFFECT.ADD\n        ? mousePositionInfo.mouseRealX - combineWidget.x\n        : mousePositionInfo.widgetX - combineWidget.x,\n  }\n\n  const topHalf =\n    alignTop || finalEffect === DRAG_EFFECT.ADD\n      ? mousePositionInfo.mouseRealTopHalf\n      : mousePositionInfo.mouseHoveredTopHalf\n\n  const currentLayoutInfo = {\n    ...combineWidget,\n    x: combineWidget.x + moveEffect.x,\n    y: combineWidget.y + moveEffect.y,\n    w: newW,\n  }\n\n  const result = getDragResult(\n    parentNodeDisplayName,\n    currentLayoutInfo,\n    draggedDisplayNames,\n    mousePositionInfo.mouseRealY,\n    mousePositionInfo.mouseRealX,\n    topHalf,\n    draggedDisplayNames.length > 1 ? currentLayoutInfo.w : 1,\n  )\n\n  const moveEffect2 = {\n    y: (result?.y ?? 0) - combineWidget.y,\n    x: (result?.x ?? 0) - combineWidget.x,\n  }\n\n  if (\n    draggedComponents.length === 1 &&\n    mousePositionInfo.mouseRealY <= combineWidget.y + moveEffect2.y\n  ) {\n    item.alignTop = true\n  }\n\n  if (draggedComponents.length > 1) {\n    item.alignTop =\n      item.alignTop ||\n      mousePositionInfo.mouseRealY <= moveEffect2.y + combineWidget.y\n  }\n\n  if (result) {\n    sendShadowMessageHandler(\n      1,\n      parentNodeDisplayName,\n      draggedDisplayNames,\n      Math.floor(result.w / 2 / unitW),\n      Math.floor(result.previewH / 2 / UNIT_HEIGHT),\n      result.w / 2 / unitW - Math.floor(result.w / 2 / unitW),\n      result.previewH / 2 / UNIT_HEIGHT -\n        Math.floor(result.previewH / 2 / UNIT_HEIGHT),\n      result.x,\n      result.y,\n      result.w,\n      result.previewH,\n    )\n\n    const clamWidgetResult = clamWidgetShape(\n      {\n        ...result,\n        h: result.previewH,\n      },\n      columnNumber,\n      draggedComponents.length > 1,\n    )\n    if (\n      draggedComponents.length > 1 &&\n      columnNumber !== columnNumberWhenDragged &&\n      !canDrop\n    ) {\n      item.dropResult = {\n        shape: undefined,\n        canDrop: false,\n        columnNumberWhenDrag: columnNumberWhenDragged,\n        columnNumberWhenDrop: columnNumber,\n      }\n      return {\n        shape: clamWidgetResult,\n        canDrop: false,\n      }\n    }\n    item.dropResult = {\n      shape: clamWidgetResult,\n      canDrop: true,\n      columnNumberWhenDrag: columnNumberWhenDragged,\n      columnNumberWhenDrop: columnNumber,\n    }\n    return {\n      shape: clamWidgetResult,\n      canDrop: true,\n    }\n  } else {\n    return null\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/utils/getDropResult.ts",
    "content": "import { WidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\nimport { combineWidgetInfos } from \"./getDragShadow\"\n\nexport interface DropResult {\n  widgetLeft: number\n  widgetTop: number\n  widgetWidth: number\n  widgetHeight: number\n  displayName: string\n}\n\nexport const getLayoutInfosWithRelativeCombineShape = (\n  widgetLayoutInfos: WidgetLayoutInfo[],\n) => {\n  const combineShape = combineWidgetInfos(\n    widgetLayoutInfos.map((info) => info.layoutInfo),\n  )\n\n  return widgetLayoutInfos.map((info) => {\n    return {\n      ...info,\n      layoutInfo: {\n        ...info.layoutInfo,\n        x: info.layoutInfo.x - combineShape.x,\n        y: info.layoutInfo.y - combineShape.y,\n      },\n    }\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/utils/sendBinaryMessage.ts",
    "content": "import { getCurrentUser } from \"@illa-public/user-data\"\nimport { throttle } from \"lodash-es\"\nimport { Connection, getBinaryMessagePayload } from \"@/api/ws\"\nimport { Signal, Target } from \"@/api/ws/ILLA_PROTO\"\nimport { ILLARoute } from \"@/router\"\nimport store from \"@/store\"\n\nexport const sendMousePosition = (\n  parentDisplayName: string,\n  cursorXInteger: number,\n  cursorYInteger: number,\n  cursorXMod: number,\n  cursorYMod: number,\n  isLeave: boolean = false,\n) => {\n  if (cursorXInteger < 0 || cursorYInteger < 0) return\n  const appID = ILLARoute.state.matches[0].params.appId\n  const currentUserInfo = getCurrentUser(store.getState())\n  if (!appID || !currentUserInfo.userID) return\n  const ws = Connection.getBinaryRoom(\"app\", appID)\n  const binMessage = getBinaryMessagePayload(\n    Signal.MOVE_CURSOR,\n    Target.CURSOR,\n    true,\n    currentUserInfo.userID,\n    currentUserInfo.nickname,\n    isLeave ? -1 : 1,\n    parentDisplayName,\n    \"\",\n    cursorXInteger,\n    cursorYInteger,\n    cursorXMod,\n    cursorYMod,\n    0,\n    0,\n    0,\n    0,\n  )\n  ws?.send(binMessage)\n}\n\nexport const sendMousePositionHandler = throttle(sendMousePosition, 50, {\n  leading: true,\n  trailing: true,\n})\n\nexport const sendShadowPosition = (\n  status: number,\n  parentDisplayName: string,\n  displayNames: string[],\n  cursorXInteger: number,\n  cursorYInteger: number,\n  cursorXMod: number,\n  cursorYMod: number,\n  widgetX: number,\n  widgetY: number,\n  widgetW: number,\n  widgetH: number,\n) => {\n  if (\n    cursorXInteger < 0 ||\n    cursorYInteger < 0 ||\n    widgetX < 0 ||\n    widgetY < 0 ||\n    widgetW < 0 ||\n    widgetH < 0\n  )\n    return\n  const appID = ILLARoute.state.matches[0].params.appId\n  const currentUserInfo = getCurrentUser(store.getState())\n  if (!appID || !currentUserInfo.userID) return\n  const ws = Connection.getBinaryRoom(\"app\", appID)\n  const binMessage = getBinaryMessagePayload(\n    Signal.MOVE_STATE,\n    Target.COMPONENTS,\n    true,\n    currentUserInfo.userID,\n    currentUserInfo.nickname,\n    status,\n    parentDisplayName,\n    displayNames.join(\",\"),\n    cursorXInteger,\n    cursorYInteger,\n    cursorXMod,\n    cursorYMod,\n    widgetX,\n    widgetY,\n    widgetW,\n    widgetH,\n  )\n  ws?.send(binMessage)\n}\n\nexport const sendShadowMessageHandler = throttle(sendShadowPosition, 50, {\n  leading: true,\n  trailing: true,\n})\n"
  },
  {
    "path": "apps/builder/src/page/App/components/DotPanel/utils.ts",
    "content": "import { DEFAULT_MIN_COLUMN } from \"../ScaleSquare/constant/widget\"\n\ninterface WidgetShape {\n  x: number\n  y: number\n  w: number\n  h: number\n  minW: number\n}\n\nexport const getLargeItemShapeWithNodeScale = (\n  selectedComponents: WidgetShape[],\n) => {\n  const top = Math.min(...selectedComponents.map((item) => item.y))\n  const left = Math.min(...selectedComponents.map((item) => item.x))\n  const bottom = Math.max(...selectedComponents.map((item) => item.y + item.h))\n  const right = Math.max(...selectedComponents.map((item) => item.x + item.w))\n  return {\n    x: left,\n    y: top,\n    w: right - left,\n    h: bottom - top,\n    minW: DEFAULT_MIN_COLUMN,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/EmptySearchResult/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Empty } from \"@illa-design/react\"\nimport EmptySearchIcon from \"@/assets/empty-search-icon.svg?react\"\nimport { EmptySearchResultProps } from \"@/page/App/components/EmptySearchResult/interface\"\nimport { emptyStyle } from \"./style\"\n\nexport const EmptySearchResult: FC<EmptySearchResultProps> = (props) => {\n  const { t } = useTranslation()\n\n  return (\n    <div css={emptyStyle}>\n      <Empty\n        icon={<EmptySearchIcon />}\n        description={props.desc ?? t(\"editor.widget_picker.empty_tip\")}\n      />\n    </div>\n  )\n}\n\nEmptySearchResult.displayName = \"EmptySearchResult\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/EmptySearchResult/interface.ts",
    "content": "export interface EmptySearchResultProps {\n  desc?: string\n}"
  },
  {
    "path": "apps/builder/src/page/App/components/EmptySearchResult/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const emptyStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  padding-top: 122.5px;\n  flex-direction: column;\n  align-items: center;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/Icons/database.tsx",
    "content": "import { createIcon } from \"@illa-design/react\"\n\nconst DatabaseIcon = createIcon({\n  title: \"AIAgentIcon\",\n  viewBox: \"0 0 16 16\",\n  path: (\n    <>\n      <path\n        fillRule=\"evenodd\"\n        clipRule=\"evenodd\"\n        d=\"M8 12.0005C9.80208 12.0005 11.4825 11.5765 12.7465 10.8391C13.1768 10.5882 13.5799 10.2862 13.9228 9.9375C13.9736 10.1208 14 10.3088 14 10.5005C14 12.4335 11.3137 14.0005 8 14.0005C4.68629 14.0005 2 12.4335 2 10.5005C2 10.3088 2.02641 10.1208 2.07721 9.9375C2.42015 10.2862 2.82323 10.5882 3.25349 10.8391C4.51754 11.5765 6.19792 12.0005 8 12.0005Z\"\n        fill=\"#1D2129\"\n      />\n      <path\n        d=\"M14 5C14 6.65685 11.3137 8 8 8C4.68629 8 2 6.65685 2 5C2 3.34315 4.68629 2 8 2C11.3137 2 14 3.34315 14 5Z\"\n        fill=\"#1D2129\"\n      />\n      <path\n        fillRule=\"evenodd\"\n        clipRule=\"evenodd\"\n        d=\"M8 9C9.80208 9 11.4825 8.57602 12.7465 7.83865C13.1768 7.58767 13.5799 7.28575 13.9228 6.93702C13.9736 7.1203 14 7.30835 14 7.5C14 9.433 11.3137 11 8 11C4.68629 11 2 9.433 2 7.5C2 7.30835 2.02641 7.1203 2.07721 6.93702C2.42015 7.28575 2.82323 7.58767 3.25349 7.83865C4.51754 8.57602 6.19792 9 8 9ZM2.5774 6C3.54037 7.18247 5.60652 8 8 8C10.3935 8 12.4596 7.18248 13.4226 6C12.4596 4.81753 10.3935 4 8 4C5.60652 4 3.54037 4.81753 2.5774 6Z\"\n        fill=\"#1D2129\"\n      />\n    </>\n  ),\n})\n\nDatabaseIcon.displayName = \"DatabaseIcon\"\nexport default DatabaseIcon\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/BorderSetter/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { MinusIcon, PlusIcon, getColor } from \"@illa-design/react\"\nimport BorderIcon from \"@/assets/border.svg?react\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { searchDSLByDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport ColorPickerSetter from \"../ColorPickerSetter\"\nimport MeasureCheckInput from \"../InputSetter/MeasureCheckInput\"\nimport { BaseInputSetterProps } from \"../InputSetter/interface\"\nimport { containerStyle, headerContainerStyle } from \"./style\"\n\nconst BorderSetter: FC<BaseInputSetterProps> = (props) => {\n  const { handleUpdateMultiAttrDSL, widgetDisplayName } = props\n\n  const currentWidget = searchDSLByDisplayName(widgetDisplayName)\n\n  const borderWidth = currentWidget?.props?.borderWidth\n  const borderColor = currentWidget?.props?.borderColor\n\n  const hasBorder = !!borderWidth && !!borderColor\n\n  const { t } = useTranslation()\n\n  const handleClickAddBorder = () => {\n    handleUpdateMultiAttrDSL?.({\n      borderWidth: \"1px\",\n      borderColor: getColor(\"white\", \"01\"),\n    })\n  }\n\n  const handleClickDeleteBorder = () => {\n    handleUpdateMultiAttrDSL?.({\n      borderWidth: undefined,\n      borderColor: undefined,\n    })\n  }\n\n  return (\n    <div css={containerStyle}>\n      <div css={headerContainerStyle}>\n        <PanelLabel labelName={t(\"editor.inspect.setter_label.border\")} />\n        {hasBorder ? (\n          <IconHotSpot onClick={handleClickDeleteBorder}>\n            <MinusIcon />\n          </IconHotSpot>\n        ) : (\n          <IconHotSpot onClick={handleClickAddBorder}>\n            <PlusIcon />\n          </IconHotSpot>\n        )}\n      </div>\n      {hasBorder && (\n        <>\n          <ColorPickerSetter\n            labelName={t(\"editor.inspect.setter_group.color\")}\n            value={borderColor}\n            attrName=\"borderColor\"\n            handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n          />\n          <MeasureCheckInput\n            labelName={t(\"editor.inspect.setter_label.border_width\")}\n            value={borderWidth}\n            attrName=\"borderWidth\"\n            handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n            icon={<BorderIcon />}\n          />\n        </>\n      )}\n    </div>\n  )\n}\n\nexport default BorderSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/BorderSetter/interface.ts",
    "content": "export interface BorderSetterProps {}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/BorderSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  padding: 0px 16px;\n  width: 100%;\n`\n\nexport const headerContainerStyle = css`\n  display: flex;\n  width: 100%;\n  justify-content: space-between;\n  align-items: center;\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/CalendarEventListSetter/index.tsx",
    "content": "import { FC } from \"react\"\nimport i18n from \"@/i18n/config\"\nimport OptionListSetter from \"@/page/App/components/InspectPanel/PanelSetters/OptionListSetter\"\nimport { CalendarEventsListSetterProps } from \"./interface\"\n\nconst CalendarEventListSetter: FC<CalendarEventsListSetterProps> = (props) => {\n  return (\n    <OptionListSetter\n      headerName={i18n.t(\"widget.eventCalendar.name.event_calendar\")}\n      itemName=\"Event\"\n      {...props}\n    />\n  )\n}\n\nCalendarEventListSetter.displayName = \"CalendarEventListSetter\"\n\nexport default CalendarEventListSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/CalendarEventListSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { CalendarEventOptionsType } from \"@/widgetLibrary/EventCalendarWidget/interface\"\n\nexport interface CalendarEventsListSetterProps extends BaseSetter {\n  value: CalendarEventOptionsType[]\n  childrenSetter?: PanelFieldConfig[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/CarouselListSetter/index.tsx",
    "content": "import { FC } from \"react\"\nimport { v4 } from \"uuid\"\nimport { Column } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Column\"\nimport { ColumnContainer } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/ColumnContainer\"\nimport { ColumnEmpty } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Empty\"\nimport { CarouselListSetterProps } from \"./interface\"\n\nconst CarouselListSetter: FC<CarouselListSetterProps> = (props) => {\n  const {\n    value,\n    attrName,\n    widgetDisplayName,\n    childrenSetter,\n    handleUpdateMultiAttrDSL,\n  } = props\n\n  return (\n    <ColumnContainer\n      attrName={attrName}\n      value={value}\n      handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n      columnNum={value.length}\n      items={value.map((item) => item.id)}\n      onClickNew={() => {\n        const newItem = {\n          id: `views-${v4()}`,\n          key: `views-${v4()}`,\n          label: `Image ${value.length + 1}`,\n        }\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: [...value, newItem],\n        })\n      }}\n    >\n      {value.length > 0 ? (\n        value.map((item, index) => {\n          return (\n            <Column\n              onCopy={() => {\n                const newItem = {\n                  ...value[index],\n                  id: `views-${v4()}`,\n                  key: `views-${v4()}`,\n                }\n                const updatedArray = [...value, newItem]\n                handleUpdateMultiAttrDSL?.({\n                  [attrName]: updatedArray,\n                })\n              }}\n              onDelete={(id) => {\n                const newV = value.filter((item) => item.id !== id)\n                handleUpdateMultiAttrDSL?.({\n                  [attrName]: newV,\n                })\n              }}\n              showCopy\n              showDelete\n              key={item.id}\n              id={item.id}\n              label={item.label}\n              widgetDisplayName={widgetDisplayName}\n              childrenSetter={childrenSetter}\n              attrPath={`${attrName}.${index}`}\n            />\n          )\n        })\n      ) : (\n        <ColumnEmpty />\n      )}\n    </ColumnContainer>\n  )\n}\n\nCarouselListSetter.displayName = \"CarouselListSetter\"\nexport default CarouselListSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/CarouselListSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { CarouselSettings } from \"@/widgetLibrary/CarouselWidget/interface\"\n\nexport interface CarouselListSetterProps extends BaseSetter {\n  value: CarouselSettings[]\n  childrenSetter?: PanelFieldConfig[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartColorSelectSetter.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport {\n  CHART_COLOR_TYPE_CONFIG_KEYS,\n  CHART__BASE_COLOR_TYPE_CONFIG,\n  ColorArea,\n} from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/listItem\"\nimport { chartColorLabelStyle } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/style\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport BaseSelectSetter from \"../SelectSetter/baseSelect\"\nimport { ChartColorSelectSetterProps } from \"./interface\"\n\ninterface CHartColorLabelProps {\n  color: string\n}\n\nexport const ChartColorLabel: FC<CHartColorLabelProps> = (props) => {\n  const { color } = props\n  return (\n    <div css={chartColorLabelStyle}>\n      <ColorArea color={color} />\n      {color}\n    </div>\n  )\n}\n\nconst ChartColorSelectSetter: FC<ChartColorSelectSetterProps> = (props) => {\n  const { widgetDisplayName } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const chartType = useMemo(() => {\n    return get(targetComponentProps, \"chartType\", \"bar\")\n  }, [targetComponentProps])\n\n  const isCanGroupBy = useMemo(() => {\n    return !!get(targetComponentProps, \"groupBy\", \"\")\n  }, [targetComponentProps])\n\n  const options = useMemo(() => {\n    if (isCanGroupBy || chartType === \"pie\") {\n      return CHART_COLOR_TYPE_CONFIG_KEYS.map((key) => {\n        return {\n          label: <ChartColorLabel color={key} />,\n          value: key,\n        }\n      })\n    }\n    return CHART__BASE_COLOR_TYPE_CONFIG.map((key) => {\n      return {\n        label: <ChartColorLabel color={key} />,\n        value: key,\n      }\n    })\n  }, [chartType, isCanGroupBy])\n\n  return <BaseSelectSetter {...props} options={options} />\n}\n\nChartColorSelectSetter.displayName = \"BaseSelect\"\nexport default ChartColorSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/datasetsContext.tsx",
    "content": "import { klona } from \"klona/json\"\nimport { FC, ReactNode, createContext, useCallback } from \"react\"\nimport { v4 } from \"uuid\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\ninterface ProviderProps {\n  datasets: any[]\n  childrenSetter: PanelFieldConfig[]\n  widgetDisplayName: string\n  attrPath: string\n  handleUpdateDsl: (attrPath: string, value: any) => void\n  children: ReactNode\n}\n\ninterface ContextShape extends Omit<ProviderProps, \"children\"> {\n  handleDeleteDataSet: (index: number) => void\n  handleAddDataSet: () => void\n  handleHiddenDataset: (index: number) => void\n}\n\nexport const DatasetsContext = createContext<ContextShape>({} as ContextShape)\n\nexport const DatasetsProvider: FC<ProviderProps> = (props) => {\n  const { children, datasets, attrPath, handleUpdateDsl } = props\n\n  const handleDeleteDataSet = useCallback(\n    (index: number) => {\n      const updatedArray = datasets.filter(\n        (optionItem: Record<string, any>, i: number) => {\n          return i !== index\n        },\n      )\n      handleUpdateDsl(attrPath, updatedArray)\n    },\n    [datasets, handleUpdateDsl, attrPath],\n  )\n\n  const handleHiddenDataset = useCallback(\n    (index: number) => {\n      let newItem = datasets[index]\n      if (!newItem) return\n      newItem = {\n        ...newItem,\n        isHidden: !newItem.isHidden,\n      }\n      const newDatasets = klona(datasets)\n      newDatasets[index] = newItem\n      handleUpdateDsl(attrPath, newDatasets)\n    },\n    [attrPath, datasets, handleUpdateDsl],\n  )\n\n  const handleAddDataSet = useCallback(async () => {\n    let oldDatasets = Array.isArray(datasets) ? datasets : []\n    const newDatasetItem = {\n      id: v4(),\n      datasetName: \"1\",\n      datasetValues: \"\",\n      aggregationMethod: \"SUM\",\n      type: \"BAR\",\n      color: \"blue\",\n    }\n    handleUpdateDsl(attrPath, [...oldDatasets, newDatasetItem])\n  }, [attrPath, datasets, handleUpdateDsl])\n\n  const value = {\n    ...props,\n    handleAddDataSet,\n    handleDeleteDataSet,\n    handleHiddenDataset,\n  }\n  return (\n    <DatasetsContext.Provider value={value}>\n      {children}\n    </DatasetsContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/index.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { DatasetsProvider } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/datasetsContext\"\nimport { ChartDatasetsSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/interface\"\nimport { generateDatasetItem } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/utils\"\nimport { AddActionLabel } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Label/addActionLabel\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { ListBody } from \"./listBody\"\nimport { chartDataSetterContainerStyle } from \"./style\"\n\nconst ChartDatasetsSetter: FC<ChartDatasetsSetterProps> = (props) => {\n  const {\n    value,\n    childrenSetter,\n    handleUpdateDsl,\n    attrName,\n    widgetDisplayName,\n    labelName,\n    labelDesc,\n  } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const isCanGroupBy = useMemo(() => {\n    return !!get(targetComponentProps, \"groupBy\", \"\")\n  }, [targetComponentProps])\n\n  const chartType = useMemo(() => {\n    return get(targetComponentProps, \"chartType\", \"bar\")\n  }, [targetComponentProps])\n\n  const hasColor = useMemo(() => {\n    if (!Array.isArray(value)) return []\n    return value.map((v) => v.color)\n  }, [value])\n\n  const hasDatasetNames = useMemo(() => {\n    if (!Array.isArray(value)) return []\n    return value.map((v) => v.datasetName)\n  }, [value])\n\n  const handleAddDataSet = useCallback(async () => {\n    let oldDatasets = Array.isArray(value) ? value : []\n    const newDatasetItem = generateDatasetItem(\n      chartType,\n      isCanGroupBy,\n      hasColor,\n      hasDatasetNames,\n    )\n    handleUpdateDsl(attrName, [...oldDatasets, newDatasetItem])\n  }, [\n    attrName,\n    chartType,\n    handleUpdateDsl,\n    hasColor,\n    hasDatasetNames,\n    isCanGroupBy,\n    value,\n  ])\n\n  if (\n    !childrenSetter ||\n    !Array.isArray(childrenSetter) ||\n    childrenSetter.length < 1\n  )\n    return null\n\n  return (\n    <DatasetsProvider\n      attrPath={attrName}\n      handleUpdateDsl={handleUpdateDsl}\n      widgetDisplayName={widgetDisplayName}\n      childrenSetter={childrenSetter}\n      datasets={value}\n    >\n      <div css={chartDataSetterContainerStyle}>\n        <AddActionLabel\n          labelName={labelName}\n          labelDesc={labelDesc}\n          handleAddItem={handleAddDataSet}\n        />\n        <ListBody datasets={value} />\n      </div>\n    </DatasetsProvider>\n  )\n}\n\nChartDatasetsSetter.displayName = \"ChartDatasetsSetter\"\n\nexport default ChartDatasetsSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/interface.ts",
    "content": "import { ChartType } from \"chart.js\"\nimport { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelLabelProps } from \"@/page/App/components/InspectPanel/components/Label/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { CHART_DATASET_AGGREGATION_METHOD } from \"@/widgetLibrary/ChartWidget\"\n\nexport interface ListItemProps {\n  color: string\n  isHidden: boolean\n  datasetName: string\n  datasetMethod: string\n  index: number\n}\n\nexport interface ChartDatasetShape {\n  id: string\n  datasetName: string\n  datasetValues: string\n  aggregationMethod: CHART_DATASET_AGGREGATION_METHOD\n  type: ChartType\n  color: string\n  isHidden: boolean\n}\n\nexport interface ChartDatasetsSetterProps extends BaseSetter, PanelLabelProps {\n  childrenSetter?: PanelFieldConfig[]\n  // TODO: not use any\n  value?: any\n}\n\nexport interface ListBodyProps {\n  datasets: ChartDatasetShape[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/listBody.tsx",
    "content": "import { FC } from \"react\"\nimport { ListBodyProps } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/interface\"\nimport { ListItem } from \"./listItem\"\n\nexport const ListBody: FC<ListBodyProps> = (props) => {\n  const { datasets } = props\n  return (\n    <>\n      {datasets?.map((dataset, index) => {\n        return (\n          <ListItem\n            index={index}\n            key={dataset.id}\n            color={dataset.color}\n            isHidden={dataset.isHidden}\n            datasetMethod={dataset.aggregationMethod}\n            datasetName={dataset.datasetName}\n          />\n        )\n      })}\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/listItem.tsx",
    "content": "import { FC, useCallback, useContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  EyeOffIcon,\n  EyeOnIcon,\n  Trigger,\n  globalColor,\n  illaPrefix,\n  useModal,\n} from \"@illa-design/react\"\nimport DeleteIcon from \"@/assets/delete-dataset-icon.svg?react\"\nimport { DatasetsContext } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/datasetsContext\"\nimport { ListItemProps } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/interface\"\nimport {\n  ListItemWrapperCss,\n  applyColorToneStyle,\n  applyListItemDataNameAreaStyle,\n  applyListItemMethodAreaStyle,\n  applySingleColorAreaStyle,\n  baseIconStyle,\n  colorToneWrapperStyle,\n  eyeIconStyle,\n  listItemActionAreaStyle,\n  listItemInfoAreaStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/style\"\nimport { BaseModal } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal\"\n\nexport const CHART_COLOR_TYPE_CONFIG = {\n  \"illa-preset\": [\n    \"#165DFF\",\n    \"#0FC6C2\",\n    \"#BDFF00\",\n    \"#FAC819\",\n    \"#F18765\",\n    \"#C465F1\",\n  ],\n  \"illa-purple\": [\n    `${globalColor(`--${illaPrefix}-techPurple-n-01`)}`,\n    `${globalColor(`--${illaPrefix}-techPurple-01`)}`,\n    `${globalColor(`--${illaPrefix}-techPurple-02`)}`,\n    `${globalColor(`--${illaPrefix}-techPurple-03`)}`,\n    `${globalColor(`--${illaPrefix}-techPurple-04`)}`,\n    `${globalColor(`--${illaPrefix}-techPurple-06`)}`,\n  ],\n  \"illa-pink\": [\n    `${globalColor(`--${illaPrefix}-techPink-n-01`)}`,\n    `${globalColor(`--${illaPrefix}-techPink-01`)}`,\n    `${globalColor(`--${illaPrefix}-techPink-02`)}`,\n    `${globalColor(`--${illaPrefix}-techPink-03`)}`,\n    `${globalColor(`--${illaPrefix}-techPink-04`)}`,\n    `${globalColor(`--${illaPrefix}-techPink-06`)}`,\n  ],\n  \"cyan-tone\": [\n    \"#09A9AE\",\n    \"#14C9C9\",\n    \"#37D4CF\",\n    \"#5EDFD6\",\n    \"#89E9E0\",\n    \"#BFF4EC\",\n  ],\n  \"green-tone\": [\n    \"#009A29\",\n    \"#00B42A\",\n    \"#23C343\",\n    \"#4CD263\",\n    \"#7BE188\",\n    \"#AFF0B5\",\n  ],\n  \"blue-tone\": [\n    \"#104AE4\",\n    \"#1657FF\",\n    \"#4080FF\",\n    \"#6AA1FF\",\n    \"#94BFFF\",\n    \"#BEDAFF\",\n  ],\n  \"orange-tone\": [\n    \"#E5700E\",\n    \"#FF7D00\",\n    \"#FF9A2E\",\n    \"#FFB65D\",\n    \"#FFCF8B\",\n    \"#FFE4BA\",\n  ],\n  \"yellow-tone\": [\n    \"#E2A214\",\n    \"#F7BA1E\",\n    \"#F9CC45\",\n    \"#FADC6D\",\n    \"#FCE996\",\n    \"#FDF4BF\",\n  ],\n  \"black-tone\": [\n    `${globalColor(`--${illaPrefix}-grayBlue-01`)}`,\n    `${globalColor(`--${illaPrefix}-grayBlue-03`)}`,\n    `${globalColor(`--${illaPrefix}-grayBlue-04`)}`,\n    `${globalColor(`--${illaPrefix}-grayBlue-05`)}`,\n    `${globalColor(`--${illaPrefix}-grayBlue-06`)}`,\n    `${globalColor(`--${illaPrefix}-grayBlue-08`)}`,\n  ],\n}\n\nexport const CHART__BASE_COLOR_TYPE_CONFIG = CHART_COLOR_TYPE_CONFIG[\n  \"illa-preset\"\n].concat([\n  \"#5343D0\",\n  \"#C24499\",\n  \"#09A9AE\",\n  \"#009A29\",\n  \"#104AE4\",\n  \"#E5700E\",\n  \"#E2A214\",\n  \"#0B0C0F\",\n])\n\nexport const CHART_PRESET_COLOR = CHART_COLOR_TYPE_CONFIG[\"illa-preset\"]\nexport const CHART_COLOR_TYPE_CONFIG_KEYS = Object.keys(CHART_COLOR_TYPE_CONFIG)\n\ninterface ColorAreaProps {\n  color: keyof typeof CHART_COLOR_TYPE_CONFIG | string\n}\n\nexport const ColorArea: FC<ColorAreaProps> = ({ color }) => {\n  if (CHART_COLOR_TYPE_CONFIG_KEYS.includes(color)) {\n    const colors =\n      CHART_COLOR_TYPE_CONFIG[color as keyof typeof CHART_COLOR_TYPE_CONFIG]\n    return (\n      <div css={colorToneWrapperStyle}>\n        {colors.map((c) => {\n          return <div css={applyColorToneStyle(c)} key={c} />\n        })}\n      </div>\n    )\n  }\n  return <div css={applySingleColorAreaStyle(color)} />\n}\n\nexport const ListItem: FC<ListItemProps> = (props) => {\n  const { color, isHidden, datasetName, datasetMethod, index } = props\n  const [modalVisible, setModalVisible] = useState(false)\n  const modal = useModal()\n  const { t } = useTranslation()\n\n  const handleCloseModal = useCallback(() => {\n    setModalVisible(false)\n  }, [])\n\n  const {\n    attrPath,\n    widgetDisplayName,\n    childrenSetter,\n    handleHiddenDataset,\n    handleDeleteDataSet,\n  } = useContext(DatasetsContext)\n\n  const handleDeleteClick = useCallback(() => {\n    modal.show({\n      id: \"deleteDatasetItem\",\n      title: t(\"editor.component.delete_title\", {\n        displayName: datasetName,\n      }),\n      children: t(\"editor.component.delete_content\"),\n      cancelText: t(\"editor.component.cancel\"),\n      okText: t(\"editor.component.delete\"),\n      okButtonProps: {\n        colorScheme: \"red\",\n      },\n      onOk: () => {\n        handleDeleteDataSet(index)\n      },\n    })\n  }, [datasetName, handleDeleteDataSet, index, modal, t])\n\n  return (\n    <Trigger\n      withoutPadding\n      colorScheme=\"white\"\n      popupVisible={modalVisible}\n      content={\n        <BaseModal\n          title={datasetName}\n          handleCloseModal={handleCloseModal}\n          attrPath={`${attrPath}.${index}`}\n          widgetDisplayName={widgetDisplayName}\n          childrenSetter={childrenSetter}\n        />\n      }\n      trigger=\"click\"\n      showArrow={false}\n      position=\"left-start\"\n      clickOutsideToClose\n      onVisibleChange={(visible) => {\n        setModalVisible(visible)\n      }}\n    >\n      <div css={ListItemWrapperCss}>\n        <div css={listItemInfoAreaStyle}>\n          <ColorArea color={color} />\n          <span css={applyListItemDataNameAreaStyle(isHidden)}>\n            {datasetName}\n          </span>\n          <span css={applyListItemMethodAreaStyle(isHidden)}>\n            {datasetMethod}\n          </span>\n        </div>\n        <div css={listItemActionAreaStyle}>\n          {isHidden ? (\n            <EyeOffIcon\n              css={baseIconStyle}\n              onClick={(e) => {\n                e.stopPropagation()\n                handleHiddenDataset(index)\n              }}\n            />\n          ) : (\n            <EyeOnIcon\n              css={eyeIconStyle}\n              id=\"eyeOnIcon\"\n              onClick={(e) => {\n                e.stopPropagation()\n                handleHiddenDataset(index)\n              }}\n            />\n          )}\n          <DeleteIcon\n            css={baseIconStyle}\n            onClick={(e) => {\n              e.stopPropagation()\n              handleDeleteClick()\n            }}\n          />\n        </div>\n      </div>\n    </Trigger>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const chartDataSetterContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n  padding: 8px 16px;\n`\n\nexport const ListItemWrapperCss = css`\n  height: 32px;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  :hover {\n    #eyeOnIcon {\n      visibility: visible;\n    }\n  }\n`\n\nexport const applySingleColorAreaStyle = (color: string) => {\n  return css`\n    width: 24px;\n    height: 24px;\n    border-radius: 12px;\n    background-color: ${color};\n    border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  `\n}\n\nexport const listItemInfoAreaStyle = css`\n  height: 100%;\n  width: 200px;\n  display: flex;\n  align-items: center;\n  padding-right: 8px;\n  border-radius: 8px;\n  cursor: pointer;\n  :hover {\n    background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  }\n`\n\nexport const applyListItemDataNameAreaStyle = (\n  isHidden: boolean,\n): SerializedStyles => {\n  return css`\n    width: 80px;\n    white-space: nowrap;\n    line-height: 24px;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    margin: 0 8px;\n    font-size: 14px;\n    flex: none;\n    color: ${isHidden\n      ? globalColor(`--${illaPrefix}-grayBlue-05`)\n      : globalColor(`--${illaPrefix}-grayBlue-02`)};\n  `\n}\n\nexport const applyListItemMethodAreaStyle = (\n  isHidden: boolean,\n): SerializedStyles => {\n  return css`\n    width: 64px;\n    line-height: 24px;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    font-size: 14px;\n    flex: none;\n    color: ${isHidden\n      ? globalColor(`--${illaPrefix}-grayBlue-05`)\n      : globalColor(`--${illaPrefix}-grayBlue-03`)};\n  `\n}\n\nexport const baseIconStyle = css`\n  font-size: 16px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  cursor: pointer;\n  :hover {\n    color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  }\n`\n\nexport const eyeIconStyle = css`\n  visibility: hidden;\n  ${baseIconStyle}\n`\n\nexport const listItemActionAreaStyle = css`\n  width: 48px;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n`\n\nexport const colorToneWrapperStyle = css`\n  width: 24px;\n  height: 12px;\n  border-radius: 2px;\n  display: flex;\n  overflow: hidden;\n`\n\nexport const applyColorToneStyle = (color: string) => {\n  return css`\n    width: 100%;\n    height: 100%;\n    background-color: ${color};\n  `\n}\n\nexport const editModalStyle = css`\n  width: 272px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/utils.tsx",
    "content": "import { ChartType } from \"chart.js\"\nimport { difference } from \"lodash-es\"\nimport { v4 } from \"uuid\"\nimport { CHART_COLOR_TYPE_CONFIG } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/listItem\"\nimport { CHART_DATASET_AGGREGATION_METHOD } from \"@/widgetLibrary/ChartWidget\"\n\nexport let datasetNameSet = new Set<string>()\n\nconst generateDatasetName = () => {\n  let i = 1\n  let datasetName = `Dataset ${i}`\n  while (datasetNameSet.has(datasetName)) {\n    i++\n    datasetName = `Dataset ${i}`\n  }\n  return datasetName\n}\n\nexport const generateDatasetItem = (\n  chartType: ChartType,\n  isGroup: boolean,\n  hasColor: string[],\n  hasDatasetNames: string[],\n) => {\n  const presetColor = CHART_COLOR_TYPE_CONFIG[\"illa-preset\"]\n  let color: string | string[] =\n    presetColor[hasColor.length % presetColor.length]\n  if (isGroup || chartType === \"pie\") {\n    color = \"illa-preset\"\n  } else {\n    if (hasColor.length <= presetColor.length) {\n      const diff = difference(presetColor, hasColor)\n      if (diff.length > 0) {\n        color = diff[0]\n      }\n    } else {\n      color = presetColor[hasColor.length % presetColor.length]\n    }\n  }\n\n  datasetNameSet = new Set<string>(hasDatasetNames)\n\n  const datasetName = generateDatasetName()\n\n  return {\n    id: v4(),\n    datasetName: datasetName,\n    datasetValues: \"\",\n    aggregationMethod: CHART_DATASET_AGGREGATION_METHOD.SUM,\n    type: chartType,\n    color: color,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartKeysDynamicSelectSetter.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { ChartDatasetShape } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/interface\"\nimport { CHART_PRESET_COLOR } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/listItem\"\nimport { ChartDataSourceSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/interface\"\nimport BaseDynamicSelect from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/baseDynamicSelect\"\nimport { publicPaddingStyle } from \"@/page/App/components/InspectPanel/style\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { getExecutionError } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { formatDataAsObject } from \"@/utils/formatData\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst ChartKeysDynamicSelectSetter: FC<ChartDataSourceSetterProps> = (\n  props,\n) => {\n  const {\n    widgetDisplayName,\n    attrName,\n    value,\n    labelName,\n    labelDesc,\n    panelConfig,\n    handleUpdateMultiAttrDSL,\n  } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const insertValues = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const targetComponentNode = searchComponentFromMap(\n        getComponentMap(rootState),\n        widgetDisplayName,\n      )\n      if (!targetComponentNode) return {}\n      return targetComponentNode.props || {}\n    },\n  )\n\n  const isDataSourceDynamic = useMemo(() => {\n    const dataSourceMode = get(targetComponentProps, \"dataSourceMode\", \"select\")\n    return dataSourceMode === \"dynamic\"\n  }, [targetComponentProps])\n\n  const dataSources = useMemo(() => {\n    let originDataSources = get(targetComponentProps, \"dataSource\", [])\n    if (isDataSourceDynamic) {\n      originDataSources = get(targetComponentProps, \"dataSourceJS\", [])\n    }\n\n    return formatDataAsObject(originDataSources)\n  }, [isDataSourceDynamic, targetComponentProps])\n\n  const selectedOptions = useMemo(() => {\n    if (!isObject(dataSources)) return []\n    let options = Object.keys(dataSources).map((key) => key)\n    if (attrName === \"groupBy\" && value) {\n      options.unshift(\"—\")\n    }\n    return options\n  }, [attrName, dataSources, value])\n\n  const datasets: ChartDatasetShape[] = useMemo(() => {\n    return get(insertValues, \"datasets\", [])\n  }, [insertValues])\n\n  const generateNewDatasets = useCallback(\n    (isGroupBy: boolean) => {\n      if (!datasets.length) return []\n      if (isGroupBy) {\n        return datasets.map((dataset) => {\n          return {\n            ...dataset,\n            color: \"illa-preset\",\n          }\n        })\n      }\n      return datasets.map((dataset, index) => {\n        return {\n          ...dataset,\n          color: CHART_PRESET_COLOR[index % CHART_PRESET_COLOR.length],\n        }\n      })\n    },\n    [datasets],\n  )\n\n  const handleUpdateDsl = useCallback(\n    (attrName: string, newValue: any) => {\n      if (attrName === \"groupBy\") {\n        if ((!!value && !newValue) || (!value && !!newValue)) {\n          const newDatasets = generateNewDatasets(!!newValue)\n          handleUpdateMultiAttrDSL?.({\n            datasets: newDatasets,\n            [attrName]: newValue === \"—\" ? undefined : newValue,\n          })\n        } else {\n          handleUpdateMultiAttrDSL?.({\n            [attrName]: newValue === \"—\" ? undefined : newValue,\n          })\n        }\n      } else {\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: newValue,\n        })\n      }\n    },\n    [generateNewDatasets, handleUpdateMultiAttrDSL, value],\n  )\n\n  const executionErrors = useSelector(getExecutionError)\n  const isError = useMemo(() => {\n    return (\n      (executionErrors[`${widgetDisplayName}.${attrName}JS`] ?? [])?.length > 0\n    )\n  }, [attrName, executionErrors, widgetDisplayName])\n\n  const isDynamic = useMemo(() => {\n    const dataSourceMode = get(\n      targetComponentProps,\n      `${widgetDisplayName}.${attrName}JS`,\n      \"select\",\n    )\n    return dataSourceMode === \"dynamic\"\n  }, [attrName, targetComponentProps, widgetDisplayName])\n\n  const finalValue = useMemo(() => {\n    return get(panelConfig, attrName, \"\")\n  }, [attrName, panelConfig])\n\n  const handleClickFxButton = useCallback(() => {\n    const isInOption = selectedOptions.some((value) => value === finalValue)\n    if (isDynamic) {\n      handleUpdateDsl(`${widgetDisplayName}.${attrName}JS`, \"select\")\n      if (!isInOption) {\n        handleUpdateDsl(attrName, \"\")\n      } else {\n        handleUpdateDsl(attrName, finalValue)\n      }\n    } else {\n      handleUpdateDsl(`${widgetDisplayName}.${attrName}JS`, \"dynamic\")\n      if (isInOption) {\n        handleUpdateDsl(attrName, finalValue)\n      }\n    }\n  }, [\n    selectedOptions,\n    isDynamic,\n    finalValue,\n    handleUpdateDsl,\n    widgetDisplayName,\n    attrName,\n  ])\n\n  const handleChangeSelect = useCallback(\n    (value: string) => {\n      handleUpdateDsl?.(attrName, value)\n    },\n    [attrName, handleUpdateDsl],\n  )\n\n  const handleChangeInput = useCallback(\n    (value: string) => {\n      handleUpdateDsl(attrName, value)\n    },\n    [attrName, handleUpdateDsl],\n  )\n\n  return (\n    <div css={publicPaddingStyle}>\n      <BaseDynamicSelect\n        {...props}\n        isDynamic={isDynamic}\n        options={selectedOptions}\n        onClickFxButton={handleClickFxButton}\n        onChangeSelect={handleChangeSelect}\n        value={finalValue}\n        onChangeInput={handleChangeInput}\n        expectedType={VALIDATION_TYPES.STRING}\n        path={`${widgetDisplayName}.${attrName}`}\n        labelName={labelName}\n        labelDesc={labelDesc}\n        isError={isError}\n      />\n    </div>\n  )\n}\n\nChartKeysDynamicSelectSetter.displayName = \"ChartXAxisSetter2\"\n\nexport default ChartKeysDynamicSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartKeysSelectSetter.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { ChartDatasetShape } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/interface\"\nimport { CHART_PRESET_COLOR } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/listItem\"\nimport { ChartDataSourceSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/interface\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { formatDataAsObject } from \"@/utils/formatData\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport SearchSelectSetter from \"../SelectSetter/searchSelect\"\n\nconst ChartKeysSelectSetter: FC<ChartDataSourceSetterProps> = (props) => {\n  const { widgetDisplayName, attrName, value, handleUpdateMultiAttrDSL } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const insertValues = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const targetComponentNode = searchComponentFromMap(\n        getComponentMap(rootState),\n        widgetDisplayName,\n      )\n      if (!targetComponentNode) return {}\n      return targetComponentNode.props || {}\n    },\n  )\n\n  const isDataSourceDynamic = useMemo(() => {\n    const dataSourceMode = get(targetComponentProps, \"dataSourceMode\", \"select\")\n    return dataSourceMode === \"dynamic\"\n  }, [targetComponentProps])\n\n  const dataSources = useMemo(() => {\n    let originDataSources = get(targetComponentProps, \"dataSource\", [])\n    if (isDataSourceDynamic) {\n      originDataSources = get(targetComponentProps, \"dataSourceJS\", [])\n    }\n\n    return formatDataAsObject(originDataSources)\n  }, [isDataSourceDynamic, targetComponentProps])\n\n  const selectedOptions = useMemo(() => {\n    if (!isObject(dataSources)) return []\n    let options = Object.keys(dataSources).map((key) => key)\n    if (attrName === \"groupBy\" && value) {\n      options.unshift(\"—\")\n    }\n    return options\n  }, [attrName, dataSources, value])\n\n  const datasets: ChartDatasetShape[] = useMemo(() => {\n    return get(insertValues, \"datasets\", [])\n  }, [insertValues])\n\n  const generateNewDatasets = useCallback(\n    (isGroupBy: boolean) => {\n      if (!datasets.length) return []\n      if (isGroupBy) {\n        return datasets.map((dataset) => {\n          return {\n            ...dataset,\n            color: \"illa-preset\",\n          }\n        })\n      }\n      return datasets.map((dataset, index) => {\n        return {\n          ...dataset,\n          color: CHART_PRESET_COLOR[index % CHART_PRESET_COLOR.length],\n        }\n      })\n    },\n    [datasets],\n  )\n\n  const handleUpdateDsl = useCallback(\n    (attrName: string, newValue: any) => {\n      if (attrName === \"groupBy\") {\n        if ((!!value && !newValue) || (!value && !!newValue)) {\n          const newDatasets = generateNewDatasets(!!newValue)\n          handleUpdateMultiAttrDSL?.({\n            datasets: newDatasets,\n            [attrName]: newValue === \"—\" ? undefined : newValue,\n          })\n        } else {\n          handleUpdateMultiAttrDSL?.({\n            [attrName]: newValue === \"—\" ? undefined : newValue,\n          })\n        }\n      } else {\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: newValue,\n        })\n      }\n    },\n    [generateNewDatasets, handleUpdateMultiAttrDSL, value],\n  )\n\n  return (\n    <SearchSelectSetter\n      {...props}\n      options={selectedOptions}\n      handleUpdateDsl={handleUpdateDsl}\n    />\n  )\n}\n\nChartKeysSelectSetter.displayName = \"ChartXAxisSetter\"\n\nexport default ChartKeysSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartTypeSelectSetter.tsx",
    "content": "import { ChartType } from \"chart.js\"\nimport { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport BarChartIcon from \"@/assets/chart/bar-chart.svg?react\"\nimport DoughnutIcon from \"@/assets/chart/doughnut-chart.svg?react\"\nimport LineChartIcon from \"@/assets/chart/line-chart.svg?react\"\nimport PieChartIcon from \"@/assets/chart/pie-chart.svg?react\"\nimport RadarIcon from \"@/assets/chart/radar-chart.svg?react\"\nimport ScatterPlotIcon from \"@/assets/chart/scatter-plot.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { ChartDatasetShape } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/interface\"\nimport { CHART_PRESET_COLOR } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/listItem\"\nimport {\n  chartTypeIconCss,\n  chartTypeStringCss,\n  chatOptionContainerStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/style\"\nimport BaseSelectSetter from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/baseSelect\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { RootState } from \"@/store\"\nimport { ChartTypeSelectSetterProps } from \"./interface\"\n\nconst typeOptions = [\n  {\n    label: (\n      <div css={chatOptionContainerStyle}>\n        <BarChartIcon css={chartTypeIconCss} />\n        <span css={chartTypeStringCss}>\n          {i18n.t(\"editor.inspect.setter_content.chart_type.bar\")}\n        </span>\n      </div>\n    ),\n    value: \"bar\",\n  },\n  {\n    label: (\n      <div css={chatOptionContainerStyle}>\n        <LineChartIcon css={chartTypeIconCss} />\n        <span css={chartTypeStringCss}>\n          {i18n.t(\"editor.inspect.setter_content.chart_type.line\")}\n        </span>\n      </div>\n    ),\n    value: \"line\",\n  },\n  {\n    label: (\n      <div css={chatOptionContainerStyle}>\n        <ScatterPlotIcon css={chartTypeIconCss} />\n        <span css={chartTypeStringCss}>\n          {i18n.t(\"editor.inspect.setter_content.chart_type.scatterplot\")}\n        </span>\n      </div>\n    ),\n    value: \"scatter\",\n  },\n  {\n    label: (\n      <div css={chatOptionContainerStyle}>\n        <PieChartIcon css={chartTypeIconCss} />\n        <span css={chartTypeStringCss}>\n          {i18n.t(\"editor.inspect.setter_content.chart_type.pie\")}\n        </span>\n      </div>\n    ),\n    value: \"pie\",\n  },\n  {\n    label: (\n      <div css={chatOptionContainerStyle}>\n        <DoughnutIcon css={chartTypeIconCss} />\n        <span css={chartTypeStringCss}>\n          {i18n.t(\"editor.inspect.setter_option.chart.chart-type.Doughnut\")}\n        </span>\n      </div>\n    ),\n    value: \"doughnut\",\n  },\n  {\n    label: (\n      <div css={chatOptionContainerStyle}>\n        <RadarIcon css={chartTypeIconCss} />\n        <span css={chartTypeStringCss}>\n          {i18n.t(\"editor.inspect.setter_option.chart.chart-type.Radar\")}\n        </span>\n      </div>\n    ),\n    value: \"radar\",\n  },\n]\n\nconst ChartTypeSelectSetter: FC<ChartTypeSelectSetterProps> = (props) => {\n  const { widgetDisplayName, handleUpdateMultiAttrDSL } = props\n\n  const insertValues = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const targetComponentNode = searchComponentFromMap(\n        getComponentMap(rootState),\n        widgetDisplayName,\n      )\n      if (!targetComponentNode) return {}\n      return targetComponentNode.props || {}\n    },\n  )\n\n  const datasets: ChartDatasetShape[] = useMemo(() => {\n    return get(insertValues, \"datasets\", [])\n  }, [insertValues])\n\n  const isCanGroupBy = useMemo(() => {\n    return !!get(insertValues, \"groupBy\", \"\")\n  }, [insertValues])\n\n  const generateNewDatasets = useCallback(\n    (chartType: ChartType) => {\n      if (!datasets.length) return []\n      if (!isCanGroupBy && chartType !== \"pie\") {\n        return datasets.map((dataset, index) => {\n          return {\n            ...dataset,\n            type: chartType,\n            color: CHART_PRESET_COLOR[index % CHART_PRESET_COLOR.length],\n          }\n        })\n      } else {\n        return datasets.map((dataset) => {\n          return {\n            ...dataset,\n            type: chartType,\n            color: \"illa-preset\",\n          }\n        })\n      }\n    },\n    [datasets, isCanGroupBy],\n  )\n\n  const handleUpdateDsl = useCallback(\n    (attrName: string, value: any) => {\n      const newDatasets = generateNewDatasets(value)\n      handleUpdateMultiAttrDSL?.({\n        datasets: newDatasets,\n        [attrName]: value,\n      })\n    },\n    [generateNewDatasets, handleUpdateMultiAttrDSL],\n  )\n\n  return (\n    <BaseSelectSetter\n      {...props}\n      handleUpdateDsl={handleUpdateDsl}\n      options={typeOptions}\n    />\n  )\n}\n\nChartTypeSelectSetter.displayName = \"ChartTypeSelectSetter\"\nexport default ChartTypeSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/interface.ts",
    "content": "import { BaseSelectSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/interface\"\nimport { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelLabelProps } from \"@/page/App/components/InspectPanel/components/Label/interface\"\n\nexport interface ChartDataSourceSetterProps\n  extends BaseSetter,\n    PanelLabelProps {\n  allowClear?: boolean\n  value: string\n}\n\nexport interface ChartColorSelectSetterProps extends BaseSetter {\n  value: string\n}\n\nexport interface ChartTypeSelectSetterProps extends BaseSelectSetterProps {}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ChartSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const chartTypeIconCss = css`\n  font-size: 16px;\n`\n\nexport const chartTypeStringCss = css`\n  font-size: 14px;\n  margin-left: 4px;\n`\n\nexport const chartColorLabelStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const chatOptionContainerStyle = css`\n  display: flex;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ColorPickerSetter/index.tsx",
    "content": "import { FC } from \"react\"\nimport ColorSetter from \"@/components/ColorSetter\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { ColorPickerSetterProps } from \"./interface\"\nimport { setterContainerStyle } from \"./style\"\n\nconst ColorPickerSetter: FC<ColorPickerSetterProps> = (props) => {\n  const {\n    labelName,\n    labelDesc,\n    handleUpdateMultiAttrDSL,\n    value,\n    defaultValue,\n    attrName,\n    labelSize = \"small\",\n  } = props\n\n  const handleUpdateBorderColor = (currentColor: string) => {\n    handleUpdateMultiAttrDSL?.({\n      [attrName]: currentColor,\n    })\n  }\n\n  return (\n    <div css={setterContainerStyle}>\n      <PanelLabel\n        labelName={labelName}\n        labelDesc={labelDesc}\n        labelSize={labelSize}\n      />\n      <ColorSetter\n        handleUpdateColor={handleUpdateBorderColor}\n        value={value ?? defaultValue}\n        setterSize={labelSize}\n      />\n    </div>\n  )\n}\n\nexport default ColorPickerSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ColorPickerSetter/interface.ts",
    "content": "export interface ColorPickerSetterProps {\n  value: string\n  defaultValue?: string\n  handleUpdateMultiAttrDSL?: (updateSlice: Record<string, any>) => void\n  attrName: string\n  labelName?: string\n  labelDesc?: string\n  labelSize?: \"medium\" | \"small\"\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ColorPickerSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const setterContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 8px 0;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/context/viewsListContext.tsx",
    "content": "import { ComponentMapNode } from \"@illa-public/public-types\"\nimport { klona } from \"klona/json\"\nimport { get } from \"lodash-es\"\nimport { FC, ReactNode, createContext, useCallback, useMemo } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { newGenerateChildrenComponentNode } from \"@/utils/generators/generateComponentNode\"\nimport { BasicContainerConfig } from \"@/widgetLibrary/BasicContainer/BasicContainer\"\nimport { ViewItemShape } from \"../interface\"\nimport {\n  generateNewViewItem,\n  generateViewItemId,\n} from \"../utils/generateNewOptions\"\n\ninterface ProviderProps {\n  viewsList: ViewItemShape[]\n  childrenSetter: PanelFieldConfig[]\n  widgetDisplayName: string\n  attrPath: string\n  componentNode: ComponentMapNode\n  handleUpdateDsl: (attrPath: string, value: any) => void\n  handleUpdateMultiAttrDSL?: (updateSlice: Record<string, any>) => void\n  handleUpdateExecutionResult?: (\n    displayName: string,\n    updateSlice: Record<string, any>,\n  ) => void\n  handleUpdateOtherMultiAttrDSL?: (\n    displayName: string,\n    updateSlice: Record<string, any>,\n  ) => void\n  children: ReactNode\n}\n\ninterface Inject extends Omit<ProviderProps, \"children\"> {\n  currentViewIndex: number\n  handleDeleteOptionItem: (index: number) => void\n  handleCopyOptionItem: (index: number) => void\n  handleUpdateCurrentViewIndex: (index: number) => void\n  handleMoveOptionItem: (dragIndex: number, hoverIndex: number) => void\n}\n\nexport const ViewListSetterContext = createContext<Inject>({} as Inject)\n\nexport const ViewListSetterProvider: FC<ProviderProps> = (props) => {\n  const {\n    viewsList,\n    attrPath,\n    widgetDisplayName,\n    handleUpdateMultiAttrDSL,\n    handleUpdateExecutionResult,\n    componentNode,\n  } = props\n  const dispatch = useDispatch()\n  const executionResult = useSelector(getExecutionResult)\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const allViews = useMemo(() => {\n    return get(\n      executionResult,\n      `${widgetDisplayName}.${attrPath}`,\n      [],\n    ) as ViewItemShape[]\n  }, [attrPath, executionResult, widgetDisplayName])\n\n  const linkWidgetDisplayName = useMemo(() => {\n    return get(targetComponentProps, \"linkWidgetDisplayName\", \"\") as string\n  }, [targetComponentProps])\n\n  const currentViewIndex = useMemo(() => {\n    return get(executionResult, `${widgetDisplayName}.currentIndex`)\n  }, [executionResult, widgetDisplayName])\n\n  const allViewsKeys = useMemo(() => {\n    return allViews.map((view) => view.key)\n  }, [allViews])\n\n  const handleDeleteOptionItem = useCallback(\n    (index: number) => {\n      if (viewsList.length <= 1) return\n      const updatedArray = viewsList.filter(\n        (optionItem: Record<string, any>, i: number) => {\n          return i !== index\n        },\n      )\n\n      const currentChildrenNodeDisplayName = componentNode.childrenNode[index]\n\n      const updateSlice = {\n        [attrPath]: updatedArray,\n        currentIndex: 0,\n        currentKey: allViewsKeys[0],\n      }\n\n      if (currentViewIndex !== index) {\n        const oldCurrentViewKey = viewsList[currentViewIndex].key\n        const newCurrentViewIndex = updatedArray.findIndex(\n          (item) => item.key === oldCurrentViewKey,\n        )\n        if (newCurrentViewIndex !== -1) {\n          updateSlice.currentIndex = newCurrentViewIndex\n          updateSlice.currentKey = oldCurrentViewKey\n        }\n      }\n\n      handleUpdateMultiAttrDSL?.(updateSlice)\n      dispatch(\n        componentsActions.deleteComponentNodeReducer({\n          displayNames: [currentChildrenNodeDisplayName],\n        }),\n      )\n    },\n    [\n      allViewsKeys,\n      attrPath,\n      componentNode.childrenNode,\n      currentViewIndex,\n      dispatch,\n      handleUpdateMultiAttrDSL,\n      viewsList,\n    ],\n  )\n\n  const handleCopyOptionItem = useCallback(\n    (index: number) => {\n      let targetOptionItem = viewsList.find(\n        (optionItem: Record<string, any>, i: number) => {\n          return i === index\n        },\n      )\n      if (!targetOptionItem) return\n      const newChildrenNodes = newGenerateChildrenComponentNode(\n        BasicContainerConfig,\n        componentNode.displayName,\n      )\n      const newItem = generateNewViewItem(allViewsKeys)\n      targetOptionItem = {\n        ...targetOptionItem,\n        key: newItem.key,\n        id: generateViewItemId(),\n      }\n      const updatedArray = [...viewsList, targetOptionItem]\n      handleUpdateMultiAttrDSL?.({\n        [attrPath]: updatedArray,\n      })\n      dispatch(componentsActions.addComponentReducer([newChildrenNodes]))\n    },\n    [\n      allViewsKeys,\n      attrPath,\n      componentNode.displayName,\n      dispatch,\n      handleUpdateMultiAttrDSL,\n      viewsList,\n    ],\n  )\n\n  const handleUpdateCurrentViewIndex = useCallback(\n    (index: number) => {\n      if (index > viewsList.length || index < 0) return\n      const currentViewKey = allViews[index].key\n      handleUpdateExecutionResult?.(widgetDisplayName, {\n        currentIndex: index,\n        currentKey: currentViewKey || index,\n      })\n      if (linkWidgetDisplayName) {\n        if (Array.isArray(linkWidgetDisplayName)) {\n          linkWidgetDisplayName.forEach((linkDisplayName) => {\n            handleUpdateExecutionResult?.(linkDisplayName, {\n              currentIndex: index,\n              currentKey: currentViewKey || index,\n            })\n          })\n        } else {\n          handleUpdateExecutionResult?.(linkWidgetDisplayName, {\n            currentIndex: index,\n            currentKey: currentViewKey || index,\n          })\n          const linkWidgetLinkedDisplayName = get(\n            executionResult,\n            `${linkWidgetDisplayName}.linkWidgetDisplayName`,\n            [],\n          )\n          linkWidgetLinkedDisplayName &&\n            Array.isArray(linkWidgetLinkedDisplayName) &&\n            linkWidgetLinkedDisplayName.forEach((name) => {\n              name !== widgetDisplayName &&\n                handleUpdateExecutionResult?.(name, {\n                  currentIndex: index,\n                  currentKey: currentViewKey || index,\n                })\n            })\n        }\n      }\n    },\n    [\n      allViews,\n      executionResult,\n      handleUpdateExecutionResult,\n      linkWidgetDisplayName,\n      viewsList.length,\n      widgetDisplayName,\n    ],\n  )\n\n  const handleMoveOptionItem = useCallback(\n    (dragIndex: number, hoverIndex: number) => {\n      const dragOptionItem = viewsList[dragIndex]\n      const currentSelected = viewsList[currentViewIndex]\n      const newComponentNode = klona(componentNode.childrenNode)\n      ;[newComponentNode[dragIndex], newComponentNode[hoverIndex]] = [\n        newComponentNode[hoverIndex],\n        newComponentNode[dragIndex],\n      ]\n      const newViews = [...viewsList]\n      newViews.splice(dragIndex, 1)\n      newViews.splice(hoverIndex, 0, dragOptionItem)\n      const newSelectedIndex = newViews.findIndex(\n        (view) => view.key === currentSelected.key,\n      )\n      const newSelectedKey = newViews[newSelectedIndex].key\n      handleUpdateMultiAttrDSL?.({\n        [attrPath]: newViews,\n        currentIndex: newSelectedIndex,\n        currentKey: newSelectedKey,\n      })\n      dispatch(\n        componentsActions.sortComponentNodeChildrenReducer({\n          parentDisplayName: componentNode.displayName,\n          newChildrenNode: newComponentNode,\n        }),\n      )\n    },\n    [\n      attrPath,\n      componentNode.childrenNode,\n      componentNode.displayName,\n      currentViewIndex,\n      dispatch,\n      handleUpdateMultiAttrDSL,\n      viewsList,\n    ],\n  )\n  const value = {\n    ...props,\n    handleDeleteOptionItem,\n    handleCopyOptionItem,\n    currentViewIndex,\n    handleUpdateCurrentViewIndex,\n    handleMoveOptionItem,\n  }\n\n  return (\n    <ViewListSetterContext.Provider value={value}>\n      {props.children}\n    </ViewListSetterContext.Provider>\n  )\n}\n\nViewListSetterProvider.displayName = \"OptionListSetterProvider\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/dragIconAndLabel.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, MouseEvent, useCallback, useContext, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport {\n  DragPointIcon,\n  Trigger,\n  WarningCircleIcon,\n  globalColor,\n  illaPrefix,\n} from \"@illa-design/react\"\nimport { ViewListSetterContext } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/context/viewsListContext\"\nimport {\n  DragIconAndLabelProps,\n  ViewItemShape,\n} from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/interface\"\nimport {\n  applyOptionStyle,\n  labelAndDragIconWrapperStyle,\n  labelWrapperStyle,\n  moveIconStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/style\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\n\ninterface optionIconProps {\n  isSelected: boolean\n  onClick: (e: MouseEvent<HTMLDivElement>) => void\n}\n\nconst OptionIcon: FC<optionIconProps> = ({ isSelected, onClick }) => {\n  return <div css={applyOptionStyle(isSelected)} onClick={onClick} />\n}\n\nexport const DragIconAndLabel: FC<DragIconAndLabelProps> = (props) => {\n  const { index, label, isSelected } = props\n  const { widgetDisplayName, attrPath, handleUpdateCurrentViewIndex } =\n    useContext(ViewListSetterContext)\n\n  const { t } = useTranslation()\n  const executionResult = useSelector(getExecutionResult)\n\n  const currentViews = useMemo(() => {\n    return get(executionResult, `${widgetDisplayName}.${attrPath}.${index}`, {})\n  }, [attrPath, executionResult, index, widgetDisplayName])\n\n  const otherViewKeys = useMemo(() => {\n    const allViews = get(\n      executionResult,\n      `${widgetDisplayName}.${attrPath}`,\n      [],\n    ) as ViewItemShape[]\n    return allViews\n      .map((views, i) => views.key || i)\n      .filter((key, i) => i != index)\n  }, [attrPath, executionResult, index, widgetDisplayName])\n\n  const isDuplicationKey = useMemo(() => {\n    return otherViewKeys.some((viewKey) => viewKey == currentViews.key)\n  }, [otherViewKeys, currentViews])\n\n  const handleChangeCurrentView = useCallback(\n    (e: MouseEvent<HTMLDivElement>) => {\n      e.stopPropagation()\n      handleUpdateCurrentViewIndex(index)\n    },\n    [handleUpdateCurrentViewIndex, index],\n  )\n\n  return (\n    <span css={labelAndDragIconWrapperStyle}>\n      <DragPointIcon css={moveIconStyle} id=\"dragIcon\" />\n      <div css={labelWrapperStyle}>\n        <OptionIcon isSelected={isSelected} onClick={handleChangeCurrentView} />\n        <span style={{ maxWidth: \"147px\" }}>{label}</span>\n        {isDuplicationKey && (\n          <Trigger\n            trigger=\"hover\"\n            showArrow={false}\n            position=\"bottom\"\n            content={`${t(\"widget.container.key_duplicated\")}`}\n          >\n            <WarningCircleIcon\n              color={globalColor(`--${illaPrefix}-orange-03`)}\n            />\n          </Trigger>\n        )}\n      </div>\n    </span>\n  )\n}\n\nDragIconAndLabel.displayName = \"DragIconAndLabel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/header.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { AddIcon, Button } from \"@illa-design/react\"\nimport {\n  HeaderLabelStyle,\n  HeaderWrapperStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/style\"\n\nexport interface HeaderProps {\n  labelName: string\n  addAction: () => void\n  hasAddAction: boolean\n}\n\nexport const Header: FC<HeaderProps> = (props) => {\n  const { t } = useTranslation()\n  const { labelName, addAction, hasAddAction } = props\n  return (\n    <div css={HeaderWrapperStyle}>\n      <span css={HeaderLabelStyle}>{labelName}</span>\n      {hasAddAction && (\n        <Button\n          leftIcon={<AddIcon />}\n          colorScheme=\"techPurple\"\n          variant=\"text\"\n          onClick={addAction}\n        >\n          {t(\"editor.inspect.setter_content.column_setter.new\")}\n        </Button>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/index.tsx",
    "content": "import { ComponentMapNode } from \"@illa-public/public-types\"\nimport { get } from \"lodash-es\"\nimport { FC, memo, useCallback, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { ViewListSetterProvider } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/context/viewsListContext\"\nimport { Header } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/header\"\nimport {\n  ViewItemShape,\n  ViewSetterProps,\n} from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/interface\"\nimport { ListBody } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/listBody\"\nimport {\n  setterPublicWrapper,\n  viewSetterWrapperStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/style\"\nimport { generateNewViewItem } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/utils/generateNewOptions\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport store, { RootState } from \"@/store\"\nimport { newGenerateChildrenComponentNode } from \"@/utils/generators/generateComponentNode\"\nimport { BasicContainerConfig } from \"@/widgetLibrary/BasicContainer/BasicContainer\"\n\nconst ViewsSetter: FC<ViewSetterProps> = memo((props: ViewSetterProps) => {\n  const {\n    value,\n    attrName,\n    widgetDisplayName,\n    childrenSetter,\n    handleUpdateExecutionResult,\n    handleUpdateMultiAttrDSL,\n    handleUpdateOtherMultiAttrDSL,\n    componentNode,\n  } = props\n  const { t } = useTranslation()\n  const executionResult = useSelector(getExecutionResult)\n  const dispatch = useDispatch()\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const linkWidgetDisplayName = useMemo(() => {\n    return get(targetComponentProps, \"linkWidgetDisplayName\", \"\") as string\n  }, [targetComponentProps])\n\n  const allViews = useMemo(() => {\n    return get(\n      executionResult,\n      `${widgetDisplayName}.${attrName}`,\n      [],\n    ) as ViewItemShape[]\n  }, [attrName, executionResult, widgetDisplayName])\n\n  const allViewsKeys = useMemo(() => {\n    return allViews.map((view) => view.key)\n  }, [allViews])\n\n  const updateMultiAttrDSL = useCallback(\n    (updateSlice: Record<string, unknown>) => {\n      handleUpdateMultiAttrDSL?.(updateSlice)\n      if (linkWidgetDisplayName) {\n        if (Array.isArray(linkWidgetDisplayName)) {\n          linkWidgetDisplayName.forEach((linkDisplayName) => {\n            handleUpdateOtherMultiAttrDSL?.(linkDisplayName, updateSlice)\n          })\n        } else {\n          handleUpdateOtherMultiAttrDSL?.(linkWidgetDisplayName, updateSlice)\n          const linkWidgetLinkedDisplayName = get(\n            executionResult,\n            `${linkWidgetDisplayName}.linkWidgetDisplayName`,\n            [],\n          )\n          linkWidgetLinkedDisplayName &&\n            Array.isArray(linkWidgetLinkedDisplayName) &&\n            linkWidgetLinkedDisplayName.forEach((name) => {\n              name !== widgetDisplayName &&\n                handleUpdateOtherMultiAttrDSL?.(name, updateSlice)\n            })\n        }\n      }\n    },\n    [\n      executionResult,\n      handleUpdateMultiAttrDSL,\n      handleUpdateOtherMultiAttrDSL,\n      linkWidgetDisplayName,\n      widgetDisplayName,\n    ],\n  )\n\n  const handleUpdateDsl = useCallback(\n    (attrName: string, value: any) => {\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: value,\n      })\n      if (linkWidgetDisplayName) {\n        if (Array.isArray(linkWidgetDisplayName)) {\n          linkWidgetDisplayName.forEach((linkDisplayName) => {\n            handleUpdateOtherMultiAttrDSL?.(linkDisplayName, {\n              [attrName]: value,\n            })\n          })\n        } else {\n          handleUpdateOtherMultiAttrDSL?.(linkWidgetDisplayName, {\n            [attrName]: value,\n          })\n          const linkWidgetLinkedDisplayName = get(\n            executionResult,\n            `${linkWidgetDisplayName}.linkWidgetDisplayName`,\n            [],\n          )\n          linkWidgetLinkedDisplayName &&\n            Array.isArray(linkWidgetLinkedDisplayName) &&\n            linkWidgetLinkedDisplayName.forEach((name) => {\n              name !== widgetDisplayName &&\n                handleUpdateOtherMultiAttrDSL?.(name, {\n                  [attrName]: value,\n                })\n            })\n        }\n      }\n    },\n    [\n      handleUpdateMultiAttrDSL,\n      linkWidgetDisplayName,\n      handleUpdateOtherMultiAttrDSL,\n      executionResult,\n      widgetDisplayName,\n    ],\n  )\n\n  const _componentNode = useMemo(() => {\n    if (componentNode.type === \"CONTAINER_WIDGET\") {\n      return componentNode\n    }\n    const finalNode = searchComponentFromMap(\n      getComponentMap(store.getState()),\n      linkWidgetDisplayName,\n    )\n    if (finalNode?.type === \"CONTAINER_WIDGET\") return finalNode\n    return {} as ComponentMapNode\n  }, [componentNode, linkWidgetDisplayName])\n\n  const handleAddViewItem = useCallback(() => {\n    const newItem = generateNewViewItem(allViewsKeys)\n    const newChildrenNodes = newGenerateChildrenComponentNode(\n      BasicContainerConfig,\n      _componentNode?.displayName,\n    )\n    handleUpdateMultiAttrDSL?.({\n      [attrName]: [...value, newItem],\n    })\n    if (linkWidgetDisplayName) {\n      if (Array.isArray(linkWidgetDisplayName)) {\n        linkWidgetDisplayName.forEach((linkDisplayName) => {\n          handleUpdateOtherMultiAttrDSL?.(linkDisplayName, {\n            [attrName]: [...value, newItem],\n          })\n        })\n      } else {\n        handleUpdateOtherMultiAttrDSL?.(linkWidgetDisplayName, {\n          [attrName]: [...value, newItem],\n        })\n        const linkWidgetLinkedDisplayName = get(\n          executionResult,\n          `${linkWidgetDisplayName}.linkWidgetDisplayName`,\n          [],\n        )\n        linkWidgetLinkedDisplayName &&\n          Array.isArray(linkWidgetLinkedDisplayName) &&\n          linkWidgetLinkedDisplayName.forEach((name) => {\n            name !== widgetDisplayName &&\n              handleUpdateOtherMultiAttrDSL?.(name, {\n                [attrName]: [...value, newItem],\n              })\n          })\n      }\n    }\n    dispatch(componentsActions.addComponentReducer([newChildrenNodes]))\n  }, [\n    _componentNode?.displayName,\n    allViewsKeys,\n    attrName,\n    dispatch,\n    executionResult,\n    handleUpdateMultiAttrDSL,\n    handleUpdateOtherMultiAttrDSL,\n    linkWidgetDisplayName,\n    value,\n    widgetDisplayName,\n  ])\n\n  return (\n    <ViewListSetterProvider\n      viewsList={value}\n      childrenSetter={childrenSetter || []}\n      widgetDisplayName={widgetDisplayName}\n      attrPath={attrName}\n      handleUpdateDsl={handleUpdateDsl}\n      handleUpdateMultiAttrDSL={updateMultiAttrDSL}\n      handleUpdateExecutionResult={handleUpdateExecutionResult}\n      handleUpdateOtherMultiAttrDSL={handleUpdateOtherMultiAttrDSL}\n      componentNode={_componentNode}\n    >\n      <div css={setterPublicWrapper}>\n        <div css={viewSetterWrapperStyle}>\n          <Header\n            labelName={t(\"editor.inspect.setter_content.view_setter.views\")}\n            addAction={handleAddViewItem}\n            hasAddAction\n          />\n          <ListBody />\n        </div>\n      </div>\n    </ViewListSetterProvider>\n  )\n})\n\nViewsSetter.displayName = \"ViewsSetter\"\n\nexport default ViewsSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/interface.ts",
    "content": "import { ComponentMapNode } from \"@illa-public/public-types\"\nimport { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface ViewItemShape {\n  id: string\n  key: string\n  label: string\n  disabled?: string\n  hidden?: string\n}\n\nexport interface ViewSetterProps extends BaseSetter {\n  value: ViewItemShape[]\n  childrenSetter?: PanelFieldConfig[]\n  componentNode: ComponentMapNode\n}\n\nexport interface DragIconAndLabelProps {\n  index: number\n  label?: string\n  isSelected: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/listBody.tsx",
    "content": "import { AnimatePresence, Reorder } from \"framer-motion\"\nimport { isEqual, omit } from \"lodash-es\"\nimport {\n  FC,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useState,\n} from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { ViewListSetterContext } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/context/viewsListContext\"\nimport { ViewItemShape } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/interface\"\nimport { removeNativeStyle } from \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/style\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { ListItem } from \"./listItem\"\n\ninterface ItemsProps extends ViewItemShape {\n  childrenNode?: string\n}\n\nexport const ListBody: FC = () => {\n  const dispatch = useDispatch()\n  const {\n    viewsList,\n    componentNode,\n    currentViewIndex,\n    attrPath,\n    handleUpdateMultiAttrDSL,\n  } = useContext(ViewListSetterContext)\n\n  const originItems: ItemsProps[] = viewsList.map((view, index) => {\n    if (Array.isArray(componentNode.childrenNode)) {\n      return { ...view, childrenNode: componentNode.childrenNode[index] }\n    }\n    return { ...view, childrenNode: \"\" }\n  })\n\n  const [items, setItems] = useState<ItemsProps[]>(originItems)\n  const currentSelected = useMemo(\n    () => viewsList[currentViewIndex],\n    [viewsList, currentViewIndex],\n  )\n\n  const onDragEnd = useCallback(() => {\n    const newComponentNode: string[] = []\n    const newViewList: ViewItemShape[] = []\n    items.forEach((item) => {\n      item?.childrenNode && newComponentNode.push(item.childrenNode)\n      newViewList.push(omit(item, [\"childrenNode\"]))\n    })\n    const newSelectedIndex = newViewList.findIndex(\n      (view) => view.key === currentSelected.key,\n    )\n    const newSelectedKey = newViewList[newSelectedIndex].key\n    handleUpdateMultiAttrDSL?.({\n      [attrPath]: newViewList,\n      currentIndex: newSelectedIndex,\n      currentKey: newSelectedKey,\n    })\n    dispatch(\n      componentsActions.sortComponentNodeChildrenReducer({\n        parentDisplayName: componentNode.displayName,\n        newChildrenNode: newComponentNode,\n      }),\n    )\n  }, [\n    items,\n    handleUpdateMultiAttrDSL,\n    attrPath,\n    dispatch,\n    componentNode.displayName,\n    currentSelected?.key,\n  ])\n\n  useEffect(() => {\n    if (!isEqual(viewsList, items)) {\n      setItems(\n        viewsList.map((view, index) => {\n          if (Array.isArray(componentNode.childrenNode)) {\n            return { ...view, childrenNode: componentNode.childrenNode[index] }\n          }\n          return { ...view, childrenNode: \"\" }\n        }),\n      )\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [componentNode.childrenNode, viewsList])\n\n  const updateItem = (values: ItemsProps[]) => {\n    if (isEqual(values, items)) return\n    setItems(values)\n  }\n\n  if (!Array.isArray(viewsList)) return null\n\n  return (\n    <AnimatePresence initial={false}>\n      <Reorder.Group\n        axis=\"y\"\n        initial={false}\n        values={items}\n        onReorder={updateItem}\n        css={removeNativeStyle}\n      >\n        {items.map((item, index) => {\n          const { id, label, key } = item\n          return (\n            <Reorder.Item\n              initial={false}\n              css={removeNativeStyle}\n              key={item.id}\n              value={item}\n              onDragEnd={onDragEnd}\n            >\n              <ListItem\n                value={item}\n                label={label}\n                key={id}\n                index={index}\n                isSelected={key === currentSelected?.key}\n              />\n            </Reorder.Item>\n          )\n        })}\n      </Reorder.Group>\n    </AnimatePresence>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/listItem.tsx",
    "content": "import { FC, useCallback, useContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { CopyIcon, ReduceIcon, Trigger } from \"@illa-design/react\"\nimport { ViewListSetterContext } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/context/viewsListContext\"\nimport { DragIconAndLabel } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/dragIconAndLabel\"\nimport { ViewItemShape } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/interface\"\nimport {\n  actionWrapperStyle,\n  copyIconStyle,\n  iconStyle,\n  listItemTriggerWrapperStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/style\"\nimport { BaseModal } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal\"\nimport { SelectedProvider } from \"@/page/App/components/InspectPanel/context/selectedContext\"\nimport { getComponentNodeBySingleSelected } from \"@/redux/currentApp/components/componentsSelector\"\n\ninterface ListItemProps {\n  value: ViewItemShape\n  index: number\n  label?: string\n  isSelected: boolean\n}\n\nexport const ListItem: FC<ListItemProps> = (props) => {\n  const { label, index, isSelected } = props\n  const [modalVisible, setModalVisible] = useState(false)\n  const {\n    handleDeleteOptionItem,\n    handleCopyOptionItem,\n    attrPath,\n    widgetDisplayName,\n    childrenSetter,\n    handleUpdateDsl,\n    handleUpdateMultiAttrDSL,\n    handleUpdateOtherMultiAttrDSL,\n  } = useContext(ViewListSetterContext)\n  const { t } = useTranslation()\n\n  const handleCloseModal = useCallback(() => {\n    setModalVisible(false)\n  }, [])\n\n  const singleSelectedComponentNode = useSelector(\n    getComponentNodeBySingleSelected,\n  )\n\n  const widgetType = singleSelectedComponentNode?.type || \"\"\n  const widgetParentDisplayName = singleSelectedComponentNode?.parentNode || \"\"\n  const widgetProps = singleSelectedComponentNode?.props || {}\n\n  return (\n    <Trigger\n      withoutPadding\n      colorScheme=\"white\"\n      popupVisible={modalVisible}\n      content={\n        <SelectedProvider\n          widgetType={widgetType}\n          widgetDisplayName={widgetDisplayName}\n          widgetParentDisplayName={widgetParentDisplayName}\n          widgetProps={widgetProps}\n          handleUpdateDsl={handleUpdateDsl}\n          handleUpdateMultiAttrDSL={(updateSlice) => {\n            handleUpdateMultiAttrDSL?.(updateSlice)\n          }}\n          handleUpdateOtherMultiAttrDSL={(displayName, updateSlice) => {\n            handleUpdateOtherMultiAttrDSL?.(displayName, updateSlice)\n          }}\n          widgetOrAction=\"WIDGET\"\n        >\n          <BaseModal\n            title={t(\"editor.inspect.setter_content.option_list.model_title\")}\n            handleCloseModal={handleCloseModal}\n            attrPath={`${attrPath}.${index}`}\n            widgetDisplayName={widgetDisplayName}\n            childrenSetter={childrenSetter}\n          />\n        </SelectedProvider>\n      }\n      trigger=\"click\"\n      showArrow={false}\n      position=\"left\"\n      clickOutsideToClose\n      onVisibleChange={(visible) => {\n        setModalVisible(visible)\n      }}\n    >\n      <span css={listItemTriggerWrapperStyle}>\n        <DragIconAndLabel index={index} label={label} isSelected={isSelected} />\n        <span css={actionWrapperStyle}>\n          <CopyIcon\n            css={copyIconStyle}\n            id=\"copyIcon\"\n            onClick={(e) => {\n              e.stopPropagation()\n              handleCopyOptionItem(index)\n            }}\n          />\n          <ReduceIcon\n            css={iconStyle}\n            onClick={(e) => {\n              e.stopPropagation()\n              handleDeleteOptionItem(index)\n            }}\n          />\n        </span>\n      </span>\n    </Trigger>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const setterPublicWrapper = css`\n  padding: 8px 16px;\n  width: 100%;\n`\n\nexport const viewSetterWrapperStyle = css`\n  width: 100%;\n  border-radius: 8px;\n  border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n`\n\nexport const HeaderWrapperStyle = css`\n  width: 100%;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  padding: 8px 8px 8px 16px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n`\n\nexport const HeaderLabelStyle = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  font-weight: 500;\n  font-size: 14px;\n`\n\nexport const applyOptionStyle = (isSelect: boolean) => {\n  return css`\n    width: 16px;\n    height: 16px;\n    border-radius: 8px;\n    border: ${isSelect\n      ? `4px solid ${globalColor(`--${illaPrefix}-techPurple-03`)}`\n      : `2px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)}`};\n    cursor: pointer;\n  `\n}\n\nexport const labelAndDragIconWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  flex: 0;\n`\n\nexport const labelWrapperStyle = css`\n  display: flex;\n  gap: 8px;\n  align-items: center;\n  white-space: nowrap;\n`\n\nexport const actionWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 16px;\n`\n\nexport const iconStyle = css`\n  cursor: pointer;\n  width: 16px;\n  height: 16px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const copyIconStyle = css`\n  ${iconStyle};\n  visibility: hidden;\n`\n\nexport const moveIconStyle = css`\n  cursor: move;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  width: 16px;\n  height: 16px;\n  visibility: hidden;\n`\n\nexport const listItemTriggerWrapperStyle = css`\n  width: 100%;\n  height: 40px;\n  padding: 9px 16px 9px 0;\n  display: flex;\n  justify-content: space-between;\n  user-select: none;\n  :hover {\n    #dragIcon {\n      visibility: visible;\n    }\n    #copyIcon {\n      visibility: visible;\n    }\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/utils/generateNewOptions.ts",
    "content": "import { v4 } from \"uuid\"\nimport { ViewItemShape } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/interface\"\n\nexport let viewNameSet = new Set<string>()\n\nconst generateDatasetName = () => {\n  let i = 1\n  let ViewName = `View ${i}`\n  while (viewNameSet.has(ViewName)) {\n    i++\n    ViewName = `View ${i}`\n  }\n  return ViewName\n}\n\nexport const generateViewItemId = () => `views-${v4()}`\n\nexport const generateNewViewItem = (\n  hasViewNameSet: string[],\n): ViewItemShape => {\n  viewNameSet = new Set<string>(hasViewNameSet)\n  const viewName = generateDatasetName()\n\n  return {\n    id: generateViewItemId(),\n    key: viewName,\n    label: viewName,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/defaultViewKeySetter.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { ViewItemShape } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/interface\"\nimport { ContainerDefaultViewKeySetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/interface\"\nimport BaseInput from \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/BaseInput\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\n\nconst ContainerDefaultViewKeySetter: FC<ContainerDefaultViewKeySetterProps> = (\n  props,\n) => {\n  const {\n    handleUpdateMultiAttrDSL,\n    handleUpdateOtherMultiAttrDSL,\n    widgetDisplayName,\n  } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const realViews = useMemo(() => {\n    return get(targetComponentProps, \"viewList\", []) as ViewItemShape[]\n  }, [targetComponentProps])\n\n  const linkWidgetDisplayName = useMemo(() => {\n    return get(targetComponentProps, \"linkWidgetDisplayName\")\n  }, [targetComponentProps])\n\n  const handleUpdateDefaultView = useCallback(\n    (attrPath: string, value: string) => {\n      const defaultViewIndex = realViews.findIndex((view) => view.key === value)\n      let currentIndex = 0\n      let currentKey = realViews[currentIndex].key\n      if (defaultViewIndex > -1) {\n        currentIndex = defaultViewIndex\n        currentKey = realViews[currentIndex].key\n      }\n      handleUpdateMultiAttrDSL?.({\n        [attrPath]: value,\n        currentIndex,\n        currentKey,\n      })\n      if (linkWidgetDisplayName && Array.isArray(linkWidgetDisplayName)) {\n        linkWidgetDisplayName.forEach((name) => {\n          handleUpdateOtherMultiAttrDSL?.(name, {\n            currentIndex,\n            currentKey,\n          })\n        })\n      }\n    },\n    [\n      realViews,\n      linkWidgetDisplayName,\n      handleUpdateMultiAttrDSL,\n      handleUpdateOtherMultiAttrDSL,\n    ],\n  )\n\n  return <BaseInput {...props} handleUpdateDsl={handleUpdateDefaultView} />\n}\n\nContainerDefaultViewKeySetter.displayName = \"ContainerDefaultViewKeySetter\"\nexport default ContainerDefaultViewKeySetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ContainerSetter/interface.ts",
    "content": "import { BaseInputSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/interface\"\n\nexport interface ContainerDefaultViewKeySetterProps\n  extends BaseInputSetterProps {}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnButtonGroupSetter/index.tsx",
    "content": "import { get, isString } from \"lodash-es\"\nimport { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { v4 } from \"uuid\"\nimport { Column } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Column\"\nimport { ColumnContainer } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/ColumnContainer\"\nimport { ColumnEmpty } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Empty\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { ColumnButtonGroupSetterProps, GroupButton } from \"./interface\"\n\nconst ColumnButtonGroupSetter: FC<ColumnButtonGroupSetterProps> = (props) => {\n  const {\n    attrName,\n    handleUpdateMultiAttrDSL,\n    childrenSetter,\n    value,\n    widgetDisplayName,\n  } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const executeValue: GroupButton[] =\n    get(targetComponentProps, attrName, undefined) ?? []\n\n  return (\n    <ColumnContainer\n      hideTitle\n      columnNum={value?.length ?? 0}\n      onClickNew={() => {\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: [\n            ...(value ?? []),\n            {\n              id: v4(),\n              mappedValue: \"Button\",\n              colorScheme: \"blue\",\n            } as GroupButton,\n          ],\n        })\n      }}\n      attrName={attrName}\n      value={value}\n      handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n      items={value?.map((v) => v.id) ?? []}\n    >\n      {value && value.length > 0 ? (\n        value.map((v, index) => {\n          return (\n            <Column\n              key={v.id}\n              label={\n                isString(executeValue[index].mappedValue)\n                  ? executeValue[index].mappedValue\n                  : JSON.stringify(executeValue[index].mappedValue)\n              }\n              showDelete={true}\n              showVisible={false}\n              attrPath={`${attrName}.${index}`}\n              childrenSetter={childrenSetter}\n              onDelete={(id) => {\n                const finalColumns = value.filter((item) => item.id !== id)\n                handleUpdateMultiAttrDSL?.({\n                  [attrName]: finalColumns,\n                })\n              }}\n              id={v.id}\n              widgetDisplayName={widgetDisplayName}\n            />\n          )\n        })\n      ) : (\n        <ColumnEmpty />\n      )}\n    </ColumnContainer>\n  )\n}\n\nColumnButtonGroupSetter.displayName = \"ColumnButtonGroupSetter\"\n\nexport default ColumnButtonGroupSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnButtonGroupSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface ColumnButtonGroupSetterProps extends BaseSetter {\n  value?: GroupButton[]\n  childrenSetter?: PanelFieldConfig[]\n}\n\nexport interface GroupButton {\n  id: string\n  mappedValue: string\n  disabled?: boolean\n  colorScheme: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnMappedInput/index.tsx",
    "content": "import { hasDynamicStringSnippet } from \"@illa-public/dynamic-string\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { get, isString } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport {\n  getNeedComputedValueWithDataList,\n  realInputValueWithDataList,\n} from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/utils\"\nimport {\n  applyInputSetterWrapperStyle,\n  setterContainerStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/BaseInput/style\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ColumnMappedInputProps } from \"./interface\"\n\nconst ColumnMappedInput: FC<ColumnMappedInputProps> = (props) => {\n  const {\n    isSetterSingleRow,\n    placeholder,\n    attrName,\n    handleUpdateDsl,\n    expectedType,\n    value,\n    widgetDisplayName,\n    labelName,\n    detailedDescription,\n    defaultValue,\n    labelDesc,\n    widgetType,\n    wrappedCodeFunc,\n    labelSize,\n    onlyHasSetter = false,\n  } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const dataSourceMode = get(targetComponentProps, \"dataSourceMode\", \"dynamic\")\n\n  const finalWrapperCode = useMemo(() => {\n    if (\n      hasDynamicStringSnippet(value ?? \"\") &&\n      isString(value) &&\n      value?.includes(\"currentRow\")\n    ) {\n      return (value: string) => {\n        return getNeedComputedValueWithDataList(\n          value,\n          widgetDisplayName,\n          dataSourceMode,\n        )\n      }\n    }\n    return wrappedCodeFunc\n  }, [value, wrappedCodeFunc, widgetDisplayName, dataSourceMode])\n\n  const finalValue = useMemo(() => {\n    const v = value ?? defaultValue\n\n    if (widgetDisplayName && isString(v) && v.includes(\"currentRow\")) {\n      return realInputValueWithDataList(\n        value ?? defaultValue,\n        widgetDisplayName,\n      )\n    }\n\n    if (value === undefined && defaultValue === undefined) {\n      return undefined\n    }\n    if (!isString(value ?? defaultValue)) {\n      return `{{ ${value ?? defaultValue} }}`\n    }\n    return value ?? defaultValue\n  }, [widgetDisplayName, value, defaultValue])\n\n  const onChange = useCallback(\n    (value: string) => {\n      let output = value\n      if (\n        hasDynamicStringSnippet(value ?? \"\") &&\n        value.includes(\"currentRow\")\n      ) {\n        output = getNeedComputedValueWithDataList(\n          value,\n          widgetDisplayName,\n          dataSourceMode,\n        )\n        handleUpdateDsl(attrName, output)\n      } else {\n        if (output === \"\") {\n          handleUpdateDsl(attrName, undefined)\n        } else {\n          handleUpdateDsl(attrName, output)\n        }\n      }\n    },\n    [attrName, dataSourceMode, handleUpdateDsl, widgetDisplayName],\n  )\n\n  const onFocus = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.FOCUS, {\n      element: \"component_inspect_code_mirror\",\n      parameter1: widgetType,\n      parameter2: attrName,\n    })\n  }, [attrName, widgetType])\n\n  const onBlur = useCallback(\n    (value: string) => {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n        element: \"component_inspect_code_mirror\",\n        parameter1: widgetType,\n        parameter2: attrName,\n        parameter3: value.length,\n      })\n    },\n    [attrName, widgetType],\n  )\n\n  return (\n    <div css={setterContainerStyle(isSetterSingleRow, onlyHasSetter)}>\n      {!onlyHasSetter && labelName && (\n        <span>\n          <PanelLabel\n            labelName={labelName}\n            labelDesc={labelDesc}\n            labelSize={labelSize}\n          />\n        </span>\n      )}\n      <div css={applyInputSetterWrapperStyle(isSetterSingleRow)}>\n        <CodeEditor\n          scopeOfAutoComplete=\"page\"\n          value={finalValue}\n          onChange={onChange}\n          showLineNumbers={false}\n          placeholder={placeholder}\n          expectValueType={expectedType}\n          lang={CODE_LANG.JAVASCRIPT}\n          maxHeight=\"208px\"\n          maxWidth=\"100%\"\n          codeType={CODE_TYPE.EXPRESSION}\n          modalTitle={labelName}\n          modalDescription={detailedDescription ?? labelDesc}\n          onFocus={onFocus}\n          onBlur={onBlur}\n          wrappedCodeFunc={finalWrapperCode}\n        />\n      </div>\n    </div>\n  )\n}\n\nColumnMappedInput.displayName = \"ColumnMappedInput\"\nexport default ColumnMappedInput\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnMappedInput/interface.ts",
    "content": "import { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface ColumnMappedInputProps {\n  isSetterSingleRow?: boolean\n  placeholder?: string\n  attrName: string\n  defaultValue?: any\n  handleUpdateDsl: (attrPath: string, value: any) => void\n  expectedType?: VALIDATION_TYPES\n  value?: unknown\n  widgetDisplayName: string\n  labelName?: string\n  detailedDescription?: string\n  labelDesc?: string\n  widgetType: string\n  wrappedCodeFunc?: (code: string) => string\n  labelSize?: \"medium\" | \"small\"\n  onlyHasSetter?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnMappedSelect/index.tsx",
    "content": "import { hasDynamicStringSnippet } from \"@illa-public/dynamic-string\"\nimport { get, isString } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Select } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport {\n  getNeedComputedValueWithDataList,\n  realInputValueWithDataList,\n} from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/utils\"\nimport { DynamicIcon } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/DynamicIcon\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport {\n  getExecutionError,\n  getExecutionResult,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { ColumnMappedSelectProps } from \"./interface\"\nimport {\n  basicDynamicSetterContainerStyle,\n  dynamicSelectHeaderStyle,\n  dynamicSelectSetterStyle,\n} from \"./style\"\n\nconst ColumnMappedSelect: FC<ColumnMappedSelectProps> = (props) => {\n  const {\n    placeholder,\n    attrName,\n    handleUpdateDsl,\n    expectedType,\n    value,\n    widgetDisplayName,\n    labelName,\n    detailedDescription,\n    defaultValue,\n    labelDesc,\n    options,\n    wrappedCodeFunc,\n  } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const isDynamic =\n    get(\n      targetComponentProps,\n      `${widgetDisplayName}.${attrName}JS`,\n      \"select\",\n    ) === \"dynamic\"\n\n  const executionErrors = useSelector(getExecutionError)\n  const isError = useMemo(() => {\n    return (\n      (executionErrors[`${widgetDisplayName}.${attrName}JS`] ?? [])?.length > 0\n    )\n  }, [attrName, executionErrors, widgetDisplayName])\n\n  const handleClickFxButton = useCallback(() => {\n    if (isDynamic) {\n      handleUpdateDsl(`${widgetDisplayName}.${attrName}JS`, \"select\")\n      handleUpdateDsl(attrName, undefined)\n    } else {\n      handleUpdateDsl(`${widgetDisplayName}.${attrName}JS`, \"dynamic\")\n    }\n  }, [attrName, handleUpdateDsl, isDynamic, widgetDisplayName])\n\n  const dataSourceMode = get(targetComponentProps, \"dataSourceMode\", \"dynamic\")\n\n  const finalWrapperCode = useMemo(() => {\n    if (\n      hasDynamicStringSnippet(value ?? \"\") &&\n      isString(value) &&\n      value?.includes(\"currentRow\")\n    ) {\n      return (value: string) => {\n        return getNeedComputedValueWithDataList(\n          value,\n          widgetDisplayName,\n          dataSourceMode,\n        )\n      }\n    }\n    return wrappedCodeFunc\n  }, [value, wrappedCodeFunc, widgetDisplayName, dataSourceMode])\n\n  const finalValue = useMemo(() => {\n    const v = value ?? defaultValue\n\n    if (widgetDisplayName && isString(v) && v.includes(\"currentRow\")) {\n      return realInputValueWithDataList(\n        value ?? defaultValue,\n        widgetDisplayName,\n      )\n    }\n\n    if (value === undefined && defaultValue === undefined) {\n      return undefined\n    }\n    if (!isString(value ?? defaultValue)) {\n      return `{{ ${value ?? defaultValue} }}`\n    }\n    return value ?? defaultValue\n  }, [widgetDisplayName, value, defaultValue])\n\n  const onChange = useCallback(\n    (value: string) => {\n      let output = value\n      if (\n        hasDynamicStringSnippet(value ?? \"\") &&\n        value.includes(\"currentRow\")\n      ) {\n        output = getNeedComputedValueWithDataList(\n          value,\n          widgetDisplayName,\n          dataSourceMode,\n        )\n        handleUpdateDsl(attrName, output)\n      } else {\n        if (output === \"\") {\n          handleUpdateDsl(attrName, undefined)\n        } else {\n          handleUpdateDsl(attrName, output)\n        }\n      }\n    },\n    [attrName, dataSourceMode, handleUpdateDsl, widgetDisplayName],\n  )\n\n  return (\n    <div css={basicDynamicSetterContainerStyle}>\n      <div css={dynamicSelectHeaderStyle}>\n        <PanelLabel labelName={labelName} labelDesc={labelDesc} />\n        <DynamicIcon\n          isDynamic={isDynamic}\n          onClick={handleClickFxButton}\n          hasRightContent={false}\n        />\n      </div>\n      <div css={dynamicSelectSetterStyle}>\n        {isDynamic ? (\n          <CodeEditor\n            value={finalValue ?? \"\"}\n            onChange={onChange}\n            showLineNumbers={false}\n            placeholder={placeholder}\n            expectValueType={expectedType}\n            lang={CODE_LANG.JAVASCRIPT}\n            maxHeight=\"208px\"\n            minHeight=\"30px\"\n            maxWidth=\"100%\"\n            codeType={CODE_TYPE.EXPRESSION}\n            modalTitle={labelName}\n            modalDescription={labelDesc ?? detailedDescription}\n            scopeOfAutoComplete=\"page\"\n            wrappedCodeFunc={finalWrapperCode}\n          />\n        ) : (\n          <Select\n            colorScheme=\"techPurple\"\n            placeholder={placeholder}\n            options={options}\n            value={finalValue}\n            onChange={(v) => handleUpdateDsl?.(attrName, v)}\n            showSearch\n            allowClear\n            error={isError}\n          />\n        )}\n      </div>\n    </div>\n  )\n}\n\nColumnMappedSelect.displayName = \"ColumnMappedSelect\"\nexport default ColumnMappedSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnMappedSelect/interface.ts",
    "content": "import { BaseSelectSetterProps } from \"../../SelectSetter/interface\"\n\nexport interface ColumnMappedSelectProps extends BaseSelectSetterProps {\n  wrappedCodeFunc?: (code: string) => string\n  onlyHasSetter?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnMappedSelect/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const basicDynamicSetterContainerStyle = css`\n  display: flex;\n  padding: 8px 0;\n  flex-direction: column;\n  gap: 8px;\n  width: 100%;\n`\nexport const dynamicSelectHeaderStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n`\nexport const dynamicSelectSetterStyle = css`\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter/Components/UpdateButton/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { RefreshIcon, Trigger } from \"@illa-design/react\"\nimport { UpdateButtonProps } from \"./interface\"\nimport {\n  basicUpdateButtonContainerStyle,\n  updateButtonContainerStyle,\n} from \"./style\"\n\nexport const UpdateButton: FC<UpdateButtonProps> = (props) => {\n  const { onClick } = props\n  const { t } = useTranslation()\n\n  return (\n    <Trigger\n      content={t(\"editor.inspect.setter_tips.grid_list.update\")}\n      position=\"top-start\"\n    >\n      <button css={updateButtonContainerStyle} onClick={onClick}>\n        <RefreshIcon size=\"16px\" />\n        {t(\"editor.inspect.setter_label.grid_list.update\")}\n      </button>\n    </Trigger>\n  )\n}\n\nexport const BasicUpdateButton: FC<UpdateButtonProps> = (props) => {\n  const { onClick } = props\n  const { t } = useTranslation()\n\n  return (\n    <Trigger\n      content={t(\"editor.inspect.setter_tips.grid_list.update\")}\n      position=\"top-start\"\n    >\n      <button css={basicUpdateButtonContainerStyle} onClick={onClick}>\n        <RefreshIcon size=\"16px\" />\n      </button>\n    </Trigger>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter/Components/UpdateButton/interface.ts",
    "content": "export interface UpdateButtonProps {\n  onClick: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter/Components/UpdateButton/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const updateButtonContainerStyle = css`\n  display: flex;\n  padding: 5px 8px;\n  gap: 8px;\n  align-items: center;\n  border: none;\n  background-color: transparent;\n  color: ${getColor(\"orange\", \"03\")};\n  font-size: 14px;\n  cursor: pointer;\n`\n\nexport const basicUpdateButtonContainerStyle = css`\n  padding: 4px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  cursor: pointer;\n  background-color: transparent;\n  border: none;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter/index.tsx",
    "content": "import { arrayMove } from \"@dnd-kit/sortable\"\nimport { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { v4 } from \"uuid\"\nimport { Trigger, WarningCircleIcon, getColor } from \"@illa-design/react\"\nimport { dealRawData2ArrayData } from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/utils\"\nimport { ColumnContainer } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/ColumnContainer\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { getColumnTypeFromValue } from \"@/widgetLibrary/DataGridWidget/columnDeal\"\nimport { UNIQUE_ID_NAME } from \"@/widgetLibrary/DataGridWidget/constants\"\nimport { getColumnsTypeSetter } from \"@/widgetLibrary/DataGridWidget/panelConfig\"\nimport { Column } from \"../../DragMoveComponent/Column\"\nimport { ColumnEmpty } from \"../../DragMoveComponent/Empty\"\nimport { BasicUpdateButton, UpdateButton } from \"./Components/UpdateButton\"\nimport { ColumnConfig, ColumnSetterProps } from \"./interface\"\n\nexport function generateCalcColumnConfig(\n  key: string,\n  isCalc: boolean,\n  randomKey: boolean,\n): ColumnConfig {\n  let field\n  if (key === UNIQUE_ID_NAME) {\n    field = UNIQUE_ID_NAME\n  } else if (randomKey) {\n    field = v4()\n  } else {\n    field = `${key}`\n  }\n  return {\n    field,\n    headerName: `${key}`,\n    width: 170,\n    isCalc: isCalc,\n    description: \"\",\n    sortable: true,\n    pinnable: true,\n    filterable: true,\n    hideable: true,\n    aggregable: true,\n    groupable: true,\n    resizable: true,\n    columnType: \"auto\",\n    disableReorder: false,\n    headerAlign: \"left\",\n  }\n}\n\nconst ColumnSetter: FC<ColumnSetterProps> = (props) => {\n  const {\n    attrName,\n    handleUpdateMultiAttrDSL,\n    value = [],\n    widgetDisplayName,\n  } = props\n\n  const { t } = useTranslation()\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const columnVisibilityModel = get(\n    targetComponentProps,\n    \"columnVisibilityModel\",\n    undefined,\n  )\n\n  const dataSourceMode = get(targetComponentProps, \"dataSourceMode\", \"dynamic\")\n\n  const rawData = get(\n    targetComponentProps,\n    dataSourceMode === \"dynamic\" ? \"dataSourceJS\" : \"dataSource\",\n    undefined,\n  )\n\n  const arrayData: object[] = useMemo(\n    () => dealRawData2ArrayData(rawData),\n    [rawData],\n  )\n\n  const calculateColumnsByDataSource: ColumnConfig[] = useMemo(() => {\n    if (arrayData.length == 0) {\n      return []\n    } else {\n      return Object.keys(arrayData[0]).map((key) => {\n        return generateCalcColumnConfig(key, true, false)\n      })\n    }\n  }, [arrayData])\n\n  const columnIDsByDataSource = useMemo(() => {\n    return calculateColumnsByDataSource\n      .map((item) => item.field)\n      .filter((key) => key !== UNIQUE_ID_NAME)\n  }, [calculateColumnsByDataSource])\n\n  const oldColumnConfigIDs = useMemo(() => {\n    return value\n      .filter((item) => item.isCalc)\n      .map((item) => item.field)\n      .filter((key) => key !== UNIQUE_ID_NAME)\n  }, [value])\n\n  const customColumns = useMemo(() => {\n    return value.filter((item) => !item.isCalc)\n  }, [value])\n\n  const removedColumnIDs: string[] = useMemo(() => {\n    return oldColumnConfigIDs.filter(\n      (item) => !columnIDsByDataSource.includes(item),\n    )\n  }, [oldColumnConfigIDs, columnIDsByDataSource])\n\n  const addedColumnsIDs: string[] = useMemo(() => {\n    return columnIDsByDataSource.filter(\n      (item) => !oldColumnConfigIDs.includes(item),\n    )\n  }, [columnIDsByDataSource, oldColumnConfigIDs])\n\n  const handleMixedColumns = useCallback(() => {\n    if (calculateColumnsByDataSource.length === 0) {\n      return value\n    }\n    const mixedColumnsResult: ColumnConfig[] = []\n\n    calculateColumnsByDataSource.forEach((config) => {\n      const oldConfig = value.find((item) => item.field === config.field)\n      if (oldConfig) {\n        mixedColumnsResult.push(oldConfig)\n      } else {\n        mixedColumnsResult.push(config)\n      }\n    })\n    mixedColumnsResult.push(...customColumns)\n\n    mixedColumnsResult.sort((a, b) => {\n      const aIndex = value.findIndex((item) => item.field === a.field)\n      const bIndex = value.findIndex((item) => item.field === b.field)\n\n      if (aIndex === -1 && bIndex === -1) {\n        return 0\n      }\n      if (aIndex === -1) {\n        return 1\n      }\n\n      if (bIndex === -1) {\n        return -1\n      }\n\n      return aIndex - bIndex\n    })\n\n    handleUpdateMultiAttrDSL?.({\n      [attrName]: mixedColumnsResult,\n    })\n\n    return mixedColumnsResult\n  }, [\n    attrName,\n    calculateColumnsByDataSource,\n    customColumns,\n    handleUpdateMultiAttrDSL,\n    value,\n  ])\n\n  return (\n    <ColumnContainer\n      columnNum={value.length}\n      onDragEnd={(event) => {\n        const { active, over } = event\n        if (active && over && active.id !== over.id) {\n          const oldIndex = value.findIndex((item) => item.field === active.id)\n          const newIndex = value.findIndex((item) => item.field === over.id)\n          const finalColumns = arrayMove(value, oldIndex, newIndex)\n          handleUpdateMultiAttrDSL?.({\n            [attrName]: finalColumns,\n          })\n          return finalColumns\n        }\n      }}\n      onClickNew={() => {\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: [\n            ...value,\n            generateCalcColumnConfig(`column${value.length + 1}`, false, true),\n          ],\n        })\n      }}\n      items={value.map((item) => item.field)}\n      headerExtNode={\n        removedColumnIDs.length > 0 || addedColumnsIDs.length > 0 ? (\n          <UpdateButton onClick={handleMixedColumns} />\n        ) : (\n          <BasicUpdateButton onClick={handleMixedColumns} />\n        )\n      }\n    >\n      {value.length > 0 ? (\n        value.map((config, index) =>\n          config.field === UNIQUE_ID_NAME ? null : (\n            <Column\n              labelTip={\n                removedColumnIDs.length > 0 &&\n                removedColumnIDs.includes(config.field) && (\n                  <Trigger\n                    content={t(\n                      \"editor.inspect.setter_tips.grid_list.no_column\",\n                    )}\n                  >\n                    <WarningCircleIcon color={getColor(\"orange\", \"03\")} />\n                  </Trigger>\n                )\n              }\n              onDelete={(id) => {\n                const finalColumns = value.filter((item) => item.field !== id)\n                handleUpdateMultiAttrDSL?.({\n                  [attrName]: finalColumns,\n                })\n              }}\n              childrenSetter={getColumnsTypeSetter(\n                config.columnType,\n                getColumnTypeFromValue(get(arrayData[0], config.field)),\n              )}\n              showDelete={!config.isCalc}\n              attrPath={`${attrName}.${index}`}\n              widgetDisplayName={widgetDisplayName}\n              key={config.field}\n              id={config.field}\n              showVisible={true}\n              label={config.headerName ?? config.field}\n              visibility={columnVisibilityModel?.[config.field] ?? true}\n              onVisibilityChange={(visibility) => {\n                handleUpdateMultiAttrDSL?.({\n                  [\"columnVisibilityModel\"]: {\n                    ...columnVisibilityModel,\n                    [config.field]: visibility,\n                  },\n                })\n              }}\n            />\n          ),\n        )\n      ) : (\n        <ColumnEmpty />\n      )}\n    </ColumnContainer>\n  )\n}\n\nColumnSetter.displayName = \"ColumnSetter\"\n\nexport default ColumnSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter/interface.ts",
    "content": "import {\n  GridAlignment,\n  GridColType,\n  GridRenderCellParams,\n  GridValueGetterParams,\n} from \"@mui/x-data-grid-premium\"\nimport { ReactNode } from \"react\"\nimport { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\n\nexport type ColumnType =\n  | \"auto\"\n  | \"text\"\n  | \"date\"\n  | \"tag\"\n  | \"datetime\"\n  | \"number\"\n  | \"percent\"\n  | \"link\"\n  | \"button\"\n  | \"buttongroup\"\n  | \"boolean\"\n  | \"image\"\n  | \"avatar\"\n  | \"rating\"\n  | \"markdown\"\n  | \"html\"\n  | \"currency\"\n\nexport interface ColumnConfig {\n  isCalc?: boolean\n  type?: GridColType\n  align?: GridAlignment\n  columnType: ColumnType\n  field: string\n  headerName: string\n  width: number\n  description: string\n  sortable: boolean\n  pinnable: boolean\n  filterable: boolean\n  hideable: boolean\n  aggregable: boolean\n  groupable: boolean\n  resizable: boolean\n  disableReorder: boolean\n  headerAlign: GridAlignment\n  aggregationModel?: string\n  valueGetter?: (params: GridValueGetterParams) => any\n  renderCell?: (params: GridRenderCellParams) => ReactNode\n}\n\nexport interface ColumnSetterProps extends BaseSetter {\n  value: ColumnConfig[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const optionListHeaderStyle = css`\n  width: 100%;\n  background-color: ${getColor(\"grayBlue\", \"09\")};\n  display: flex;\n  align-items: center;\n  height: 40px;\n  box-sizing: border-box;\n  padding: 0 16px;\n`\n\nexport const columnNumStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 600;\n  line-height: 22px;\n`\n\nexport const columnLabelStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  justify-content: space-between;\n  margin: 0 16px 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSwitchSetter/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { get } from \"lodash-es\"\nimport { FC, useCallback } from \"react\"\nimport { Switch } from \"@illa-design/react\"\nimport ColumnMappedInput from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnMappedInput\"\nimport { DynamicIcon } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/DynamicIcon\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ColumnSwitchSetterProps } from \"./interface\"\nimport {\n  applyLabelWrapperStyle,\n  customAndSwitchWrapperStyle,\n  dynamicSwitchWrapperStyle,\n} from \"./style\"\n\nconst ColumnSwitchSetter: FC<ColumnSwitchSetterProps> = (props) => {\n  const {\n    attrName,\n    labelName,\n    labelDesc,\n    panelConfig,\n    handleUpdateDsl,\n    defaultValue,\n    handleUpdateMultiAttrDSL,\n    value,\n    openDynamic,\n    detailedDescription,\n    widgetType,\n  } = props\n\n  const customSelected = get(panelConfig, `${attrName}Dynamic`, false)\n\n  const handleClickDynamicIcon = useCallback(() => {\n    if (customSelected) {\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: undefined,\n        [`${attrName}Dynamic`]: false,\n      })\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"fx\",\n        parameter1: widgetType,\n        parameter2: attrName,\n        parameter3: \"off\",\n      })\n    } else {\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: undefined,\n        [`${attrName}Dynamic`]: true,\n      })\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"fx\",\n        parameter1: widgetType,\n        parameter2: attrName,\n        parameter3: \"on\",\n      })\n    }\n  }, [attrName, customSelected, handleUpdateMultiAttrDSL, widgetType])\n\n  return (\n    <div css={applyLabelWrapperStyle(customSelected)}>\n      <div css={dynamicSwitchWrapperStyle}>\n        {labelName && (\n          <PanelLabel labelName={labelName} labelDesc={labelDesc} />\n        )}\n        <div css={customAndSwitchWrapperStyle}>\n          {openDynamic && (\n            <DynamicIcon\n              isDynamic={customSelected}\n              hasRightContent\n              onClick={handleClickDynamicIcon}\n            />\n          )}\n          {!customSelected && (\n            <Switch\n              defaultValue={defaultValue}\n              onChange={(value) => {\n                handleUpdateDsl(attrName, value)\n                trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                  element: \"component_inspect_radio\",\n                  parameter1: widgetType,\n                  parameter2: attrName,\n                })\n              }}\n              checked={Boolean(value)}\n              colorScheme=\"techPurple\"\n            />\n          )}\n        </div>\n      </div>\n      {customSelected && (\n        <ColumnMappedInput\n          {...props}\n          value={value}\n          isSetterSingleRow\n          detailedDescription={detailedDescription ?? labelDesc}\n          onlyHasSetter={true}\n        />\n      )}\n    </div>\n  )\n}\n\nColumnSwitchSetter.displayName = \"ColumnSwitchSetter\"\n\nexport default ColumnSwitchSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSwitchSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelLabelProps } from \"@/page/App/components/InspectPanel/components/Label/interface\"\n\nexport interface ColumnSwitchSetterProps extends BaseSetter, PanelLabelProps {\n  panelConfig: Record<string, any>\n  openDynamic?: boolean\n  value?: string | boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSwitchSetter/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const dynamicSwitchWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  width: 100%;\n`\n\nexport const customAndSwitchWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  min-height: 28px;\n`\n\nexport const applyCustomIconStyle = (\n  isSelected: boolean = false,\n): SerializedStyles => {\n  const selectedStyle = isSelected\n    ? css`\n        color: ${globalColor(`--${illaPrefix}-purple-03`)};\n      `\n    : css`\n        color: ${globalColor(`--${illaPrefix}-grayBlue-06`)};\n        margin-right: 10px;\n      `\n  return css`\n    ${selectedStyle};\n    width: 16px;\n    height: 16px;\n    font-size: 16px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n\n    :hover {\n      cursor: pointer;\n      color: ${globalColor(`--${illaPrefix}-purple-03`)};\n    }\n  `\n}\n\nconst singleRowStyle = css`\n  width: 100%;\n  padding: 8px 16px;\n`\n\nconst doubleRowStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  padding: 8px 16px;\n  gap: 8px;\n`\n\nexport const applyLabelWrapperStyle = (\n  isCustom: boolean = false,\n): SerializedStyles => {\n  return isCustom ? doubleRowStyle : singleRowStyle\n}\n\nexport const setterContainerStyle = (isSetterSingleRow: boolean = false) => {\n  const basicStyle = css`\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n  `\n  const singleRowStyle = css`\n    flex-direction: column;\n    gap: 8px;\n  `\n  return css`\n    display: flex;\n    padding: 8px 0;\n    ${isSetterSingleRow ? singleRowStyle : basicStyle};\n    width: 100%;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnTypeSelectSetter/index.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC } from \"react\"\nimport SearchSelectSetter from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/searchSelect\"\nimport { ColumnTypeSelectSetterProps } from \"./interface\"\n\nconst ColumnTypeSelectSetter: FC<ColumnTypeSelectSetterProps> = (props) => {\n  const {\n    widgetDisplayName,\n    componentNode,\n    attrName,\n    parentAttrName,\n    isSetterSingleRow,\n    widgetOrAction,\n    widgetType,\n    expectedType,\n    value,\n    options,\n    handleUpdateMultiAttrDSL,\n    ...otherProps\n  } = props\n\n  return (\n    <SearchSelectSetter\n      {...otherProps}\n      isSetterSingleRow={isSetterSingleRow}\n      options={options}\n      attrName={attrName}\n      handleUpdateDsl={(attrName: string, newValue: any) => {\n        const match = attrName.match(/\\[([0-9]+)\\]/)\n        if (match && parentAttrName) {\n          const currentColumn = get(componentNode?.props, parentAttrName)\n          const columns = get(componentNode?.props, \"columns\")\n          const newColumns = [...columns]\n          newColumns[parseInt(match[1])] = {\n            field: currentColumn.field,\n            headerName: currentColumn.headerName,\n            width: currentColumn.width,\n            isCalc: currentColumn.isCalc,\n            description: currentColumn.description,\n            sortable: currentColumn.sortable,\n            pinnable: currentColumn.pinnable,\n            filterable: currentColumn.filterable,\n            hideable: currentColumn.hideable,\n            aggregable: currentColumn.aggregable,\n            groupable: currentColumn.groupable,\n            resizable: currentColumn.resizable,\n            columnType: newValue,\n            disableReorder: currentColumn.disableReorder,\n            headerAlign: currentColumn.headerAlign,\n          }\n          handleUpdateMultiAttrDSL?.({\n            columns: newColumns,\n          })\n        }\n      }}\n      value={value}\n      expectedType={expectedType}\n      widgetDisplayName={widgetDisplayName}\n      widgetOrAction={widgetOrAction}\n      widgetType={widgetType}\n      allowClear={true}\n    />\n  )\n}\n\nColumnTypeSelectSetter.displayName = \"ColumnTypeSelectSetter\"\n\nexport default ColumnTypeSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnTypeSelectSetter/interface.ts",
    "content": "import { BaseSelectSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/interface\"\n\nexport interface ColumnTypeSelectSetterProps extends BaseSelectSetterProps {}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnsSelectSetter/index.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { SelectOptionObject } from \"@illa-design/react\"\nimport { dealRawData2ArrayData } from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/utils\"\nimport SearchSelectSetter from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/searchSelect\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { UNIQUE_ID_NAME } from \"@/widgetLibrary/DataGridWidget/constants\"\nimport { ColumnsSelectSetterProps } from \"./interface\"\n\nconst ColumnsSelectSetter: FC<ColumnsSelectSetterProps> = (props) => {\n  const {\n    widgetDisplayName,\n    attrName,\n    isSetterSingleRow,\n    widgetOrAction,\n    widgetType,\n    expectedType,\n    value,\n    handleUpdateMultiAttrDSL,\n    ...otherProps\n  } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const options: SelectOptionObject[] = useMemo(() => {\n    const dataSourceMode = get(\n      targetComponentProps,\n      \"dataSourceMode\",\n      \"dynamic\",\n    )\n    const rawData = get(\n      targetComponentProps,\n      dataSourceMode === \"dynamic\" ? \"dataSourceJS\" : \"dataSource\",\n      undefined,\n    )\n\n    const arrayData: object[] = dealRawData2ArrayData(rawData)\n\n    const opt: SelectOptionObject[] = [\n      {\n        value: \"—\",\n        label: \"—\",\n      },\n    ]\n    if (arrayData.length > 0) {\n      Object.keys(arrayData[0]).map((key) => {\n        key !== UNIQUE_ID_NAME &&\n          opt.push({\n            value: key,\n            label: key,\n          })\n      })\n    }\n    return opt\n  }, [targetComponentProps])\n\n  return (\n    <SearchSelectSetter\n      {...otherProps}\n      isSetterSingleRow={isSetterSingleRow}\n      options={options}\n      attrName={attrName}\n      handleUpdateDsl={(attrName: string, newValue: any) => {\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: newValue === \"—\" ? undefined : newValue,\n        })\n      }}\n      value={value ?? \"—\"}\n      expectedType={expectedType}\n      widgetDisplayName={widgetDisplayName}\n      widgetOrAction={widgetOrAction}\n      widgetType={widgetType}\n      allowClear={true}\n    />\n  )\n}\n\nColumnsSelectSetter.displayName = \"ColumnsSelectSetter\"\n\nexport default ColumnsSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnsSelectSetter/interface.ts",
    "content": "import { BaseSelectSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/interface\"\n\nexport interface ColumnsSelectSetterProps extends BaseSelectSetterProps {}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DataGridSetter/utils.ts",
    "content": "import { isObject, isString } from \"lodash-es\"\nimport { isNumber } from \"@illa-design/react\"\nimport { JSToString, stringToJS } from \"@/utils/evaluateDynamicString/utils\"\nimport { UNIQUE_ID_NAME } from \"@/widgetLibrary/DataGridWidget/constants\"\n\nexport function dealRawData2ArrayData(\n  rawData: unknown,\n  enableServerSidePagination?: boolean,\n  serverSideOffset?: number,\n): object[] {\n  if (rawData === undefined || rawData === \"\" || rawData === null) {\n    return []\n  }\n  if (Array.isArray(rawData)) {\n    if (rawData.length === 0) {\n      return []\n    } else {\n      if (isObject(rawData[0])) {\n        return rawData.map((item, i) => {\n          let uniqueID = i\n          if (enableServerSidePagination && serverSideOffset) {\n            uniqueID = serverSideOffset + i\n          }\n          return {\n            [UNIQUE_ID_NAME]: uniqueID,\n            ...item,\n          }\n        })\n      } else {\n        return rawData.map((item, i) => {\n          let uniqueID = i\n          if (enableServerSidePagination && serverSideOffset) {\n            uniqueID = serverSideOffset + i\n          }\n          return {\n            [UNIQUE_ID_NAME]: uniqueID,\n            field: item,\n          }\n        })\n      }\n    }\n  } else {\n    let uniqueID = 0\n    if (enableServerSidePagination && serverSideOffset) {\n      uniqueID = serverSideOffset\n    }\n    if (isObject(rawData)) {\n      return [\n        {\n          [UNIQUE_ID_NAME]: uniqueID,\n          ...rawData,\n        },\n      ]\n    } else {\n      return [\n        {\n          [UNIQUE_ID_NAME]: uniqueID,\n          field: rawData,\n        },\n      ]\n    }\n  }\n}\n\nexport function getHashCode(str: string) {\n  let hash = 0,\n    i,\n    chr\n  if (typeof str !== \"string\" || str.length === 0) return hash\n  for (i = 0; i < str.length; i++) {\n    chr = str.charCodeAt(i)\n    hash = (hash << 5) - hash + chr\n    hash |= 0 // Convert to 32bit integer\n  }\n  return hash\n}\n\nexport function isValidLocale(locale: string) {\n  const localePattern = /^[a-z]{2}(?:-[A-Z]{2})?$/\n  return localePattern.test(locale)\n}\n\nexport const CurrencyCode = {\n  AED: \"د.إ\",\n  AFN: \"؋\",\n  ALL: \"L\",\n  AMD: \"֏\",\n  ANG: \"ƒ\",\n  AOA: \"Kz\",\n  ARS: \"$\",\n  AUD: \"$\",\n  AWG: \"ƒ\",\n  AZN: \"₼\",\n  BAM: \"KM\",\n  BBD: \"$\",\n  BDT: \"৳\",\n  BGN: \"лв\",\n  BHD: \".د.ب\",\n  BIF: \"FBu\",\n  BMD: \"$\",\n  BND: \"$\",\n  BOB: \"$b\",\n  BRL: \"R$\",\n  BSD: \"$\",\n  BTC: \"₿\",\n  BTN: \"Nu.\",\n  BWP: \"P\",\n  BYR: \"Br\",\n  BYN: \"Br\",\n  BZD: \"BZ$\",\n  CAD: \"$\",\n  CDF: \"FC\",\n  CHF: \"CHF\",\n  CLP: \"$\",\n  CNY: \"¥\",\n  COP: \"$\",\n  CRC: \"₡\",\n  CUC: \"$\",\n  CUP: \"₱\",\n  CVE: \"$\",\n  CZK: \"Kč\",\n  DJF: \"Fdj\",\n  DKK: \"kr\",\n  DOP: \"RD$\",\n  DZD: \"دج\",\n  EEK: \"kr\",\n  EGP: \"£\",\n  ERN: \"Nfk\",\n  ETB: \"Br\",\n  ETH: \"Ξ\",\n  EUR: \"€\",\n  FJD: \"$\",\n  FKP: \"£\",\n  GBP: \"£\",\n  GEL: \"₾\",\n  GGP: \"£\",\n  GHC: \"₵\",\n  GHS: \"GH₵\",\n  GIP: \"£\",\n  GMD: \"D\",\n  GNF: \"FG\",\n  GTQ: \"Q\",\n  GYD: \"$\",\n  HKD: \"$\",\n  HNL: \"L\",\n  HRK: \"kn\",\n  HTG: \"G\",\n  HUF: \"Ft\",\n  IDR: \"Rp\",\n  ILS: \"₪\",\n  IMP: \"£\",\n  INR: \"₹\",\n  IQD: \"ع.د\",\n  IRR: \"﷼\",\n  ISK: \"kr\",\n  JEP: \"£\",\n  JMD: \"J$\",\n  JOD: \"JD\",\n  JPY: \"¥\",\n  KES: \"KSh\",\n  KGS: \"лв\",\n  KHR: \"៛\",\n  KMF: \"CF\",\n  KPW: \"₩\",\n  KRW: \"₩\",\n  KWD: \"KD\",\n  KYD: \"$\",\n  KZT: \"лв\",\n  LAK: \"₭\",\n  LBP: \"£\",\n  LKR: \"₨\",\n  LRD: \"$\",\n  LSL: \"M\",\n  LTC: \"Ł\",\n  LTL: \"Lt\",\n  LVL: \"Ls\",\n  LYD: \"LD\",\n  MAD: \"MAD\",\n  MDL: \"lei\",\n  MGA: \"Ar\",\n  MKD: \"ден\",\n  MMK: \"K\",\n  MNT: \"₮\",\n  MOP: \"MOP$\",\n  MRO: \"UM\",\n  MRU: \"UM\",\n  MUR: \"₨\",\n  MVR: \"Rf\",\n  MWK: \"MK\",\n  MXN: \"$\",\n  MYR: \"RM\",\n  MZN: \"MT\",\n  NAD: \"$\",\n  NGN: \"₦\",\n  NIO: \"C$\",\n  NOK: \"kr\",\n  NPR: \"₨\",\n  NZD: \"$\",\n  OMR: \"﷼\",\n  PAB: \"B/.\",\n  PEN: \"S/\",\n  PGK: \"K\",\n  PHP: \"₱\",\n  PKR: \"₨\",\n  PLN: \"zł\",\n  PYG: \"Gs\",\n  QAR: \"﷼\",\n  RMB: \"￥\",\n  RON: \"lei\",\n  RSD: \"Дин.\",\n  RUB: \"₽\",\n  RWF: \"R₣\",\n  SAR: \"﷼\",\n  SBD: \"$\",\n  SCR: \"₨\",\n  SDG: \"ج.س.\",\n  SEK: \"kr\",\n  SGD: \"S$\",\n  SHP: \"£\",\n  SLL: \"Le\",\n  SOS: \"S\",\n  SRD: \"$\",\n  SSP: \"£\",\n  STD: \"Db\",\n  STN: \"Db\",\n  SVC: \"$\",\n  SYP: \"£\",\n  SZL: \"E\",\n  THB: \"฿\",\n  TJS: \"SM\",\n  TMT: \"T\",\n  TND: \"د.ت\",\n  TOP: \"T$\",\n  TRL: \"₤\",\n  TRY: \"₺\",\n  TTD: \"TT$\",\n  TVD: \"$\",\n  TWD: \"NT$\",\n  TZS: \"TSh\",\n  UAH: \"₴\",\n  UGX: \"USh\",\n  USD: \"$\",\n  UYU: \"$U\",\n  UZS: \"so'm\",\n  VEF: \"Bs\",\n  VND: \"₫\",\n  VUV: \"VT\",\n  WST: \"WS$\",\n  XAF: \"FCFA\",\n  XBT: \"Ƀ\",\n  XCD: \"$\",\n  XOF: \"CFA\",\n  XPF: \"₣\",\n  YER: \"﷼\",\n  ZAR: \"R\",\n  ZMK: \"ZK\",\n  ZWD: \"Z$\",\n}\n\nexport function getPreColor(index: number) {\n  const colors = [\n    \"red\",\n    \"orange\",\n    \"yellow\",\n    \"green\",\n    \"cyan\",\n    \"purple\",\n    \"techPink\",\n  ]\n  return colors[Math.abs(index) % colors.length]\n}\n\nexport const realInputValueWithDataList = (\n  attrValue: string | undefined,\n  widgetDisplayName: string,\n) => {\n  if (attrValue === \"\" || attrValue == undefined) return undefined\n  let value = attrValue\n  if (\n    attrValue.includes(\n      `{{${widgetDisplayName}.dataSource.map((currentRow) => (`,\n    )\n  ) {\n    value = `${attrValue.substring(\n      `{{${widgetDisplayName}.dataSource.map((currentRow) => (`.length,\n      attrValue.length - 4,\n    )}`\n    return JSToString(value)\n  } else if (\n    attrValue.includes(\n      `{{${widgetDisplayName}.dataSourceJS.map((currentRow) => (`,\n    )\n  ) {\n    value = `${attrValue.substring(\n      `{{${widgetDisplayName}.dataSourceJS.map((currentRow) => (`.length,\n      attrValue.length - 4,\n    )}`\n    return JSToString(value)\n  }\n  return value\n}\n\nexport const getNeedComputedValueWithDataList = (\n  value: string,\n  widgetDisplayName: string,\n  dataSourceMode: \"dynamic\" | \"select\",\n) => {\n  const stringToCanEvaluate = stringToJS(value)\n  if (stringToCanEvaluate === \"\") {\n    return stringToCanEvaluate\n  }\n  return `{{${widgetDisplayName}.${\n    dataSourceMode === \"select\" ? \"dataSource\" : \"dataSourceJS\"\n  }.map((currentRow) => (${stringToCanEvaluate}))}}`\n}\n\nexport const getValueFromMappedValue = (\n  value: unknown,\n  index: number,\n  defaultValue?: string,\n): string | undefined => {\n  let finalValue = defaultValue\n  if (Array.isArray(value)) {\n    finalValue = isString(value[index]) ? value[index] : finalValue\n  } else if (isNumber(value) || isString(value)) {\n    finalValue = `${value}`\n  }\n  return finalValue\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Column/index.tsx",
    "content": "import { useSortable } from \"@dnd-kit/sortable\"\nimport { CSS } from \"@dnd-kit/utilities\"\nimport IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC, useState } from \"react\"\nimport {\n  CopyIcon,\n  DragPointIcon,\n  EyeOffIcon,\n  EyeOnIcon,\n  MinusIcon,\n  Trigger,\n  getColor,\n} from \"@illa-design/react\"\nimport { BaseModal } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal\"\nimport { ColumnProps } from \"./interface\"\nimport {\n  baseModalContainerStyle,\n  columnContainerStyle,\n  columnLabelContainerStyle,\n  columnLabelStyle,\n  dragIconStyle,\n} from \"./style\"\n\nexport const Column: FC<ColumnProps> = (props) => {\n  const {\n    id,\n    visibility,\n    childrenSetter,\n    attrPath,\n    onDelete,\n    showDelete,\n    widgetDisplayName,\n    label,\n    showVisible,\n    extraElement,\n    showCopy,\n    labelTip,\n    onCopy,\n    onVisibilityChange,\n  } = props\n\n  const { attributes, listeners, setNodeRef, transform, transition } =\n    useSortable({ id })\n\n  const style = {\n    transform: CSS.Transform.toString(transform),\n    transition,\n  }\n\n  const [triggerVisible, setTriggerVisible] = useState(false)\n\n  return (\n    <div\n      css={columnContainerStyle}\n      ref={setNodeRef}\n      style={style}\n      {...attributes}\n    >\n      <DragPointIcon\n        className=\"dragIcon\"\n        css={dragIconStyle}\n        fs=\"16px\"\n        c={getColor(\"grayBlue\", \"04\")}\n        {...listeners}\n      />\n\n      <Trigger\n        withoutPadding\n        colorScheme=\"white\"\n        trigger=\"click\"\n        onVisibleChange={(visible) => {\n          setTriggerVisible(visible)\n        }}\n        popupVisible={triggerVisible}\n        content={\n          <BaseModal\n            title={label as string}\n            attrPath={attrPath}\n            _css={baseModalContainerStyle}\n            widgetDisplayName={widgetDisplayName}\n            childrenSetter={childrenSetter}\n            extraElement={extraElement}\n            handleCloseModal={() => {\n              setTriggerVisible(false)\n            }}\n          />\n        }\n        showArrow={false}\n        position=\"left\"\n        clickOutsideToClose\n      >\n        <div css={columnLabelContainerStyle}>\n          <span css={columnLabelStyle}> {label}</span>\n          {labelTip}\n        </div>\n      </Trigger>\n      {showCopy && (\n        <IconHotSpot\n          onClick={() => {\n            onCopy?.()\n          }}\n        >\n          <CopyIcon />\n        </IconHotSpot>\n      )}\n      {showVisible && (\n        <IconHotSpot\n          onClick={() => {\n            onVisibilityChange?.(!visibility)\n          }}\n        >\n          {visibility ? <EyeOnIcon /> : <EyeOffIcon />}\n        </IconHotSpot>\n      )}\n      {showDelete && (\n        <IconHotSpot\n          onClick={() => {\n            onDelete?.(id)\n          }}\n        >\n          <MinusIcon />\n        </IconHotSpot>\n      )}\n    </div>\n  )\n}\n\nColumn.displayName = \"Column\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Column/interface.ts",
    "content": "import { ReactNode } from \"react\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface ColumnProps {\n  id: string\n  label?: string\n  showDelete?: boolean\n  showCopy?: boolean\n  onCopy?: () => void\n  showVisible?: boolean\n  widgetDisplayName: string\n  onVisibilityChange?: (visibility: boolean) => void\n  onDelete?: (id: string) => void\n  attrPath: string\n  visibility?: boolean\n  extraElement?: ReactNode\n  childrenSetter?: PanelFieldConfig[]\n  labelTip?: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Column/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const dragIconStyle = css`\n  visibility: hidden;\n  cursor: grab;\n  &:active {\n    cursor: grabbing;\n  }\n`\n\nexport const columnContainerStyle = css`\n  padding-top: 8px;\n  padding-bottom: 8px;\n  padding-right: 16px;\n  display: flex;\n  align-items: center;\n  flex-direction: row;\n  &:hover {\n    .dragIcon {\n      visibility: visible;\n    }\n  }\n`\nexport const columnLabelContainerStyle = css`\n  display: flex;\n  flex-grow: 1;\n  cursor: pointer;\n  height: 22px;\n  overflow: hidden;\n  gap: 8px;\n`\n\nexport const columnLabelStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  font-weight: 400;\n  line-height: 22px;\n  max-width: 180px;\n  overflow: hidden;\n`\n\nexport const baseModalContainerStyle = css`\n  max-height: 800px;\n  overflow-y: auto;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/ColumnContainer/index.tsx",
    "content": "import {\n  DndContext,\n  KeyboardSensor,\n  PointerSensor,\n  closestCenter,\n  useSensor,\n  useSensors,\n} from \"@dnd-kit/core\"\nimport {\n  restrictToVerticalAxis,\n  restrictToWindowEdges,\n} from \"@dnd-kit/modifiers\"\nimport {\n  SortableContext,\n  arrayMove,\n  sortableKeyboardCoordinates,\n  verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { AddIcon, Button } from \"@illa-design/react\"\nimport {\n  columnLabelStyle,\n  columnNumStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter/style\"\nimport { ColumnContainerProps } from \"./interface\"\nimport {\n  containerStyle,\n  listStyle,\n  optionListHeaderStyle,\n  optionListLabelStyle,\n} from \"./style\"\n\nexport const ColumnContainer: FC<ColumnContainerProps> = (props) => {\n  const {\n    onDragEnd,\n    handleUpdateMultiAttrDSL,\n    attrName,\n    value,\n    hideTitle,\n    onClickNew,\n    columnNum,\n    children,\n    items,\n    headerExtNode,\n  } = props\n\n  const { t } = useTranslation()\n\n  const sensors = useSensors(\n    useSensor(PointerSensor),\n    useSensor(KeyboardSensor, {\n      coordinateGetter: sortableKeyboardCoordinates,\n    }),\n  )\n\n  return (\n    <div css={containerStyle}>\n      <div css={columnLabelStyle}>\n        <div css={columnNumStyle}>\n          {t(\"editor.inspect.setter_content.column_setter.label\", {\n            number: columnNum,\n          })}\n        </div>\n        <Button\n          leftIcon={<AddIcon />}\n          variant=\"text\"\n          size=\"small\"\n          colorScheme=\"techPurple\"\n          onClick={() => {\n            onClickNew()\n          }}\n        >\n          {t(\"editor.inspect.setter_content.column_setter.new\")}\n        </Button>\n      </div>\n      <div css={listStyle}>\n        {!hideTitle && (\n          <div css={optionListHeaderStyle}>\n            <div css={optionListLabelStyle}>\n              {t(\"editor.inspect.setter_content.column_setter.title\")}\n            </div>\n            {headerExtNode}\n          </div>\n        )}\n        <DndContext\n          modifiers={[restrictToVerticalAxis, restrictToWindowEdges]}\n          sensors={sensors}\n          collisionDetection={closestCenter}\n          onDragEnd={\n            onDragEnd\n              ? onDragEnd\n              : (event) => {\n                  if (value === undefined || attrName == undefined) {\n                    return\n                  }\n                  const { active, over } = event\n                  if (active && over && active.id !== over.id) {\n                    const oldIndex = value.findIndex(\n                      (item) => item.id === active.id,\n                    )\n                    const newIndex = value.findIndex(\n                      (item) => item.id === over.id,\n                    )\n                    const finalColumns = arrayMove(value, oldIndex, newIndex)\n                    handleUpdateMultiAttrDSL?.({\n                      [attrName]: finalColumns,\n                    })\n                    return finalColumns\n                  }\n                }\n          }\n        >\n          <SortableContext items={items} strategy={verticalListSortingStrategy}>\n            {children}\n          </SortableContext>\n        </DndContext>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/ColumnContainer/interface.ts",
    "content": "import { UniqueIdentifier } from \"@dnd-kit/core\"\nimport { DragEndEvent } from \"@dnd-kit/core/dist/types\"\nimport { PropsWithChildren, ReactNode } from \"react\"\n\nexport interface ColumnContainerProps extends PropsWithChildren {\n  onDragEnd?: (event: DragEndEvent) => void\n  hideTitle?: boolean\n  columnNum: number\n  handleUpdateMultiAttrDSL?: (updateSlice: Record<string, unknown>) => void\n  attrName?: string\n  value?: any[]\n  onClickNew: () => void\n  items: (\n    | UniqueIdentifier\n    | {\n        id: UniqueIdentifier\n      }\n  )[]\n  headerExtNode?: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/ColumnContainer/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const optionListHeaderStyle = css`\n  width: 100%;\n  background-color: ${getColor(\"grayBlue\", \"09\")};\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  height: 40px;\n  box-sizing: border-box;\n  padding: 0 16px;\n`\n\nexport const optionListLabelStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 22px;\n  text-transform: capitalize;\n`\nexport const listStyle = css`\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  margin: 0 16px;\n  border-radius: 8px;\n`\n\nexport const containerStyle = css`\n  display: flex;\n  flex-direction: column;\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Empty/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Empty } from \"@illa-design/react\"\nimport { emptyBodyStyle } from \"./style\"\n\nexport const ColumnEmpty: FC = () => {\n  return (\n    <div css={emptyBodyStyle}>\n      <Empty />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Empty/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const emptyBodyStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 100%;\n  height: 200px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/SourceHeader/index.tsx",
    "content": "import { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { FC, useContext } from \"react\"\nimport Folder from \"@/assets/drive/panelFolder.svg?react\"\nimport { DriveFileSelectContext } from \"@/components/DriveFileSelect\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport {\n  fileSelectContainerStyle,\n  folderIconStyle,\n  sourceHeaderContainerStyle,\n} from \"./style\"\n\ninterface SourceHeaderProps {\n  labelName?: string\n  labelDesc?: string\n  showSelect: boolean\n  canUseDrive: boolean\n}\nconst SourceHeader: FC<SourceHeaderProps> = ({\n  labelName,\n  labelDesc,\n  showSelect,\n  canUseDrive,\n}) => {\n  const upgradeModal = useUpgradeModal()\n  const { setModalVisible } = useContext(DriveFileSelectContext)\n  const handleClickSelect = () => {\n    if (canUseDrive) {\n      setModalVisible(true)\n    } else {\n      upgradeModal({\n        modalType: \"upgrade\",\n        from: \"panel_setter_select\",\n      })\n    }\n  }\n  return (\n    <div css={sourceHeaderContainerStyle}>\n      <PanelLabel\n        labelName={labelName}\n        labelDesc={labelDesc}\n        labelSize=\"medium\"\n      />\n      {showSelect && (\n        <div css={fileSelectContainerStyle} onClick={handleClickSelect}>\n          <span css={folderIconStyle}>\n            <Folder />\n          </span>\n          <span>ILLA Drive</span>\n        </div>\n      )}\n    </div>\n  )\n}\n\nexport default SourceHeader\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/SourceHeader/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const sourceHeaderContainerStyle = css`\n  width: 100%;\n  height: 24px;\n  display: flex;\n  justify-content: space-between;\n  align-items: flex-start;\n`\n\nexport const fileSelectContainerStyle = css`\n  display: flex;\n  padding: 1px 8px;\n  justify-content: center;\n  align-items: center;\n  gap: 4px;\n  cursor: pointer;\n  & > span {\n    color: ${getColor(\"grayBlue\", \"02\")};\n    font-size: 14px;\n    font-style: normal;\n    font-weight: 500;\n    line-height: 22px;\n    text-transform: capitalize;\n  }\n`\n\nexport const folderIconStyle = css`\n  width: 16px;\n  height: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/URLModeInput/index.tsx",
    "content": "import { FC } from \"react\"\nimport BaseInput from \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/BaseInput\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { URLModeInputProps } from \"./interface\"\n\nconst URLModeInput: FC<URLModeInputProps> = (props) => {\n  return (\n    <BaseInput\n      {...props}\n      isSetterSingleRow\n      expectedType={VALIDATION_TYPES.STRING}\n    />\n  )\n}\n\nexport default URLModeInput\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/URLModeInput/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\n\nexport type URLModeInputProps = Pick<\n  BaseSetter,\n  \"attrName\" | \"handleUpdateDsl\" | \"widgetDisplayName\" | \"widgetType\"\n> & { value: string }\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/UploadInput/index.tsx",
    "content": "import { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { FC, useContext } from \"react\"\nimport { FolderOperateModalContext } from \"@/components/FolderOperateModal/context\"\nimport { FileUploadContext } from \"@/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/provider/FileUploadProvider\"\nimport { getUploadModeInfo } from \"@/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/utils\"\nimport { uploadContainerStyle, uploadIconStyle, uploadNameStyle } from \"./style\"\n\ninterface UploadModeProps {\n  widgetType: string\n  canUseDrive: boolean\n}\nconst UploadMode: FC<UploadModeProps> = ({ widgetType, canUseDrive }) => {\n  const placeholderInfo = getUploadModeInfo(widgetType)\n  const upgradeModal = useUpgradeModal()\n  const { uploadName, isUpLoading } = useContext(FileUploadContext)\n  const { setFolderOperateVisible } = useContext(FolderOperateModalContext)\n  const handleClickUpload = () => {\n    if (canUseDrive) {\n      setFolderOperateVisible(true)\n    } else {\n      upgradeModal({\n        modalType: \"upgrade\",\n        from: \"panel_setter_upload\",\n      })\n    }\n  }\n\n  return (\n    <div css={uploadContainerStyle(isUpLoading)} onClick={handleClickUpload}>\n      <span css={uploadIconStyle}>{placeholderInfo?.icon}</span>\n      <span css={uploadNameStyle}>{uploadName || placeholderInfo?.name}</span>\n    </div>\n  )\n}\n\nexport default UploadMode\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/UploadInput/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const uploadContainerStyle = (isUpLoading: boolean) => css`\n  pointer-events: ${isUpLoading ? \"none\" : \"auto\"};\n  width: 100%;\n  cursor: ${isUpLoading ? \"not-allowed\" : \"pointer\"};\n  display: flex;\n  padding: 3px 12px 3px 8px;\n  align-items: center;\n  gap: 8px;\n  margin-top: 8px;\n  border-radius: 8px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  opacity: ${isUpLoading ? 0.5 : 1};\n`\n\nexport const uploadIconStyle = css`\n  padding: 4px;\n  display: inline-flex;\n  flex: none;\n`\n\nexport const uploadNameStyle = css`\n  overflow: hidden;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  font-size: 12px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 24px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/UploadOperate/index.tsx",
    "content": "import {\n  HTTP_REQUEST_PUBLIC_BASE_URL,\n  PUBLIC_DRIVE_REQUEST_PREFIX,\n} from \"@illa-public/illa-net\"\nimport { EXPIRATION_TYPE } from \"@illa-public/public-types\"\nimport {\n  CollarModalType,\n  handleCollaPurchaseError,\n} from \"@illa-public/upgrade-modal\"\nimport { useContext, useRef } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button, useMessage } from \"@illa-design/react\"\nimport { FolderOperateModalContext } from \"@/components/FolderOperateModal/context\"\nimport { FILE_ITEM_DETAIL_STATUS_IN_UI } from \"@/page/App/Module/UploadDetail/components/DetailList/interface\"\nimport { updateFileDetailStore } from \"@/page/App/Module/UploadDetail/store\"\nimport { fetchGenerateTinyUrl } from \"@/services/drive\"\nimport { uploadFileToDrive } from \"@/utils/drive/upload/getSingedURL\"\nimport { FileUploadContext } from \"../../provider/FileUploadProvider\"\nimport {\n  getPathForSignedUrl,\n  getReportElementForUpload,\n  getUploadAccept,\n} from \"../../utils\"\n\nconst UploadOperate = () => {\n  const uploadFileRef = useRef<HTMLInputElement | null>(null)\n  const message = useMessage()\n  const { t } = useTranslation()\n  const { currentFolderPath, setFolderOperateVisible } = useContext(\n    FolderOperateModalContext,\n  )\n\n  const { widgetType, setIsUpLoading, setUploadName, handleUpdateResult } =\n    useContext(FileUploadContext)\n\n  const onChangeFiles = async (e: React.ChangeEvent<HTMLInputElement>) => {\n    const files = e.target.files\n    if (!files) return\n    setIsUpLoading(true)\n    message.info({\n      content: t(\"drive.message.start_upload\"),\n    })\n    const file = files[0]\n    if (!file) return\n    setFolderOperateVisible(false)\n    const queryID = `${file.name}_${new Date().getTime()}`\n\n    const abortController = new AbortController()\n\n    const uploadParams = {\n      folder: getPathForSignedUrl(currentFolderPath),\n      allowAnonymous: false,\n      replace: false,\n    }\n\n    updateFileDetailStore.addFileDetailInfo({\n      loaded: 0,\n      total: 0,\n      status: FILE_ITEM_DETAIL_STATUS_IN_UI.WAITING,\n      fileName: file.name,\n      contentType: file.type,\n      queryID: queryID,\n      abortController,\n      saveToILLADriveParams: {\n        fileData: file,\n        ...uploadParams,\n      },\n    })\n    let uploadRes\n    try {\n      uploadRes = await uploadFileToDrive(\n        queryID,\n        file,\n        uploadParams,\n        abortController.signal,\n      )\n    } catch (e) {\n      handleCollaPurchaseError(\n        e,\n        CollarModalType.TRAFFIC,\n        getReportElementForUpload(widgetType)!,\n      )\n    }\n    if (!!uploadRes) {\n      try {\n        const selectIds = [uploadRes.id]\n        const requestParams = {\n          ids: selectIds,\n          expirationType: EXPIRATION_TYPE.PERSISTENT,\n          hotlinkProtection: false,\n        }\n        const res = await fetchGenerateTinyUrl(requestParams)\n        let value = `${HTTP_REQUEST_PUBLIC_BASE_URL}${PUBLIC_DRIVE_REQUEST_PREFIX}/${res.data.tinyURL}`\n        setUploadName(uploadRes.name)\n        handleUpdateResult(value)\n      } catch (e) {\n        message.error({\n          content: t(\"drive.message.generate_url_fail\"),\n        })\n      } finally {\n        setIsUpLoading(false)\n      }\n    } else {\n      setIsUpLoading(false)\n    }\n    e.target.value = \"\"\n  }\n  return (\n    <Button\n      colorScheme=\"techPurple\"\n      onClick={() => {\n        uploadFileRef.current?.click()\n      }}\n    >\n      <span>\n        <input\n          style={{ display: \"none\" }}\n          type=\"file\"\n          accept={getUploadAccept(widgetType)}\n          ref={uploadFileRef}\n          onChange={onChangeFiles}\n        />\n        {t(\"drive.upload.modal.file_upload\")}\n      </span>\n    </Button>\n  )\n}\nexport default UploadOperate\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/components/UploadOperate/style.ts",
    "content": ""
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/constants.ts",
    "content": "export const PAGESIZE = 10\nexport const COLOR_SCHEME = \"techPurple\"\nexport enum DRIVE_SOURCE_MODE {\n  URL = \"url\",\n  UPLOAD = \"upload\",\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/index.tsx",
    "content": "import { UpgradeIcon } from \"@illa-public/icon\"\nimport { isSubscribeForUseDrive } from \"@illa-public/upgrade-modal/utils\"\nimport { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { get } from \"lodash-es\"\nimport { FC, useMemo, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { RadioGroup, getColor } from \"@illa-design/react\"\nimport FilesModal, { ROOT_PATH } from \"@/components/DriveFileSelect\"\nimport FolderOperateModal from \"@/components/FolderOperateModal\"\nimport {\n  applyRadioGroupWrapperStyle,\n  baseRadioGroupContainerStyle,\n  radioGroupStyle,\n  uploadButtonStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/style\"\nimport SourceHeader from \"./components/SourceHeader\"\nimport URLModeInput from \"./components/URLModeInput\"\nimport UploadMode from \"./components/UploadInput\"\nimport { DRIVE_SOURCE_MODE } from \"./constants\"\nimport { DriveSourceGroupSetterProps } from \"./interface\"\nimport { FileUploadProvider } from \"./provider/FileUploadProvider\"\nimport { SourceSelectProvider } from \"./provider/SourceSelectProvider\"\n\nconst DriveSourceGroupSetter: FC<DriveSourceGroupSetterProps> = (props) => {\n  const {\n    value = \"\",\n    isSetterSingleRow = false,\n    attrName,\n    widgetType,\n    labelName,\n    labelDesc,\n    widgetDisplayName,\n    componentNode,\n    handleUpdateDsl,\n  } = props\n\n  const { t } = useTranslation()\n  const teamInfo = useSelector(getCurrentTeamInfo)!\n  const canUseDrive = isSubscribeForUseDrive(teamInfo)\n\n  const options = [\n    {\n      label: t(\"widget.public.select_options.url\"),\n      value: DRIVE_SOURCE_MODE.URL,\n    },\n    {\n      label: (\n        <span css={uploadButtonStyle}>\n          {!canUseDrive && <UpgradeIcon color={getColor(\"techPurple\", \"03\")} />}\n          <span>{t(\"widget.public.select_options.upload\")}</span>\n        </span>\n      ),\n      value: DRIVE_SOURCE_MODE.UPLOAD,\n    },\n  ]\n\n  const [selectMode, setSelectMode] = useState(DRIVE_SOURCE_MODE.URL)\n  const { srcByURL, srcByUpload } = useMemo(() => {\n    const srcByURL = get(componentNode, `props.${attrName}ByURL`, value)\n    const srcByUpload = get(componentNode, `props.${attrName}ByUpload`, value)\n    return {\n      srcByURL,\n      srcByUpload,\n    }\n  }, [attrName, componentNode, value])\n\n  const handleSelectModeChange = (mode: DRIVE_SOURCE_MODE) => {\n    setSelectMode(mode)\n    if (mode === DRIVE_SOURCE_MODE.URL) {\n      handleUpdateDsl(attrName, srcByURL)\n    } else {\n      handleUpdateDsl(attrName, srcByUpload)\n    }\n  }\n\n  const handleUpdateResultByURL = (attrNameByUrl: string, value: string) => {\n    if (selectMode === DRIVE_SOURCE_MODE.URL) {\n      handleUpdateDsl(attrName, value)\n    }\n    handleUpdateDsl(attrNameByUrl, value)\n  }\n\n  const handleUpdateResultByUpload = (value: string) => {\n    if (selectMode === DRIVE_SOURCE_MODE.UPLOAD) {\n      handleUpdateDsl(attrName, value)\n    }\n    handleUpdateDsl(`${attrName}ByUpload`, value)\n  }\n\n  return (\n    <SourceSelectProvider\n      widgetType={widgetType}\n      path={ROOT_PATH}\n      handleUpdateResult={(value) => {\n        handleUpdateResultByURL(`${attrName}ByURL`, value)\n      }}\n    >\n      <FileUploadProvider\n        widgetType={widgetType}\n        handleUpdateResult={handleUpdateResultByUpload}\n      >\n        <div css={baseRadioGroupContainerStyle(isSetterSingleRow)}>\n          <SourceHeader\n            labelDesc={labelDesc}\n            labelName={labelName}\n            showSelect={selectMode === DRIVE_SOURCE_MODE.URL}\n            canUseDrive={canUseDrive}\n          />\n          <div css={applyRadioGroupWrapperStyle(isSetterSingleRow)}>\n            <RadioGroup\n              onChange={handleSelectModeChange}\n              value={selectMode}\n              forceEqualWidth={true}\n              options={options}\n              type=\"button\"\n              size=\"medium\"\n              colorScheme=\"grayBlue\"\n              css={radioGroupStyle}\n            />\n            {selectMode === DRIVE_SOURCE_MODE.URL && (\n              <URLModeInput\n                value={srcByURL}\n                attrName={`${attrName}ByURL`}\n                widgetType={widgetType}\n                handleUpdateDsl={handleUpdateResultByURL}\n                widgetDisplayName={widgetDisplayName}\n              />\n            )}\n            {selectMode === DRIVE_SOURCE_MODE.UPLOAD && (\n              <UploadMode widgetType={widgetType} canUseDrive={canUseDrive} />\n            )}\n          </div>\n        </div>\n        <FolderOperateModal />\n        <FilesModal />\n      </FileUploadProvider>\n    </SourceSelectProvider>\n  )\n}\n\nDriveSourceGroupSetter.displayName = \"DriveSourceGroupSetter\"\n\nexport default DriveSourceGroupSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\n\nexport interface DriveSourceGroupSetterProps extends BaseSetter {\n  value?: string\n}\n\nexport interface SelectItemValue {\n  fileURL: string\n  tinyURL: string\n  fileID: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/provider/FileUploadProvider/index.tsx",
    "content": "import { FC, ReactNode, createContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  FolderOperateModalContext,\n  ROOT_PATH,\n} from \"@/components/FolderOperateModal\"\nimport UploadOperate from \"../../components/UploadOperate\"\n\ninterface Injected {\n  uploadName: string\n  widgetType: string\n  isUpLoading: boolean\n  setIsUpLoading: (v: boolean) => void\n  setUploadName: (name: string) => void\n  handleUpdateResult: (value: string) => void\n}\n\ninterface FileUploadProviderProps {\n  widgetType: string\n  handleUpdateResult: (value: string) => void\n  children: ReactNode\n}\n\nexport const FileUploadContext = createContext<Injected>({} as Injected)\n\nexport const FileUploadProvider: FC<FileUploadProviderProps> = ({\n  children,\n  widgetType,\n  handleUpdateResult,\n}) => {\n  const [currentFolderPath, setCurrentFolderPath] = useState(ROOT_PATH)\n  const [folderOperateVisible, setFolderOperateVisible] = useState(false)\n  const [createFolderVisible, setCreateFolderVisible] = useState(false)\n  const [isUpLoading, setIsUpLoading] = useState(false)\n  const [uploadName, setUploadName] = useState(\"\")\n  const { t } = useTranslation()\n\n  return (\n    <FileUploadContext.Provider\n      value={{\n        widgetType,\n        handleUpdateResult,\n        isUpLoading,\n        uploadName,\n        setIsUpLoading,\n        setUploadName,\n      }}\n    >\n      <FolderOperateModalContext.Provider\n        value={{\n          subTitle: t(\"drive.upload.modal.upload_to\"),\n          currentFolderPath,\n          folderOperateVisible,\n          createFolderVisible,\n          setCreateFolderVisible,\n          setCurrentFolderPath,\n          setFolderOperateVisible,\n          operateChildren: <UploadOperate />,\n        }}\n      >\n        {children}\n      </FolderOperateModalContext.Provider>\n    </FileUploadContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/provider/SourceSelectProvider/index.tsx",
    "content": "import {\n  HTTP_REQUEST_PUBLIC_BASE_URL,\n  PUBLIC_DRIVE_REQUEST_PREFIX,\n} from \"@illa-public/illa-net/constant\"\nimport {\n  DRIVE_FILE_TYPE,\n  EXPIRATION_TYPE,\n  FILE_CATEGORY,\n  IILLAFileInfo,\n} from \"@illa-public/public-types\"\nimport {\n  CollarModalType,\n  handleCollaPurchaseError,\n} from \"@illa-public/upgrade-modal\"\nimport { FC, ReactNode, useCallback, useMemo, useState } from \"react\"\nimport { ROOT_PATH, usePath } from \"@/components/DriveFileSelect\"\nimport { DriveFileSelectContext } from \"@/components/DriveFileSelect/context\"\nimport { FileToPanel } from \"@/components/DriveFileSelect/interface\"\nimport {\n  COLOR_SCHEME,\n  PAGESIZE,\n} from \"@/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/constants\"\nimport { fetchFileList, fetchGenerateTinyUrl } from \"@/services/drive\"\nimport { getReportElementForSelect } from \"../../utils\"\n\ninterface Props {\n  widgetType: string\n  path: string\n  children?: ReactNode\n  handleUpdateResult: (value: string) => void\n}\n\nexport const SourceSelectProvider: FC<Props> = (props) => {\n  const { path = ROOT_PATH, children, widgetType, handleUpdateResult } = props\n  const { currentPath, updatePath, totalPath } = usePath(path)\n  const [fileList, setFileList] = useState<IILLAFileInfo[]>([])\n  const [modalVisible, setModalVisible] = useState(false)\n\n  const fileCategory = useMemo(() => {\n    switch (widgetType) {\n      case \"IMAGE_WIDGET\":\n      case \"CAROUSEL_WIDGET\":\n        return FILE_CATEGORY.IMAGE\n      case \"PDF_WIDGET\":\n        return FILE_CATEGORY.PDF\n      case \"VIDEO_WIDGET\":\n        return FILE_CATEGORY.VIDEO\n      case \"AUDIO_WIDGET\":\n        return FILE_CATEGORY.AUDIO\n    }\n  }, [widgetType])\n  const handleCloseModal = useCallback(() => {\n    setModalVisible(false)\n    updatePath(path || ROOT_PATH)\n    setFileList([])\n  }, [path, updatePath])\n\n  const submitSelect = useCallback(\n    (items: FileToPanel[]) => {\n      return new Promise(async (resolve, reject) => {\n        const selectIds = [items[0].id]\n        const requestParams = {\n          ids: selectIds,\n          expirationType: EXPIRATION_TYPE.PERSISTENT,\n          hotlinkProtection: false,\n        }\n        try {\n          const res = await fetchGenerateTinyUrl(requestParams)\n          let value = `${HTTP_REQUEST_PUBLIC_BASE_URL}${PUBLIC_DRIVE_REQUEST_PREFIX}/${res.data.tinyURL}`\n          await handleUpdateResult(value)\n          handleCloseModal()\n          resolve(true)\n        } catch (e) {\n          handleCollaPurchaseError(\n            e,\n            CollarModalType.TRAFFIC,\n            getReportElementForSelect(widgetType)!,\n          )\n          reject(e)\n        }\n      })\n    },\n    [handleCloseModal, handleUpdateResult, widgetType],\n  )\n\n  const getFileList = useCallback(\n    async (currentPage: number, totalPath: string, search?: string) => {\n      try {\n        const requestParams = {\n          path: `/${totalPath || ROOT_PATH}`,\n          page: currentPage,\n          limit: PAGESIZE,\n          type: DRIVE_FILE_TYPE.MIX,\n          search,\n          fileCategory,\n        }\n        const res = await fetchFileList(requestParams)\n        if (currentPage === 1) {\n          setFileList(res.data?.files || [])\n        } else {\n          setFileList((prev) => [...prev, ...(res.data?.files || [])])\n        }\n      } catch (e) {}\n    },\n    [fileCategory],\n  )\n\n  const value = {\n    rootPath: ROOT_PATH,\n    modalVisible,\n    fileList,\n    currentPath,\n    totalPath,\n    colorScheme: COLOR_SCHEME,\n    singleSelect: true,\n    updatePath,\n    submitSelect,\n    setModalVisible,\n    getFileList,\n    handleCloseModal,\n  }\n\n  return (\n    <DriveFileSelectContext.Provider value={value}>\n      {children}\n    </DriveFileSelectContext.Provider>\n  )\n}\n\nSourceSelectProvider.displayName = \"SourceSelectProvider\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { fixedWidthStyle } from \"@/page/App/components/InspectPanel/PanelSetters/style\"\n\nexport const applyRadioGroupWrapperStyle = (\n  isSetterSingleRow: boolean = false,\n): SerializedStyles => {\n  let width = isSetterSingleRow\n    ? css`\n        width: 100%;\n      `\n    : fixedWidthStyle\n  return css`\n    display: flex;\n    flex: none;\n    flex-direction: column;\n    gap: 8px;\n    ${width};\n  `\n}\n\nexport const radioGroupStyle = css`\n  width: 100%;\n`\n\nexport const baseRadioGroupContainerStyle = (\n  isSetterSingleRow: boolean = false,\n) => {\n  const basicStyle = css`\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n  `\n  const singleRowStyle = css`\n    flex-direction: column;\n    gap: 8px;\n  `\n  return css`\n    display: flex;\n    padding: 8px 0;\n    ${isSetterSingleRow ? singleRowStyle : basicStyle};\n    width: 100%;\n  `\n}\n\nexport const uploadButtonStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 100%;\n  gap: 4px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter/utils.tsx",
    "content": "import AudioIcon from \"@/assets/drive/audio.svg?react\"\nimport ImageIcon from \"@/assets/drive/image.svg?react\"\nimport PdfIcon from \"@/assets/drive/pdf.svg?react\"\nimport VideoIcon from \"@/assets/drive/video.svg?react\"\nimport i18n from \"@/i18n/config\"\n\nexport const getUploadModeInfo = (widgetType: string) => {\n  switch (widgetType) {\n    case \"IMAGE_WIDGET\":\n    case \"CAROUSEL_WIDGET\":\n      return {\n        name: i18n.t(\"editor.inspect.setter_placeholder.choose_image\"),\n        icon: <ImageIcon />,\n      }\n    case \"PDF_WIDGET\":\n      return {\n        name: i18n.t(\"editor.inspect.setter_placeholder.choose_pdf\"),\n        icon: <PdfIcon />,\n      }\n    case \"VIDEO_WIDGET\":\n      return {\n        name: i18n.t(\"editor.inspect.setter_placeholder.choose_video\"),\n        icon: <VideoIcon />,\n      }\n    case \"AUDIO_WIDGET\":\n      return {\n        name: i18n.t(\"editor.inspect.setter_placeholder.choose_audio\"),\n        icon: <AudioIcon />,\n      }\n  }\n}\n\nexport const getUploadAccept = (widgetType: string) => {\n  switch (widgetType) {\n    case \"IMAGE_WIDGET\":\n    case \"CAROUSEL_WIDGET\":\n      return \"image/*\"\n    case \"PDF_WIDGET\":\n      return \".pdf\"\n    case \"VIDEO_WIDGET\":\n      return \"video/*\"\n    case \"AUDIO_WIDGET\":\n      return \"audio/*\"\n  }\n}\n\nexport const getPathForSignedUrl = (path: string) => {\n  if (path === \"root\") {\n    return \"\"\n  } else {\n    return path.replace(\"root/\", \"\")\n  }\n}\n\nexport const getReportElementForUpload = (widgetType: string) => {\n  switch (widgetType) {\n    case \"IMAGE_WIDGET\":\n      return \"builder_editor_storage_not_enough_image\"\n    case \"CAROUSEL_WIDGET\":\n      return \"builder_editor_storage_not_enough_carousel\"\n    case \"VIDEO_WIDGET\":\n      return \"builder_editor_storage_not_enough_video\"\n    case \"AUDIO_WIDGET\":\n      return \"builder_editor_storage_not_enough_audio\"\n  }\n}\n\nexport const getReportElementForSelect = (widgetType: string) => {\n  switch (widgetType) {\n    case \"IMAGE_WIDGET\":\n      return \"builder_editor_traffic_not_enough_image\"\n    case \"CAROUSEL_WIDGET\":\n      return \"builder_editor_traffic_not_enough_carousel\"\n    case \"VIDEO_WIDGET\":\n      return \"builder_editor_traffic_not_enough_video\"\n    case \"AUDIO_WIDGET\":\n      return \"builder_editor_traffic_not_enough_audio\"\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/actionMenu.tsx",
    "content": "import { FC, useContext } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { DropList, DropListItem } from \"@illa-design/react\"\nimport { BaseEventHandlerContext } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/context\"\nimport { ActionMenuProps } from \"./interface\"\n\nexport const ActionMenu: FC<ActionMenuProps> = (props) => {\n  const { index, handleCloseMode } = props\n  const { handleCopyEventItem, handleDeleteEventItem } = useContext(\n    BaseEventHandlerContext,\n  )\n  const { t } = useTranslation()\n\n  return (\n    <DropList w=\"184px\">\n      <DropListItem\n        key=\"duplicate\"\n        value=\"duplicate\"\n        title={t(\n          \"editor.inspect.setter_content.option_list.action_menu.duplicate\",\n        )}\n        onClick={() => {\n          handleCopyEventItem(index)\n          handleCloseMode()\n        }}\n      />\n      <DropListItem\n        key=\"delete\"\n        value=\"delete\"\n        title={t(\n          \"editor.inspect.setter_content.option_list.action_menu.delete\",\n        )}\n        deleted\n        onClick={() => {\n          handleDeleteEventItem(index)\n          handleCloseMode()\n        }}\n      />\n    </DropList>\n  )\n}\n\nActionMenu.displayName = \"ActionMenu\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/body.tsx",
    "content": "import { FC } from \"react\"\nimport { EventHandlerEmpty } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/empty\"\nimport { ListBodyProps } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/interface\"\nimport { ListItem } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/item\"\n\nexport const ListBody: FC<ListBodyProps> = (props) => {\n  const { events } = props\n\n  if (!events || events.length === 0) return <EventHandlerEmpty />\n  return (\n    <>\n      {events.map((item, index) => {\n        return <ListItem key={item.id} index={index} />\n      })}\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/empty.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { emptyBodyStyle } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/style\"\n\nexport const EventHandlerEmpty: FC = memo(() => {\n  const { t } = useTranslation()\n  return (\n    <div css={emptyBodyStyle}>\n      {t(\"editor.inspect.setter_content.event_handler_list.empty\")}\n    </div>\n  )\n})\n\nEventHandlerEmpty.displayName = \"EventHandlerEmpty\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/eventAndMethodLabel.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { EVENT_HANDLER_DOC_LINK } from \"@illa-public/public-configs\"\nimport { get } from \"lodash-es\"\nimport { FC, useCallback, useContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { Trigger } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { BaseEventHandlerContext } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/context\"\nimport { BaseModal } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal\"\nimport { isOpenLeftPanel } from \"@/redux/config/configSelector\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { EventAndMethodLabelProps } from \"./interface\"\nimport {\n  eventAndMethodWrapperStyle,\n  eventNameStyle,\n  methodNameStyle,\n} from \"./style\"\n\nconst getMethodName = (\n  actionType: string,\n  widgetId: string,\n  widgetMethod: string,\n  queryID: string,\n) => {\n  if (actionType === \"widget\") {\n    return widgetId && widgetMethod\n      ? `${widgetId}.${widgetMethod}()`\n      : i18n.t(\n          \"editor.inspect.setter_content.event_handler_list.incomplete_selection\",\n        )\n  }\n  if (actionType === \"datasource\") {\n    return queryID\n      ? `${queryID}.run()`\n      : i18n.t(\n          \"editor.inspect.setter_content.event_handler_list.incomplete_selection\",\n        )\n  }\n  if (actionType) {\n    return `${actionType}()`\n  }\n  return i18n.t(\n    \"editor.inspect.setter_content.event_handler_list.incomplete_selection\",\n  )\n}\n\nexport const EventAndMethodLabel: FC<EventAndMethodLabelProps> = (props) => {\n  const leftPanelVisible = useSelector(isOpenLeftPanel)\n  const { index } = props\n  const { t } = useTranslation()\n  const [modalVisible, setModalVisible] = useState(false)\n  const {\n    widgetDisplayName,\n    attrPath,\n    childrenSetter,\n    eventItems,\n    widgetType,\n  } = useContext(BaseEventHandlerContext)\n\n  const event = get(eventItems, index)\n  const { eventType, widgetID, queryID, widgetMethod, actionType } = event\n  const handleCloseModal = useCallback(() => {\n    setModalVisible(false)\n  }, [])\n\n  return (\n    <Trigger\n      withoutPadding\n      colorScheme=\"white\"\n      popupVisible={modalVisible}\n      content={\n        <BaseModal\n          title={t(\"editor.inspect.setter_content.event_handler_list.title\")}\n          handleCloseModal={handleCloseModal}\n          attrPath={`${attrPath}.${index}`}\n          widgetDisplayName={widgetDisplayName}\n          childrenSetter={childrenSetter}\n          docLink={EVENT_HANDLER_DOC_LINK}\n        />\n      }\n      trigger=\"click\"\n      showArrow={false}\n      position={leftPanelVisible ? \"left-start\" : \"top-start\"}\n      clickOutsideToClose={false}\n      onVisibleChange={(visible) => {\n        if (visible) {\n          trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n            element: \"event_handler_editor\",\n            parameter1: widgetType,\n          })\n        }\n        setModalVisible(visible)\n      }}\n    >\n      <div css={eventAndMethodWrapperStyle}>\n        <div css={eventNameStyle}>\n          {eventType\n            ? (t(\n                // @ts-ignore\n                `editor.inspect.setter_content.widget_action_type_name.${eventType}`,\n              ) as string)\n            : t(\n                \"editor.inspect.setter_content.event_handler_list.incomplete_selection\",\n              )}\n        </div>\n        <div css={methodNameStyle}>\n          {getMethodName(actionType, widgetID, widgetMethod, queryID)}\n        </div>\n      </div>\n    </Trigger>\n  )\n}\n\nEventAndMethodLabel.displayName = \"EventAndMethodLabel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/interface.ts",
    "content": "export interface ActionMenuProps {\n  index: number\n  label?: string\n  handleCloseMode: () => void\n}\n\nexport interface EventAndMethodLabelProps {\n  index: number\n}\n\nexport interface MoreProps {\n  index: number\n}\n\nexport interface ListBodyProps {\n  events: any[]\n}\n\nexport interface ListItemProps {\n  index: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/item.tsx",
    "content": "import { FC } from \"react\"\nimport { EventAndMethodLabel } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/eventAndMethodLabel\"\nimport { ListItemProps } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/interface\"\nimport { More } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/more\"\nimport {\n  groupWrapperStyle,\n  listItemWrapperStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/style\"\n\nexport const ListItem: FC<ListItemProps> = (props) => {\n  const { index } = props\n  return (\n    <div css={listItemWrapperStyle}>\n      <div css={groupWrapperStyle}>\n        <EventAndMethodLabel index={index} />\n        <More index={index} />\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/more.tsx",
    "content": "import { FC, useCallback, useState } from \"react\"\nimport { Dropdown, MoreIcon } from \"@illa-design/react\"\nimport { ActionMenu } from \"./actionMenu\"\nimport { MoreProps } from \"./interface\"\nimport { moreIconWrapperStyle } from \"./style\"\n\nexport const More: FC<MoreProps> = (props) => {\n  const { index } = props\n\n  const [actionMenuVisible, setActionMenuVisible] = useState(false)\n  const handleCloseActionMenu = useCallback(() => {\n    setActionMenuVisible(false)\n  }, [])\n  return (\n    <Dropdown\n      popupVisible={actionMenuVisible}\n      dropList={\n        <ActionMenu index={index} handleCloseMode={handleCloseActionMenu} />\n      }\n      trigger=\"click\"\n      position=\"bottom-end\"\n      onVisibleChange={(visible) => {\n        setActionMenuVisible(visible)\n      }}\n    >\n      <div css={moreIconWrapperStyle}>\n        <MoreIcon />\n      </div>\n    </Dropdown>\n  )\n}\n\nMore.displayName = \"OptionListSetterMore\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/List/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const listItemStyle = css`\n  width: 100%;\n  height: 32px;\n  border: solid 1px ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  border-radius: 8px;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-05`)};\n  font-size: 12px;\n\n  :not(:first-of-type) {\n    margin-top: 8px;\n  }\n\n  cursor: pointer;\n`\nexport const headerWrapperStyle = css`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  height: 40px;\n`\n\nexport const fontButtonWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  color: ${globalColor(`--${illaPrefix}-purple-03`)};\n  cursor: pointer;\n  height: 24px;\n  padding: 1px 8px;\n  border-radius: 8px;\n  font-size: 14px;\n\n  &:hover {\n    background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  }\n`\n\nexport const fontButtonStyle = css`\n  margin-left: 4px;\n`\n\nexport const listItemWrapperStyle = css`\n  height: 32px;\n  width: 100%;\n`\n\nexport const groupWrapperStyle = css`\n  width: 100%;\n  height: 32px;\n  display: flex;\n`\n\nexport const moreIconWrapperStyle = css`\n  width: 32px;\n  flex: none;\n  height: 32px;\n  border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  border-radius: 0 8px 8px 0;\n  font-size: 14px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  cursor: pointer;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-06`)};\n`\n\nexport const eventAndMethodWrapperStyle = css`\n  display: flex;\n  height: 100%;\n  width: 100%;\n  box-sizing: border-box;\n  border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  border-right: none;\n  border-radius: 8px 0 0 8px;\n  padding: 6px 16px;\n  cursor: pointer;\n  font-size: 12px;\n  gap: 8px;\n  overflow: hidden;\n`\n\nexport const eventNameStyle = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  min-width: 64px;\n  display: block;\n  max-width: 100%;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  overflow: hidden;\n`\n\nexport const methodNameStyle = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  display: block;\n  max-width: 100%;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  overflow: hidden;\n`\n\nexport const emptyBodyStyle = css`\n  min-height: 32px;\n  width: 100%;\n  display: flex;\n  align-items: center;\n  padding: 8px 16px;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  color: ${globalColor(`--${illaPrefix}-grayBlue-03`)};\n  border-radius: 8px;\n  font-size: 14px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/context/index.tsx",
    "content": "import { FC, ReactNode, createContext, useCallback } from \"react\"\nimport { v4 } from \"uuid\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\ninterface ProviderProps {\n  eventItems: any[]\n  childrenSetter: PanelFieldConfig[]\n  widgetDisplayName: string\n  attrPath: string\n  handleUpdateDsl: (attrPath: string, value: any) => void\n  children: ReactNode\n  widgetType: string\n}\n\ninterface Inject extends Omit<ProviderProps, \"children\"> {\n  handleDeleteEventItem: (index: number) => void\n  handleCopyEventItem: (index: number) => void\n}\n\nexport const BaseEventHandlerContext = createContext<Inject>({} as Inject)\n\nexport const BaseEventHandlerProvider: FC<ProviderProps> = (props) => {\n  const { eventItems, attrPath, handleUpdateDsl } = props\n\n  const handleDeleteEventItem = useCallback(\n    (index: number) => {\n      const updatedArray = eventItems.filter(\n        (optionItem: Record<string, any>, i: number) => {\n          return i !== index\n        },\n      )\n      handleUpdateDsl(attrPath, updatedArray)\n    },\n    [eventItems, handleUpdateDsl, attrPath],\n  )\n\n  const handleCopyEventItem = useCallback(\n    (index: number) => {\n      let targetEventItem = eventItems.find(\n        (optionItem: Record<string, any>, i: number) => {\n          return i === index\n        },\n      )\n      if (!targetEventItem) return\n      targetEventItem = {\n        ...targetEventItem,\n        id: `option-${v4()}`,\n      }\n      const updatedArray = [...eventItems, targetEventItem]\n      handleUpdateDsl(attrPath, updatedArray)\n    },\n    [eventItems, handleUpdateDsl, attrPath],\n  )\n\n  const value = {\n    ...props,\n    handleDeleteEventItem,\n    handleCopyEventItem,\n  }\n\n  return (\n    <BaseEventHandlerContext.Provider value={value}>\n      {props.children}\n    </BaseEventHandlerContext.Provider>\n  )\n}\n\nBaseEventHandlerProvider.displayName = \"BaseEventHandlerProvider\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, useCallback } from \"react\"\nimport { BaseEventHandlerProvider } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/context\"\nimport { NewBaseEventHandlerSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/interface\"\nimport { generateNewEventItem } from \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/utils\"\nimport { AddActionLabel } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Label/addActionLabel\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ListBody } from \"./List/body\"\nimport { containerStyle } from \"./style\"\n\nconst EventHandlerSetter: FC<NewBaseEventHandlerSetterProps> = (props) => {\n  const {\n    widgetType,\n    value,\n    childrenSetter,\n    handleUpdateDsl,\n    attrName,\n    widgetDisplayName,\n    labelName,\n    labelDesc,\n    defaultValue,\n    eventHandlerConfig = {\n      events: [`${defaultValue}`],\n      method: [],\n    },\n  } = props\n\n  const handleAddItemAsync = useCallback(async () => {\n    const { events: defaultEvents } = eventHandlerConfig\n    let oldEventItem = Array.isArray(value) ? value : []\n    const eventType =\n      typeof defaultEvents[0] === \"string\"\n        ? defaultEvents[0]\n        : defaultEvents[0].value\n    const newEventItem = generateNewEventItem(eventType, \"query1\")\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"add_event_handler\",\n      parameter1: widgetType,\n    })\n\n    handleUpdateDsl(attrName, [...oldEventItem, newEventItem])\n  }, [eventHandlerConfig, value, widgetType, handleUpdateDsl, attrName])\n\n  if (\n    !childrenSetter ||\n    !Array.isArray(childrenSetter) ||\n    childrenSetter.length < 1\n  )\n    return null\n\n  return (\n    <BaseEventHandlerProvider\n      eventItems={value}\n      attrPath={attrName}\n      handleUpdateDsl={handleUpdateDsl}\n      widgetDisplayName={widgetDisplayName}\n      childrenSetter={childrenSetter}\n      widgetType={widgetType}\n    >\n      <div css={containerStyle}>\n        <AddActionLabel\n          labelName={labelName}\n          labelDesc={labelDesc}\n          handleAddItem={handleAddItemAsync}\n        />\n        <ListBody events={value} />\n      </div>\n    </BaseEventHandlerProvider>\n  )\n}\n\nEventHandlerSetter.displayName = \"EventHandlerSetter\"\nexport default EventHandlerSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelLabelProps } from \"@/page/App/components/InspectPanel/components/Label/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport interface NewBaseEventHandlerSetterProps\n  extends BaseSetter,\n    PanelLabelProps {\n  childrenSetter?: PanelFieldConfig[]\n  eventHandlerConfig?: EventHandlerConfig\n  // TODO: not use any\n  value?: any\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  padding: 8px 16px;\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter/utils/index.ts",
    "content": "import { v4 } from \"uuid\"\n\nexport const generateEventItemId = () => `events-${v4()}`\n\nexport const generateNewEventItem = (event: string, targetId?: string) => {\n  return {\n    id: generateEventItemId(),\n    eventType: event,\n    targetId,\n    type: \"datasource\",\n    method: \"trigger\",\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/IconSetter/IconPickerList.tsx",
    "content": "import { FC } from \"react\"\nimport { isFunction } from \"@illa-design/react\"\nimport { EmptySearchResult } from \"@/page/App/components/EmptySearchResult\"\nimport { IconPickerListProps } from \"@/page/App/components/InspectPanel/PanelSetters/IconSetter/interface\"\nimport {\n  rightBottomItemStyle,\n  rightBottomStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/IconSetter/style\"\nimport { AllData, AllIconData } from \"@/widgetLibrary/IconWidget/utils\"\n\nconst IconPickerList: FC<IconPickerListProps> = (props) => {\n  const { iconOrigin, iconType, searchInput, handleCurrentIconClick } = props\n\n  const iconSets = iconOrigin === \"default\" ? AllData : AllIconData[iconOrigin]\n  const iconsInfo = iconSets\n    ? Object.keys(iconSets).map((key) => ({\n        name: key,\n        getIcon: iconSets[key],\n      }))\n    : []\n\n  const originAndTypeFilter =\n    iconType === \"All\"\n      ? iconsInfo\n      : iconType === \"Filled\"\n      ? iconsInfo.filter((icon) => icon.name.toLowerCase().includes(\"fill\"))\n      : iconsInfo.filter((icon) => icon.name.toLowerCase().includes(\"outline\"))\n\n  const filteredIconsInfoSet = !searchInput\n    ? originAndTypeFilter\n    : originAndTypeFilter.filter((icon) =>\n        icon.name.toLowerCase().includes(searchInput.toLowerCase()),\n      )\n\n  return (\n    <div css={rightBottomStyle}>\n      {filteredIconsInfoSet && filteredIconsInfoSet.length > 0 ? (\n        filteredIconsInfoSet.map((icons) => {\n          const { name, getIcon } = icons\n          return (\n            <span\n              css={rightBottomItemStyle}\n              key={name}\n              onClick={() => handleCurrentIconClick(icons)}\n            >\n              {isFunction(getIcon) && getIcon({})}\n            </span>\n          )\n        })\n      ) : (\n        <EmptySearchResult />\n      )}\n    </div>\n  )\n}\n\nIconPickerList.displayName = \"IconPickerList\"\n\nexport default IconPickerList\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/IconSetter/IconSelector.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, useCallback, useState } from \"react\"\nimport { Trigger } from \"@illa-design/react\"\nimport { IconTriggerComponent } from \"@/page/App/components/InspectPanel/PanelSetters/IconSetter/IconTriggerComponent\"\nimport { BaseIconSetter } from \"@/page/App/components/InspectPanel/PanelSetters/IconSetter/baseIconSetter\"\nimport {\n  IconDataType,\n  IconSelectorProps,\n} from \"@/page/App/components/InspectPanel/PanelSetters/IconSetter/interface\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { AllData } from \"@/widgetLibrary/IconWidget/utils\"\nimport { setterContainerStyle } from \"./style\"\n\nconst IconSelector: FC<IconSelectorProps> = (props) => {\n  const {\n    value,\n    widgetType,\n    attrName,\n    labelName,\n    labelDesc,\n    labelSize,\n    isSetterSingleRow,\n  } = props\n  const [rightPanelData, setRightPanelData] = useState<IconDataType>({\n    name: value,\n    getIcon: AllData[value],\n  })\n  const [modalVisible, setModalVisible] = useState(false)\n\n  const handleCurrentIconClick = useCallback(\n    ({ getIcon, name }: IconDataType) => {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CHANGE, {\n        element: \"component_inspect_select\",\n        parameter1: widgetType,\n        parameter2: attrName,\n        parameter3: name,\n      })\n      setRightPanelData({ getIcon, name })\n      setModalVisible(false)\n    },\n    [attrName, widgetType],\n  )\n\n  const handleCloseModal = useCallback(\n    (visible: boolean) => {\n      if (visible) {\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n          element: \"component_inspect_select\",\n          parameter1: widgetType,\n          parameter2: attrName,\n        })\n      }\n      setModalVisible(visible)\n    },\n    [attrName, widgetType],\n  )\n\n  return (\n    <div css={setterContainerStyle(isSetterSingleRow)}>\n      {labelName && (\n        <span>\n          <PanelLabel\n            labelName={labelName}\n            labelDesc={labelDesc}\n            labelSize={labelSize}\n          />\n        </span>\n      )}\n      <Trigger\n        withoutPadding\n        colorScheme=\"white\"\n        popupVisible={modalVisible}\n        content={\n          <IconTriggerComponent\n            handleCurrentIconClick={handleCurrentIconClick}\n            handleCloseModal={handleCloseModal}\n          />\n        }\n        trigger=\"click\"\n        showArrow={false}\n        position=\"left-start\"\n        clickOutsideToClose\n        onVisibleChange={handleCloseModal}\n      >\n        <div>\n          <BaseIconSetter {...props} showData={rightPanelData} />\n        </div>\n      </Trigger>\n    </div>\n  )\n}\n\nIconSelector.displayName = \"IconSelector\"\nexport default IconSelector\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/IconSetter/IconTriggerComponent.tsx",
    "content": "import { t } from \"i18next\"\nimport { FC, Suspense, lazy, useCallback, useMemo, useState } from \"react\"\nimport { IconManifest } from \"react-icons\"\nimport { CloseIcon, Loading, Search } from \"@illa-design/react\"\nimport {\n  IconShowType,\n  IconTriggerComponentProps,\n} from \"@/page/App/components/InspectPanel/PanelSetters/IconSetter/interface\"\nimport {\n  fallbackContainerStyle,\n  getNameSelectedStyle,\n  getSelectedStyle,\n  headerCloseIconStyle,\n  iconPickerBodyStyle,\n  iconPickerContainerStyle,\n  iconPickerHeaderContainerStyle,\n  iconPickerHeaderTextStyle,\n  iconPickerLeftPanelStyle,\n  iconPickerSearchStyle,\n  leftPanelItemStyle,\n  rightPanelStyle,\n  rightTopItemStyle,\n  rightTopPanelStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/IconSetter/style\"\nimport { ALL_ICONS } from \"@/widgetLibrary/IconWidget/utils\"\n\nconst defaultItem: IconManifest = {\n  id: \"default\",\n  name: \"All\",\n  projectUrl: \"\",\n  license: \"MIT\",\n  licenseUrl: \"https://opensource.org/licenses/MIT\",\n}\n\nconst iconsList = ALL_ICONS.sort((a, b) => (a.name > b.name ? 1 : -1))\nconst [firstItem, ...others] = iconsList\nconst realIconsNameLists = [defaultItem, ...others, firstItem]\nrealIconsNameLists.forEach((nameInfo) => {\n  if (nameInfo.name.length > 16) {\n    const names = nameInfo.name.split(\" \")\n    nameInfo.name = names.slice(0, names.length - 1).join(\" \")\n  }\n})\nconst IconTypes = [\"All\", \"Filled\", \"Outline\"]\n\nexport const IconTriggerComponent: FC<IconTriggerComponentProps> = (props) => {\n  const { handleCurrentIconClick, handleCloseModal } = props\n\n  const [iconType, setIconType] = useState<IconShowType>(\"All\")\n  const [iconOrigin, setIconOrigin] = useState<string>(\"default\")\n  const [searchInput, setSearchInput] = useState<string>(\"\")\n\n  const RightBottomPanel = lazy(() => import(\"./IconPickerList\"))\n\n  const handleOnChange = (value: string) => {\n    setSearchInput(value)\n  }\n\n  const handleIconOriginChange = (origin: string) => {\n    setIconOrigin(origin)\n  }\n\n  const handleIconTypeChange = (type: string) => {\n    setIconType(type as IconShowType)\n  }\n\n  const handleCloseIconClick = useCallback(\n    () => handleCloseModal(false),\n    [handleCloseModal],\n  )\n\n  const Header = useMemo(\n    () => (\n      <div css={iconPickerHeaderContainerStyle}>\n        <div css={iconPickerHeaderTextStyle}>Icon picker</div>\n        <CloseIcon css={headerCloseIconStyle} onClick={handleCloseIconClick} />\n      </div>\n    ),\n    [handleCloseIconClick],\n  )\n\n  const LeftPanel = useMemo(\n    () => (\n      <div css={iconPickerLeftPanelStyle}>\n        {realIconsNameLists.map((info) => {\n          const { name, id } = info\n          return (\n            <div\n              css={[\n                leftPanelItemStyle,\n                getNameSelectedStyle(iconOrigin === id),\n              ]}\n              key={id}\n              onClick={() => handleIconOriginChange(id)}\n            >\n              {name}\n            </div>\n          )\n        })}\n      </div>\n    ),\n    [iconOrigin],\n  )\n\n  const RightTopPanel = useMemo(() => {\n    return (\n      <div css={rightTopPanelStyle}>\n        {IconTypes.map((type) => (\n          <div\n            css={[rightTopItemStyle, getSelectedStyle(iconType === type)]}\n            key={type}\n            onClick={() => handleIconTypeChange(type)}\n          >\n            {type}\n          </div>\n        ))}\n      </div>\n    )\n  }, [iconType])\n\n  const Fallback = () => {\n    return (\n      <div css={fallbackContainerStyle}>\n        <Loading />\n      </div>\n    )\n  }\n\n  const RightBottom = useMemo(() => {\n    return (\n      <Suspense fallback={<Fallback />}>\n        <RightBottomPanel\n          iconOrigin={iconOrigin}\n          iconType={iconType}\n          searchInput={searchInput}\n          handleCurrentIconClick={handleCurrentIconClick}\n        />\n      </Suspense>\n    )\n  }, [\n    RightBottomPanel,\n    handleCurrentIconClick,\n    iconOrigin,\n    iconType,\n    searchInput,\n  ])\n\n  const RightPanel = useMemo(() => {\n    return (\n      <div css={rightPanelStyle}>\n        {RightTopPanel}\n        {RightBottom}\n      </div>\n    )\n  }, [RightBottom, RightTopPanel])\n\n  const IconPickerBody = useMemo(() => {\n    return (\n      <div css={iconPickerBodyStyle}>\n        {LeftPanel}\n        {RightPanel}\n      </div>\n    )\n  }, [LeftPanel, RightPanel])\n\n  const IconSearchBar = useMemo(\n    () => (\n      <div css={iconPickerSearchStyle}>\n        <Search\n          value={searchInput}\n          colorScheme=\"techPurple\"\n          variant=\"fill\"\n          placeholder={t(\"editor.widget_picker.search_placeholder\")}\n          onChange={handleOnChange}\n        />\n      </div>\n    ),\n    [searchInput],\n  )\n\n  return (\n    <div css={iconPickerContainerStyle}>\n      {Header}\n      {IconSearchBar}\n      {IconPickerBody}\n    </div>\n  )\n}\n\nIconTriggerComponent.displayName = \"IconTriggerComponent\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/IconSetter/baseIconSetter.tsx",
    "content": "import { FC, MouseEventHandler, useCallback, useEffect, useState } from \"react\"\nimport { ErrorCircleIcon, getColor } from \"@illa-design/react\"\nimport {\n  applyBaseIconWrapperStyle,\n  clearIconStyle,\n  iconContentStyle,\n  iconSelectorContainerStyle,\n  iconSelectorIconStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/IconSetter/style\"\nimport { BaseIconSetterProps, IconDataType } from \"./interface\"\n\nexport const BaseIconSetter: FC<BaseIconSetterProps> = (props) => {\n  const { attrName, isSetterSingleRow, handleUpdateDsl, showData } = props\n\n  const [displayData, setDisplayData] = useState<IconDataType | undefined>(\n    undefined,\n  )\n\n  useEffect(() => {\n    handleUpdateDsl(attrName, showData?.name)\n    setDisplayData(showData)\n  }, [attrName, handleUpdateDsl, showData])\n\n  const handleClearClick: MouseEventHandler<HTMLDivElement> = useCallback(\n    (event) => {\n      event.stopPropagation()\n      setDisplayData(undefined)\n      handleUpdateDsl(attrName, undefined)\n    },\n    [attrName, handleUpdateDsl],\n  )\n\n  return (\n    <div css={applyBaseIconWrapperStyle(isSetterSingleRow)}>\n      <div css={iconSelectorContainerStyle}>\n        <div css={iconSelectorIconStyle}>\n          {displayData?.getIcon && displayData?.getIcon({})}\n        </div>\n        <span css={iconContentStyle}>{displayData?.name ?? \"\"}</span>\n        <div css={clearIconStyle} onClick={handleClearClick}>\n          <ErrorCircleIcon color={getColor(\"grayBlue\", \"05\")} />\n        </div>\n      </div>\n    </div>\n  )\n}\n\nBaseIconSetter.displayName = \"BaseIconSetter\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/IconSetter/interface.ts",
    "content": "import { IconType } from \"react-icons\"\nimport { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\n\nexport type IconShowType = \"All\" | \"Filled\" | \"Outline\"\n\nexport type IconDataType = {\n  name: string\n  getIcon: IconType\n}\n\nexport interface BaseIconSetterProps extends BaseSetter {\n  showData?: IconDataType\n}\n\nexport interface IconSelectorProps extends BaseSetter {\n  value: string\n  labelSize?: \"medium\" | \"small\"\n}\n\nexport interface IconPickerListProps {\n  iconType: IconShowType\n  iconOrigin: string\n  searchInput: string\n  handleCurrentIconClick: (info: IconDataType) => void\n}\n\nexport interface IconTriggerComponentProps {\n  handleCurrentIconClick: (info: IconDataType) => void\n  handleCloseModal: (visible: boolean) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/IconSetter/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\nimport { fixedWidthStyle } from \"@/page/App/components/InspectPanel/PanelSetters/style\"\n\nexport const applyBaseIconWrapperStyle = (\n  isSetterSingleRow: boolean = false,\n): SerializedStyles => {\n  const width = isSetterSingleRow\n    ? css`\n        width: 100%;\n      `\n    : fixedWidthStyle\n  return css`\n    ${width};\n    height: 100%;\n  `\n}\n\nexport const iconSelectorIconStyle = css`\n  width: 24px;\n  height: 24px;\n  padding: 4px;\n  & > svg {\n    width: 16px;\n    height: 16px;\n  }\n`\n\nexport const iconSelectorContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  position: relative;\n  border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  padding: 3px 12px;\n  border-radius: 8px;\n  cursor: pointer;\n  gap: 8px;\n  display: flex;\n  overflow: hidden;\n  align-items: center;\n  :hover > div:last-child {\n    display: flex;\n  }\n`\n\nexport const iconContentStyle = css`\n  height: 100%;\n  display: flex;\n  font-size: 12px;\n  line-height: 22px;\n  text-overflow: ellipsis;\n  overflow: hidden;\n  white-space: nowrap;\n`\n\nexport const clearIconStyle = css`\n  width: 16px;\n  height: 16px;\n  display: none;\n  cursor: pointer;\n  position: absolute;\n  right: 12px;\n  top: 8px;\n  justify-content: center;\n  align-items: center;\n  & > svg {\n    width: 12px;\n    height: 12px;\n  }\n`\n\nexport const iconPickerContainerStyle = css`\n  min-width: 545px;\n  height: 546px;\n  display: flex;\n  flex-direction: column;\n`\n\nexport const iconPickerHeaderContainerStyle = css`\n  width: 100%;\n  height: 56px;\n  padding: 16px;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n`\nexport const iconPickerHeaderTextStyle = css`\n  font-weight: 600;\n  font-size: 16px;\n  line-height: 24px;\n`\n\nexport const iconPickerSearchStyle = css`\n  width: 100%;\n  height: 48px;\n  padding: 0 16px 16px 16px;\n  box-shadow: inset 0px -1px 0px ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n`\n\nexport const iconPickerBodyStyle = css`\n  width: 100%;\n  flex: 1;\n  display: flex;\n  overflow: scroll;\n`\n\nexport const iconPickerLeftPanelStyle = css`\n  flex: 1;\n  max-height: 100%;\n  height: 100%;\n  overflow: scroll;\n  display: flex;\n  flex-direction: column;\n  align-items: flex-start;\n  padding: 8px 0px;\n  border-bottom-left-radius: 8px;\n  flex: none;\n`\n\nexport const leftPanelItemStyle = css`\n  width: 100%;\n  min-height: 40px;\n  cursor: pointer;\n  text-overflow: ellipsis;\n  overflow: hidden;\n  white-space: nowrap;\n  padding: 9px 16px;\n  font-size: 14px;\n  line-height: 22px;\n  font-weight: 500;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  background: ${globalColor(`--${illaPrefix}-white-01`)};\n`\n\nexport const rightPanelStyle = css`\n  width: 440px;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  border-left: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n`\n\nexport const rightTopPanelStyle = css`\n  width: 100%;\n  height: 40px;\n  background: ${globalColor(`--${illaPrefix}-white-01`)};\n  padding: 8px 0 0;\n  display: flex;\n  align-items: center;\n`\n\nexport const getSelectedStyle = (selected: boolean) => {\n  if (selected) {\n    return css`\n      box-shadow: inset 0px -2px 0px ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n    `\n  } else {\n    return css``\n  }\n}\n\nexport const getNameSelectedStyle = (selected: boolean) => {\n  if (selected) {\n    return css`\n      background: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n    `\n  } else {\n    return css``\n  }\n}\n\nexport const rightTopItemStyle = css`\n  width: auto;\n  height: 32px;\n  background: ${globalColor(`--${illaPrefix}-white-01`)};\n  padding: 0 16px;\n  display: flex;\n  align-items: center;\n  cursor: pointer;\n  justify-content: center;\n`\n\nexport const rightBottomStyle = css`\n  width: 100%;\n  flex-grow: 1;\n  min-width: 400px;\n  overflow: scroll;\n  padding: 0px 8px 8px;\n  display: flex;\n  flex-direction: row;\n  flex-wrap: wrap;\n  align-content: flex-start;\n`\n\nexport const rightBottomItemStyle = css`\n  width: 48px;\n  cursor: pointer;\n  height: 48px;\n  display: inline-block;\n  padding: 12px;\n  & > svg {\n    width: 24px;\n    height: 24px;\n  }\n`\n\nexport const headerCloseIconStyle = css`\n  cursor: pointer;\n`\n\nexport const fallbackContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  padding: 0px 8px 8px;\n  justify-content: center;\n  align-items: center;\n`\n\nexport const setterContainerStyle = (isSetterSingleRow: boolean = false) => {\n  const basicStyle = css`\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n  `\n  const singleRowStyle = css`\n    flex-direction: column;\n    gap: 8px;\n  `\n  return css`\n    display: flex;\n    padding: 8px 0;\n    ${isSetterSingleRow ? singleRowStyle : basicStyle};\n    width: 100%;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/BaseInput/index.tsx",
    "content": "import { hasDynamicStringSnippet } from \"@illa-public/dynamic-string\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { isString } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport {\n  getNeedComputedValueWithList,\n  realInputValueWithList,\n} from \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/util\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { getContainerListDisplayNameMappedChildrenNodeDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { NewBaseInputSetterProps } from \"./interface\"\nimport { applyInputSetterWrapperStyle, setterContainerStyle } from \"./style\"\n\nconst BaseInput: FC<NewBaseInputSetterProps> = (props) => {\n  const {\n    isSetterSingleRow,\n    placeholder,\n    attrName,\n    handleUpdateDsl,\n    expectedType,\n    value,\n    widgetDisplayName,\n    labelName,\n    detailedDescription,\n    defaultValue,\n    labelDesc,\n    widgetType,\n    wrappedCodeFunc,\n    labelSize,\n    onlyHasSetter = false,\n  } = props\n\n  const listWidgets = useSelector(\n    getContainerListDisplayNameMappedChildrenNodeDisplayName,\n  )\n\n  const currentListDisplayName = useMemo(() => {\n    const listWidgetDisplayNames = Object.keys(listWidgets)\n    for (let i = 0; i < listWidgetDisplayNames.length; i++) {\n      if (listWidgets[listWidgetDisplayNames[i]].includes(widgetDisplayName)) {\n        return listWidgetDisplayNames[i]\n      }\n    }\n    return \"\"\n  }, [listWidgets, widgetDisplayName])\n\n  const finalWrapperCode = useMemo(() => {\n    if (\n      currentListDisplayName &&\n      hasDynamicStringSnippet(value ?? \"\") &&\n      value?.includes(\"currentItem\")\n    ) {\n      return (value: string) => {\n        return getNeedComputedValueWithList(value, currentListDisplayName)\n      }\n    }\n    return wrappedCodeFunc\n  }, [currentListDisplayName, value, wrappedCodeFunc])\n\n  const finalValue = useMemo(() => {\n    if (currentListDisplayName) {\n      return realInputValueWithList(\n        value ?? defaultValue,\n        currentListDisplayName,\n      )\n    }\n\n    if (value === undefined && defaultValue === undefined) {\n      return undefined\n    }\n\n    if (!isString(value ?? defaultValue)) {\n      return `{{ ${value ?? defaultValue} }}`\n    }\n    return value ?? defaultValue\n  }, [currentListDisplayName, defaultValue, value])\n\n  const onChange = useCallback(\n    (value: string) => {\n      let output = value\n      if (\n        currentListDisplayName &&\n        hasDynamicStringSnippet(value ?? \"\") &&\n        value.includes(\"currentItem\")\n      ) {\n        output = getNeedComputedValueWithList(value, currentListDisplayName)\n      }\n      handleUpdateDsl(attrName, output)\n    },\n    [attrName, currentListDisplayName, handleUpdateDsl],\n  )\n\n  const onFocus = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.FOCUS, {\n      element: \"component_inspect_code_mirror\",\n      parameter1: widgetType,\n      parameter2: attrName,\n    })\n  }, [attrName, widgetType])\n\n  const onBlur = useCallback(\n    (value: string) => {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n        element: \"component_inspect_code_mirror\",\n        parameter1: widgetType,\n        parameter2: attrName,\n        parameter3: value.length,\n      })\n    },\n    [attrName, widgetType],\n  )\n\n  return (\n    <div css={setterContainerStyle(isSetterSingleRow, onlyHasSetter)}>\n      {!onlyHasSetter && labelName && (\n        <span>\n          <PanelLabel\n            labelName={labelName}\n            labelDesc={labelDesc}\n            labelSize={labelSize}\n          />\n        </span>\n      )}\n      <div css={applyInputSetterWrapperStyle(isSetterSingleRow)}>\n        <CodeEditor\n          scopeOfAutoComplete=\"page\"\n          value={finalValue}\n          onChange={onChange}\n          showLineNumbers={false}\n          placeholder={placeholder}\n          expectValueType={currentListDisplayName ? undefined : expectedType}\n          lang={CODE_LANG.JAVASCRIPT}\n          maxHeight=\"208px\"\n          maxWidth=\"100%\"\n          codeType={CODE_TYPE.EXPRESSION}\n          modalTitle={labelName}\n          modalDescription={detailedDescription ?? labelDesc}\n          onFocus={onFocus}\n          onBlur={onBlur}\n          wrappedCodeFunc={finalWrapperCode}\n        />\n      </div>\n    </div>\n  )\n}\n\nBaseInput.displayName = \"BaseInput\"\nexport default BaseInput\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/BaseInput/interface.ts",
    "content": "import { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface NewBaseInputSetterProps {\n  isSetterSingleRow?: boolean\n  placeholder?: string\n  attrName: string\n  defaultValue?: any\n  handleUpdateDsl: (attrPath: string, value: any) => void\n  expectedType?: VALIDATION_TYPES\n  value?: string\n  widgetDisplayName: string\n  labelName?: string\n  detailedDescription?: string\n  labelDesc?: string\n  widgetType: string\n  wrappedCodeFunc?: (code: string) => string\n  labelSize?: \"medium\" | \"small\"\n  onlyHasSetter?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/BaseInput/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { fixedWidthStyle } from \"../../style\"\n\nexport const applyInputSetterWrapperStyle = (\n  isSetterSingleRow: boolean = false,\n) => {\n  return isSetterSingleRow\n    ? css`\n        width: 100%;\n      `\n    : fixedWidthStyle\n}\n\nexport const setterContainerStyle = (\n  isSetterSingleRow: boolean = false,\n  onlyHasSetter: boolean,\n) => {\n  const basicStyle = css`\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n  `\n  const singleRowStyle = css`\n    flex-direction: column;\n    gap: 8px;\n  `\n  return css`\n    display: flex;\n    padding: ${onlyHasSetter ? `0` : `8px 0`};\n    ${isSetterSingleRow ? singleRowStyle : basicStyle};\n    width: 100%;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/FileMinMaxSetter/index.tsx",
    "content": "import { FC, useCallback, useMemo, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport {\n  DownIcon,\n  Trigger,\n  UpIcon,\n  isNumber,\n  isString,\n} from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport {\n  getNeedComputedValueWithList,\n  realInputValueWithList,\n} from \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/util\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { getContainerListDisplayNameMappedChildrenNodeDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { FileMinMaxSetterProps } from \"./interface\"\nimport {\n  codeEditorContainerStyle,\n  codeEditorWrapperStyle,\n  dashCharStyle,\n  dropListItemStyle,\n  inputWithSelectSetterStyle,\n  labelContainerStyle,\n  panelLabelContainerStyle,\n  sizeContainerStyle,\n  sizeDropListStyle,\n  sizeSelectionStyle,\n} from \"./style\"\n\nconst options = [\n  { label: \"KB\", value: \"kb\" },\n  { label: \"MB\", value: \"mb\" },\n]\n\nconst FileMinMaxSetter: FC<FileMinMaxSetterProps> = (props) => {\n  const {\n    labelName,\n    labelDesc,\n    handleUpdateDsl,\n    widgetDisplayName,\n    placeholder,\n    componentNode,\n  } = props\n\n  const sizeType = componentNode?.props?.sizeType ?? \"\"\n  const maxSize = componentNode?.props?.maxSize ?? \"\"\n  const minSize = componentNode?.props?.minSize ?? \"\"\n\n  const [popupVisible, setPopupVisible] = useState<boolean>(false)\n  const { t } = useTranslation()\n\n  const listWidgets = useSelector(\n    getContainerListDisplayNameMappedChildrenNodeDisplayName,\n  )\n\n  const currentListDisplayName = useMemo(() => {\n    const listWidgetDisplayNames = Object.keys(listWidgets)\n    for (let i = 0; i < listWidgetDisplayNames.length; i++) {\n      if (listWidgets[listWidgetDisplayNames[i]].includes(widgetDisplayName)) {\n        return listWidgetDisplayNames[i]\n      }\n    }\n    return \"\"\n  }, [listWidgets, widgetDisplayName])\n\n  const finalMaxSize = useMemo(() => {\n    if (currentListDisplayName) {\n      return realInputValueWithList(maxSize, currentListDisplayName)\n    }\n    return maxSize\n  }, [currentListDisplayName, maxSize])\n\n  const finalMinSize = useMemo(() => {\n    if (currentListDisplayName) {\n      return realInputValueWithList(minSize, currentListDisplayName)\n    }\n    return minSize\n  }, [currentListDisplayName, minSize])\n\n  const onChange = useCallback(\n    (value: string, attrName: string) => {\n      let output = value\n      if (currentListDisplayName) {\n        output = getNeedComputedValueWithList(value, currentListDisplayName)\n      }\n\n      handleUpdateDsl(attrName, output)\n    },\n    [currentListDisplayName, handleUpdateDsl],\n  )\n\n  const onVisibleChange = (visible: boolean) => {\n    if (popupVisible !== visible) {\n      setPopupVisible(visible)\n    }\n  }\n\n  const handleOptionsItemClick = (value: string | number) => {\n    handleUpdateDsl(\"sizeType\", value)\n    onVisibleChange(false)\n  }\n  return (\n    <div css={inputWithSelectSetterStyle}>\n      <div css={labelContainerStyle}>\n        <div css={panelLabelContainerStyle}>\n          <PanelLabel labelName={labelName} labelDesc={labelDesc} />\n        </div>\n        <div>\n          {options && (\n            <Trigger\n              trigger=\"click\"\n              colorScheme=\"white\"\n              position=\"bottom-start\"\n              withoutPadding\n              showArrow={false}\n              popupVisible={popupVisible}\n              onVisibleChange={onVisibleChange}\n              content={\n                <div css={sizeDropListStyle}>\n                  {options.map((option) => {\n                    let label\n                    let value: number | string\n                    if (isString(option) || isNumber(option)) {\n                      label = value = option\n                    } else {\n                      label = option.label\n                      value = option.value\n                    }\n                    return (\n                      <div\n                        css={dropListItemStyle}\n                        key={value}\n                        onClick={() => handleOptionsItemClick(value)}\n                      >\n                        {label}\n                      </div>\n                    )\n                  })}\n                </div>\n              }\n            >\n              <div css={sizeContainerStyle}>\n                <div css={sizeSelectionStyle}>{sizeType?.toUpperCase()}</div>\n                {popupVisible ? <UpIcon /> : <DownIcon />}\n              </div>\n            </Trigger>\n          )}\n        </div>\n      </div>\n      <div css={codeEditorContainerStyle}>\n        <CodeEditor\n          scopeOfAutoComplete=\"page\"\n          wrapperCss={codeEditorWrapperStyle}\n          value={finalMinSize}\n          onChange={(value) => onChange(value, \"minSize\")}\n          showLineNumbers={false}\n          expectValueType={VALIDATION_TYPES.NUMBER}\n          lang={CODE_LANG.JAVASCRIPT}\n          maxHeight=\"208px\"\n          placeholder={placeholder}\n          maxWidth=\"100%\"\n          codeType={CODE_TYPE.EXPRESSION}\n          modalTitle={t(\"editor.inspect.setter_label.max_size\")}\n        />\n        <div css={dashCharStyle}>~</div>\n        <CodeEditor\n          scopeOfAutoComplete=\"page\"\n          wrapperCss={codeEditorWrapperStyle}\n          value={finalMaxSize}\n          onChange={(value) => onChange(value, \"maxSize\")}\n          showLineNumbers={false}\n          expectValueType={VALIDATION_TYPES.NUMBER}\n          lang={CODE_LANG.JAVASCRIPT}\n          placeholder={placeholder}\n          maxHeight=\"208px\"\n          maxWidth=\"100%\"\n          codeType={CODE_TYPE.EXPRESSION}\n          modalTitle={t(\"editor.inspect.setter_label.min_size\")}\n        />\n      </div>\n    </div>\n  )\n}\nFileMinMaxSetter.displayName = \"FileMinMaxSetter\"\nexport default FileMinMaxSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/FileMinMaxSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelLabelProps } from \"@/page/App/components/InspectPanel/components/Label/interface\"\n\nexport interface FileMinMaxSetterProps extends BaseSetter, PanelLabelProps {\n  placeholder?: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/FileMinMaxSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const codeEditorContainerStyle = css`\n  width: 100%;\n  display: flex;\n  justify-content: center;\n`\n\nexport const codeEditorWrapperStyle = css`\n  flex: 1;\n  .cm-editor {\n    border-radius: 8px;\n  }\n`\nexport const dashCharStyle = css`\n  width: 9px;\n  line-height: 22px;\n  margin: 0 8px;\n  display: flex;\n  align-items: center;\n`\n\nexport const dropListItemStyle = css`\n  padding: 10px 16px;\n  cursor: pointer;\n  transition: background-color 0.3s;\n  &:hover {\n    background-color: ${getColor(\"grayBlue\", \"09\")};\n  }\n`\n\nexport const inputWithSelectSetterStyle = css`\n  display: flex;\n  align-items: center;\n  flex-direction: column;\n  position: relative;\n  width: 100%;\n  padding: 8px 16px;\n  gap: 8px;\n`\n\nexport const labelContainerStyle = css`\n  width: 100%;\n  display: flex;\n  justify-content: space-between;\n`\n\nexport const panelLabelContainerStyle = css`\n  width: 66%;\n  display: flex;\n  align-items: center;\n`\n\nexport const sizeContainerStyle = css`\n  display: flex;\n  width: 44px;\n  height: 100%;\n  z-index: 1;\n  gap: 4px;\n  cursor: pointer;\n  border-left: none;\n  align-items: center;\n  padding: 2px;\n  & > svg {\n    width: 12px;\n    height: 12px;\n  }\n`\n\nexport const sizeDropListStyle = css`\n  width: 100px;\n  padding: 8px 0;\n  font-size: 14px;\n  line-height: 22px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const sizeSelectionStyle = css`\n  line-height: 26px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/MeasureCheckInput/index.tsx",
    "content": "import { FC, FocusEvent, useCallback } from \"react\"\nimport { Input } from \"@illa-design/react\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { MeasureCheckInputSetterProps } from \"./interface\"\nimport { setterContainerStyle } from \"./style\"\n\nconst valueWithMeasureRegex = /^\\d+(\\.\\d+)?(px|vh|vw|%|em|rem|cm|mm|in|pt|pc)$/\n\nconst MeasureCheckInput: FC<MeasureCheckInputSetterProps> = (props) => {\n  const {\n    handleUpdateMultiAttrDSL,\n    attrName,\n    value,\n    icon,\n    labelName,\n    labelSize = \"small\",\n    labelDesc,\n  } = props\n\n  const handleUpdateBorderWidth = useCallback(\n    (currentValue: string) => {\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: currentValue,\n      })\n    },\n    [attrName, handleUpdateMultiAttrDSL],\n  )\n\n  const fixInputValueWhenBlur = useCallback(\n    (e: FocusEvent<HTMLInputElement>) => {\n      let currentValue = e.target.value.toLocaleLowerCase().replace(/\\s*/g, \"\")\n      if (currentValue && !valueWithMeasureRegex.test(currentValue)) {\n        const decimalArr = currentValue.match(/\\d+(\\.\\d+)?/g)\n        if (decimalArr) currentValue = decimalArr.join(\"\") + \"px\"\n      }\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: currentValue,\n      })\n    },\n    [attrName, handleUpdateMultiAttrDSL],\n  )\n\n  return (\n    <div css={setterContainerStyle}>\n      <PanelLabel\n        labelName={labelName}\n        labelDesc={labelDesc}\n        labelSize={labelSize}\n      />\n      <Input\n        onChange={handleUpdateBorderWidth}\n        value={value}\n        prefix={icon}\n        w=\"170px\"\n        onBlur={fixInputValueWhenBlur}\n        colorScheme=\"techPurple\"\n      />\n    </div>\n  )\n}\n\nexport default MeasureCheckInput\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/MeasureCheckInput/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface MeasureCheckInputSetterProps {\n  value: string\n  handleUpdateMultiAttrDSL?: (updateSlice: Record<string, any>) => void\n  attrName: string\n  labelName?: string\n  labelDesc?: string\n  labelSize?: \"medium\" | \"small\"\n  icon?: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/MeasureCheckInput/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const setterContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 8px 0;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/OptionMappedInput/optionMappedInputSetter.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport {\n  getNeedComputedValue,\n  realInputValue,\n} from \"@/utils/InspectHelper/selectWidgetHelper\"\nimport BaseInput from \"../BaseInput\"\nimport { BaseInputSetterProps } from \"../interface\"\n\nconst OptionMappedInputSetter: FC<BaseInputSetterProps> = (props) => {\n  const { handleUpdateDsl, value, widgetDisplayName } = props\n\n  const handleValueChange = useCallback(\n    (attrName: string, value: string) => {\n      const output = getNeedComputedValue(value, widgetDisplayName)\n      handleUpdateDsl(attrName, output)\n    },\n    [handleUpdateDsl, widgetDisplayName],\n  )\n\n  const wrappedCodeFunc = useCallback(\n    (value: string) => {\n      return getNeedComputedValue(value, widgetDisplayName)\n    },\n    [widgetDisplayName],\n  )\n\n  return (\n    <BaseInput\n      {...props}\n      value={realInputValue(value, widgetDisplayName)}\n      handleUpdateDsl={handleValueChange}\n      wrappedCodeFunc={wrappedCodeFunc}\n    />\n  )\n}\n\nOptionMappedInputSetter.displayName = \"OptionMappedInputSetter\"\nexport default OptionMappedInputSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/PaddingInput/index.tsx",
    "content": "import PartialIcon from \"@assets/rightPagePanel/partial.svg?react\"\nimport { PADDING_MODE } from \"@illa-public/public-types\"\nimport { get } from \"lodash-es\"\nimport { FC, FocusEventHandler, useRef } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { Input, RadioGroup } from \"@illa-design/react\"\nimport AllIcon from \"@/assets/rightPagePanel/all.svg?react\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { DirectionPaddingSetterProps } from \"./interface\"\nimport {\n  directionPaddingContainerStyle,\n  optionsIconHotSpotStyle,\n  prefixContainerStyle,\n  setterContainerStyle,\n} from \"./style\"\n\nconst formatValue = (value: string = \"\") => {\n  const values = value\n    .split(\" \")\n    .filter((v) => v !== \"\")\n    .filter((v) => !isNaN(Number(v)))\n  if (values.length === 2) {\n    return `${values[0]} ${values[1]} 0 0`\n  }\n  if (values.length === 3) {\n    return `${values[0]} ${values[1]} ${values[2]} 0`\n  }\n  if (values.length > 4) {\n    return `${values[0]} ${values[1]} ${values[2]} ${values[3]}`\n  }\n  return values.join(\" \")\n}\n\nconst formatPartialValue = (value: string = \"\") => {\n  if (!/^[0-9]+$/.test(value)) {\n    return \"0\"\n  }\n  return value\n}\n\nconst options = [\n  {\n    label: (\n      <div css={optionsIconHotSpotStyle}>\n        <AllIcon />\n      </div>\n    ),\n    value: PADDING_MODE.ALL,\n  },\n  {\n    label: (\n      <div css={optionsIconHotSpotStyle}>\n        <PartialIcon />\n      </div>\n    ),\n    value: PADDING_MODE.PARTIAL,\n  },\n]\n\nexport const DirectionPaddingSetter: FC<DirectionPaddingSetterProps> = (\n  props,\n) => {\n  const dispatch = useDispatch()\n  const { handleUpdateMultiAttrDSL, componentNode, attrName, labelName } = props\n\n  const paddingValue = {\n    mode: get(componentNode, `props.${attrName}.mode`, PADDING_MODE.ALL),\n    size: get(componentNode, `props.${attrName}.size`, \"0\"),\n  }\n\n  const values = paddingValue.size.split(\" \")\n  const isAll = paddingValue.mode === PADDING_MODE.ALL\n\n  const allInputRef = useRef<HTMLInputElement>(null)\n\n  const handleChangeAllValue = (allValue: string) => {\n    handleUpdateMultiAttrDSL?.({\n      [attrName]: {\n        mode: PADDING_MODE.ALL,\n        size: allValue,\n      },\n    })\n  }\n\n  const handleBlurAllValue: FocusEventHandler<HTMLInputElement> = (e) => {\n    handleUpdateMultiAttrDSL?.({\n      [attrName]: {\n        mode: PADDING_MODE.ALL,\n        size: formatValue(e.target.value ?? \"\"),\n      },\n    })\n    dispatch(configActions.updateShowDot(false))\n  }\n\n  const handleChangePartialValue = (index: number) => {\n    return (partialValue: string) => {\n      values[index] = partialValue\n      if (partialValue !== \"\" && !/^[0-9]+$/.test(partialValue)) return\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: {\n          mode: PADDING_MODE.PARTIAL,\n          size: values.join(\" \"),\n        },\n      })\n    }\n  }\n\n  const handleChangeMode = (mode: PADDING_MODE) => {\n    if (paddingValue.mode === mode) return\n    switch (mode) {\n      case PADDING_MODE.ALL: {\n        let result = paddingValue.size\n        const partialSize = Array.from(new Set(paddingValue.size.split(\" \")))\n        if (partialSize.length === 1) {\n          result = partialSize[0]\n        }\n\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: {\n            size: result,\n            mode: mode,\n          },\n        })\n        break\n      }\n      case PADDING_MODE.PARTIAL: {\n        const partialSize = paddingValue.size.split(\" \")\n        let result = paddingValue.size\n        if (partialSize.length === 1) {\n          result = `${partialSize[0]} ${partialSize[0]} ${partialSize[0]} ${partialSize[0]}`\n        }\n        if (partialSize.length === 4) {\n          result = `${partialSize[0]} ${partialSize[1]} ${partialSize[2]} ${partialSize[3]}`\n        }\n\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: {\n            size: result,\n            mode: mode,\n          },\n        })\n        break\n      }\n    }\n  }\n\n  const handleOnFocus = () => {\n    dispatch(configActions.updateShowDot(true))\n  }\n\n  const handleOnBlurPartialValue = (index: number) => {\n    const fixFunc: FocusEventHandler<HTMLInputElement> = (e) => {\n      dispatch(configActions.updateShowDot(false))\n      const value = formatPartialValue(e.target.value)\n      values[index] = value\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: {\n          mode: PADDING_MODE.PARTIAL,\n          size: values.join(\" \"),\n        },\n      })\n    }\n    return fixFunc\n  }\n\n  return (\n    <>\n      <div css={setterContainerStyle}>\n        <PanelLabel labelName={labelName} />\n        <RadioGroup\n          type=\"button\"\n          options={options}\n          value={paddingValue.mode}\n          onChange={handleChangeMode}\n          size=\"small\"\n          w=\"105px\"\n          forceEqualWidth\n        />\n      </div>\n      <div css={directionPaddingContainerStyle}>\n        {isAll ? (\n          <Input\n            prefix={<span css={prefixContainerStyle}>All</span>}\n            colorScheme=\"techPurple\"\n            value={values.join(\" \")}\n            ref={allInputRef}\n            onFocus={handleOnFocus}\n            onChange={handleChangeAllValue}\n            onBlur={handleBlurAllValue}\n          />\n        ) : (\n          <>\n            <Input\n              prefix={<span css={prefixContainerStyle}>T</span>}\n              colorScheme=\"techPurple\"\n              bdRadius=\"8px 0 0 8px\"\n              value={values[0]}\n              onFocus={handleOnFocus}\n              onBlur={handleOnBlurPartialValue(0)}\n              onChange={handleChangePartialValue(0)}\n            />\n            <Input\n              prefix={<span css={prefixContainerStyle}>R</span>}\n              colorScheme=\"techPurple\"\n              bdRadius=\"0\"\n              pos=\"relative\"\n              l=\"-1px\"\n              value={values[1]}\n              onFocus={handleOnFocus}\n              onBlur={handleOnBlurPartialValue(1)}\n              onChange={handleChangePartialValue(1)}\n            />\n            <Input\n              prefix={<span css={prefixContainerStyle}>B</span>}\n              colorScheme=\"techPurple\"\n              bdRadius=\"0\"\n              pos=\"relative\"\n              l=\"-2px\"\n              value={values[2]}\n              onFocus={handleOnFocus}\n              onBlur={handleOnBlurPartialValue(2)}\n              onChange={handleChangePartialValue(2)}\n            />\n            <Input\n              prefix={<span css={prefixContainerStyle}>L</span>}\n              colorScheme=\"techPurple\"\n              bdRadius=\"0 8px 8px 0\"\n              pos=\"relative\"\n              l=\"-3px\"\n              value={values[3]}\n              onFocus={handleOnFocus}\n              onBlur={handleOnBlurPartialValue(3)}\n              onChange={handleChangePartialValue(3)}\n            />\n          </>\n        )}\n      </div>\n    </>\n  )\n}\n\nexport default DirectionPaddingSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/PaddingInput/interface.ts",
    "content": "import { BaseInputSetterProps } from \"../interface\"\n\nexport interface DirectionPaddingSetterProps extends BaseInputSetterProps {\n  value?: any\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/PaddingInput/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const directionPaddingContainerStyle = css`\n  display: flex;\n  padding: 8px 16px;\n`\n\nexport const setterContainerStyle = css`\n  padding: 8px 16px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n`\n\nexport const optionsIconHotSpotStyle = css`\n  width: 16px;\n  height: 16px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n\nexport const prefixContainerStyle = css`\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 12px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/ScriptInput/index.tsx",
    "content": "import { hasDynamicStringSnippet } from \"@illa-public/dynamic-string\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { RUN_SCRIPT_DOC_LINK } from \"@illa-public/public-configs\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { Link } from \"react-router-dom\"\nimport { Button, DocsIcon } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport {\n  getNeedComputedValueWithList,\n  realInputValueWithList,\n} from \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/util\"\nimport { getContainerListDisplayNameMappedChildrenNodeDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport {\n  realInputValueWithScript,\n  wrapperScriptCode,\n} from \"@/utils/evaluateDynamicString/valueConverter\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { BaseInputSetterProps } from \"../interface\"\nimport {\n  applyInputSetterWrapperStyle,\n  docComponentContainerStyle,\n} from \"./style\"\n\nconst ScriptInput: FC<BaseInputSetterProps> = (props) => {\n  const {\n    className,\n    placeholder,\n    attrName,\n    handleUpdateDsl,\n    value,\n    widgetDisplayName,\n    labelName,\n    detailedDescription,\n    labelDesc,\n    widgetType,\n  } = props\n\n  const { t } = useTranslation()\n\n  const listWidgets = useSelector(\n    getContainerListDisplayNameMappedChildrenNodeDisplayName,\n  )\n\n  const currentListDisplayName = useMemo(() => {\n    const listWidgetDisplayNames = Object.keys(listWidgets)\n    for (let i = 0; i < listWidgetDisplayNames.length; i++) {\n      if (listWidgets[listWidgetDisplayNames[i]].includes(widgetDisplayName)) {\n        return listWidgetDisplayNames[i]\n      }\n    }\n    return \"\"\n  }, [listWidgets, widgetDisplayName])\n\n  const finalValue = useMemo(() => {\n    let tempValue = value\n    if (currentListDisplayName) {\n      tempValue = realInputValueWithList(value, currentListDisplayName)\n    }\n    return realInputValueWithScript(tempValue, true)\n  }, [currentListDisplayName, value])\n\n  const onChange = useCallback(\n    (value: string) => {\n      let output = value\n      if (\n        currentListDisplayName &&\n        hasDynamicStringSnippet(value ?? \"\") &&\n        value.includes(\"currentItem\")\n      ) {\n        output = getNeedComputedValueWithList(value, currentListDisplayName)\n      }\n      output = wrapperScriptCode(output, true)\n      handleUpdateDsl(attrName, output)\n    },\n    [attrName, currentListDisplayName, handleUpdateDsl],\n  )\n\n  const onFocus = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.FOCUS, {\n      element: \"component_inspect_code_mirror\",\n      parameter1: widgetType,\n      parameter2: attrName,\n    })\n  }, [attrName, widgetType])\n\n  const onBlur = useCallback(\n    (value: string) => {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n        element: \"component_inspect_code_mirror\",\n        parameter1: widgetType,\n        parameter2: attrName,\n        parameter3: value.length,\n      })\n    },\n    [attrName, widgetType],\n  )\n\n  return (\n    <div css={applyInputSetterWrapperStyle}>\n      <div css={docComponentContainerStyle}>\n        <Link to={RUN_SCRIPT_DOC_LINK} target=\"_blank\">\n          <Button\n            leftIcon={<DocsIcon />}\n            colorScheme=\"grayBlue\"\n            variant=\"text\"\n            size=\"small\"\n          >\n            {t(\"editor.inspect.header.action_menu.view_documentation\")}\n          </Button>\n        </Link>\n      </div>\n      <CodeEditor\n        scopeOfAutoComplete=\"page\"\n        className={className}\n        value={finalValue}\n        onChange={onChange}\n        showLineNumbers={false}\n        placeholder={placeholder}\n        expectValueType={VALIDATION_TYPES.STRING}\n        lang={CODE_LANG.JAVASCRIPT}\n        maxHeight=\"208px\"\n        minHeight=\"120px\"\n        maxWidth=\"100%\"\n        codeType={CODE_TYPE.FUNCTION}\n        modalTitle={labelName}\n        canShowCompleteInfo\n        modalDescription={detailedDescription ?? labelDesc}\n        onFocus={onFocus}\n        onBlur={onBlur}\n      />\n    </div>\n  )\n}\n\nScriptInput.displayName = \"BaseInput\"\nexport default ScriptInput\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/ScriptInput/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const applyInputSetterWrapperStyle = css`\n  width: 100%;\n  padding: 8px 0;\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n`\n\nexport const docComponentContainerStyle = css`\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface BaseInputSetterProps extends BaseSetter {\n  placeholder?: string\n  expectedType?: VALIDATION_TYPES\n  value?: string\n  wrappedCodeFunc?: (code: string) => string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const setterContainerStyle = css`\n  padding: 8px 16px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/InputSetter/util.ts",
    "content": "import { JSToString, stringToJS } from \"@/utils/evaluateDynamicString/utils\"\n\nexport const realInputValueWithList = (\n  attrValue: string | undefined,\n  widgetDisplayName: string,\n) => {\n  if (attrValue === \"\" || attrValue == undefined) return \"\"\n  let value = attrValue\n  if (\n    attrValue.includes(\n      `{{${widgetDisplayName}.dataSources.map((currentItem) => (`,\n    )\n  ) {\n    value = `${attrValue.substring(\n      `{{${widgetDisplayName}.dataSources.map((currentItem) => (`.length,\n      attrValue.length - 4,\n    )}`\n    return JSToString(value)\n  }\n  return value\n}\n\nexport const getNeedComputedValueWithList = (\n  value: string,\n  widgetDisplayName: string,\n) => {\n  const stringToCanEvaluate = stringToJS(value)\n  if (stringToCanEvaluate === \"\") {\n    return stringToCanEvaluate\n  }\n  return `{{${widgetDisplayName}.dataSources.map((currentItem) => (${stringToCanEvaluate}))}}`\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ItemBorderSetter/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { MinusIcon, PlusIcon, getColor } from \"@illa-design/react\"\nimport BorderIcon from \"@/assets/border.svg?react\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { searchDSLByDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport ColorPickerSetter from \"../ColorPickerSetter\"\nimport MeasureCheckInput from \"../InputSetter/MeasureCheckInput\"\nimport { BaseInputSetterProps } from \"../InputSetter/interface\"\nimport { containerStyle, headerContainerStyle } from \"./style\"\n\nconst ItemBorderSetter: FC<BaseInputSetterProps> = (props) => {\n  const { handleUpdateMultiAttrDSL, widgetDisplayName } = props\n\n  const currentWidget = searchDSLByDisplayName(widgetDisplayName)\n\n  const borderWidth = currentWidget?.props?.itemBorderWidth\n  const borderColor = currentWidget?.props?.itemBorderColor\n\n  const hasBorder = !!borderWidth && !!borderColor\n\n  const { t } = useTranslation()\n\n  const handleClickAddBorder = () => {\n    handleUpdateMultiAttrDSL?.({\n      itemBorderWidth: \"1px\",\n      itemBorderColor: getColor(\"white\", \"01\"),\n    })\n  }\n\n  const handleClickDeleteBorder = () => {\n    handleUpdateMultiAttrDSL?.({\n      itemBorderWidth: undefined,\n      itemBorderColor: undefined,\n    })\n  }\n\n  return (\n    <div css={containerStyle}>\n      <div css={headerContainerStyle}>\n        <PanelLabel labelName={t(\"editor.inspect.setter_label.border\")} />\n        {hasBorder ? (\n          <IconHotSpot onClick={handleClickDeleteBorder}>\n            <MinusIcon />\n          </IconHotSpot>\n        ) : (\n          <IconHotSpot onClick={handleClickAddBorder}>\n            <PlusIcon />\n          </IconHotSpot>\n        )}\n      </div>\n      {hasBorder && (\n        <>\n          <ColorPickerSetter\n            labelName={t(\"editor.inspect.setter_group.color\")}\n            value={borderColor}\n            attrName=\"itemBorderColor\"\n            handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n          />\n          <MeasureCheckInput\n            labelName={t(\"editor.inspect.setter_label.border_width\")}\n            value={borderWidth}\n            attrName=\"itemBorderWidth\"\n            handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n            icon={<BorderIcon />}\n          />\n        </>\n      )}\n    </div>\n  )\n}\n\nexport default ItemBorderSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ItemBorderSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  padding: 0px 16px;\n  width: 100%;\n`\n\nexport const headerContainerStyle = css`\n  display: flex;\n  width: 100%;\n  justify-content: space-between;\n  align-items: center;\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ListGapSetter/index.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { InputNumber } from \"@illa-design/react\"\nimport GapXIcon from \"@/assets/rightPagePanel/gridList/gap-x.svg?react\"\nimport GapYIcon from \"@/assets/rightPagePanel/gridList/gap-y.svg?react\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { BaseInputSetterProps } from \"../InputSetter/interface\"\nimport { containerStyle, gapContainerStyle } from \"./style\"\n\nconst ListGapSetter: FC<BaseInputSetterProps> = (props) => {\n  const {\n    handleUpdateDsl,\n    widgetType,\n    attrName,\n    defaultValue,\n    componentNode,\n    value,\n  } = props\n\n  const isGridGap = widgetType === \"GRID_LIST_WIDGET\"\n\n  const { gapX, gapY } = useMemo(() => {\n    const gapX = get(componentNode, `props.${attrName}X`, defaultValue)\n    const gapY = get(componentNode, `props.${attrName}Y`, defaultValue)\n    return {\n      gapX,\n      gapY,\n    }\n  }, [attrName, componentNode, defaultValue])\n\n  const { t } = useTranslation()\n\n  const handleOnChange = (attr: string, v: number | undefined) => {\n    if (v !== undefined) {\n      handleUpdateDsl(attr, v)\n    }\n  }\n\n  return (\n    <div css={containerStyle(isGridGap)}>\n      <span>\n        <PanelLabel\n          labelName={t(\"editor.inspect.setter_label.grid_list.item_spacing\")}\n          labelDesc={t(\"editor.inspect.setter_tips.grid_list.item_spacing\")}\n        />\n      </span>\n      {isGridGap ? (\n        <div css={gapContainerStyle}>\n          <InputNumber\n            colorScheme=\"techPurple\"\n            value={parseInt(gapX ?? \"0\")}\n            w=\"100%\"\n            prefix={<GapXIcon />}\n            onChange={(v) => handleOnChange(`${attrName}X`, v)}\n          />\n          <InputNumber\n            colorScheme=\"techPurple\"\n            value={parseInt(gapY ?? \"0\")}\n            w=\"100%\"\n            prefix={<GapYIcon />}\n            onChange={(v) => handleOnChange(`${attrName}Y`, v)}\n          />\n        </div>\n      ) : (\n        <InputNumber\n          colorScheme=\"techPurple\"\n          w=\"184px\"\n          value={parseInt(value ?? \"0\")}\n          prefix={<GapYIcon />}\n          onChange={(v) => handleOnChange(attrName, v)}\n        />\n      )}\n    </div>\n  )\n}\n\nexport default ListGapSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/ListGapSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = (isGridList: boolean = false) => {\n  const basicStyle = css`\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n  `\n  const singleRowStyle = css`\n    flex-direction: column;\n    gap: 8px;\n  `\n  return css`\n    display: flex;\n    padding: 8px 0;\n    ${isGridList ? singleRowStyle : basicStyle};\n    width: 100%;\n  `\n}\n\nexport const gapContainerStyle = css`\n  display: flex;\n  width: 100%;\n  gap: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/MappedOptionSetter/index.tsx",
    "content": "import { FC } from \"react\"\nimport RenderFieldAndLabel from \"@/page/App/components/InspectPanel/components/FieldAndLabel\"\nimport { MappedOptionSetterProps } from \"./interface\"\nimport { listStyle, listWrapperStyle, optionListHeaderStyle } from \"./style\"\n\nconst MappedOptionSetter: FC<MappedOptionSetterProps> = (props) => {\n  const { attrName, labelName, childrenSetter, widgetDisplayName } = props\n\n  return (\n    <div css={listStyle}>\n      <div css={optionListHeaderStyle}>\n        <div>{labelName}</div>\n      </div>\n      <div css={listWrapperStyle}>\n        {childrenSetter?.map((child) => {\n          const { id } = child\n\n          return (\n            <RenderFieldAndLabel\n              key={`${id}-${widgetDisplayName}`}\n              config={child}\n              displayName={widgetDisplayName ?? \"\"}\n              parentAttrName={attrName}\n            />\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n\nMappedOptionSetter.displayName = \"MappedOptionSetter\"\nexport default MappedOptionSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/MappedOptionSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelLabelProps } from \"@/page/App/components/InspectPanel/components/Label/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface MappedOptionSetterProps extends BaseSetter, PanelLabelProps {\n  childrenSetter?: PanelFieldConfig[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/MappedOptionSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const optionListHeaderStyle = css`\n  width: 100%;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  height: 40px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  font-weight: 500;\n  box-sizing: border-box;\n  padding: 0 16px;\n`\n\nexport const listStyle = css`\n  border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  margin: 8px 16px;\n  border-radius: 8px;\n`\n\nexport const listWrapperStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  box-sizing: border-box;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/index.tsx",
    "content": "import {\n  DndContext,\n  KeyboardSensor,\n  PointerSensor,\n  closestCenter,\n  useSensor,\n  useSensors,\n} from \"@dnd-kit/core\"\nimport {\n  restrictToVerticalAxis,\n  restrictToWindowEdges,\n} from \"@dnd-kit/modifiers\"\nimport {\n  SortableContext,\n  arrayMove,\n  sortableKeyboardCoordinates,\n  verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\"\nimport { get, isString } from \"lodash-es\"\nimport { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { v4 } from \"uuid\"\nimport { MenuItemProps, MenuItemType, SubMenuProps } from \"@illa-design/react\"\nimport { SetterMenuItem } from \"@/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/setterMenuItem\"\nimport { SetterSubMenu } from \"@/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/setterSubMenu\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { ColumnContainer } from \"../../DragMoveComponent/ColumnContainer\"\nimport { MenuOptionSetterProps } from \"./interface\"\n\nfunction getDifferentLabelFromValue(\n  values: MenuItemType[],\n  prefix: string,\n): string {\n  let label = `${prefix}${values.length}`\n  let plus = 0\n  while (values.find((item) => item.label === label)) {\n    plus++\n    label = `${prefix}${values.length + plus}`\n  }\n  return label\n}\n\nfunction getDifferentValueFromValue(\n  values: MenuItemType[],\n  prefix: string,\n  suffix: string,\n): string {\n  let value = `${prefix}${suffix}${values.length}`\n  let plus = 0\n  while (values.find((item) => item.value === value)) {\n    plus++\n    value = `${prefix}${suffix}${values.length + plus}`\n  }\n  return value\n}\n\nexport const MenuOptionSetter: FC<MenuOptionSetterProps> = (props) => {\n  const {\n    handleUpdateMultiAttrDSL,\n    attrName,\n    value,\n    childrenSetter,\n    widgetDisplayName,\n  } = props\n\n  const execResult = useSelector(getExecutionResult)\n  const executeValue = get(\n    execResult,\n    `${widgetDisplayName}.${attrName}`,\n    [],\n  ) as MenuItemType[]\n\n  const sensors = useSensors(\n    useSensor(PointerSensor),\n    useSensor(KeyboardSensor, {\n      coordinateGetter: sortableKeyboardCoordinates,\n    }),\n  )\n\n  return (\n    <ColumnContainer\n      attrName={attrName}\n      value={value}\n      handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n      items={value.map((item) => item.id!)}\n      columnNum={value.length}\n      onClickNew={() => {\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: [\n            ...value,\n            {\n              id: v4(),\n              label: getDifferentLabelFromValue(value, \"Menu \"),\n              value: getDifferentValueFromValue(value, \"\", \"menu\"),\n            },\n          ],\n        })\n      }}\n    >\n      {value.map((item, index) => (\n        <SetterSubMenu\n          id={item.id!}\n          key={item.id}\n          onDelete={() => {\n            const newValues: MenuItemProps[] = value.filter(\n              (_, i) => i !== index,\n            )\n            handleUpdateMultiAttrDSL?.({\n              [attrName]: newValues,\n            })\n          }}\n          value={item.value}\n          label={\n            isString(executeValue[index].label)\n              ? (executeValue[index].label as string)\n              : JSON.stringify(executeValue[index].label)\n          }\n          onClickAdd={() => {\n            const newValues = value.map((i) => {\n              if (i.value === item.value) {\n                if (\"subItems\" in i) {\n                  return {\n                    ...i,\n                    subItems: [\n                      ...(i.subItems ?? []),\n                      {\n                        id: v4(),\n                        label: getDifferentLabelFromValue(\n                          i.subItems!!,\n                          \"Sub Menu \",\n                        ),\n                        value: getDifferentValueFromValue(\n                          i.subItems!!,\n                          `${item.value}:`,\n                          \"subMenu\",\n                        ),\n                      },\n                    ],\n                  }\n                } else {\n                  return {\n                    ...i,\n                    subItems: [\n                      {\n                        id: v4(),\n                        label: \"Sub Menu 0\",\n                        value: `${item.value}:subMenu0`,\n                      },\n                    ],\n                  }\n                }\n              } else {\n                return i\n              }\n            })\n            handleUpdateMultiAttrDSL?.({\n              [attrName]: [...newValues],\n            })\n          }}\n          attrPath={`${attrName}.${index}`}\n          childrenSetter={childrenSetter}\n          widgetDisplayName={widgetDisplayName}\n        >\n          <DndContext\n            modifiers={[restrictToVerticalAxis, restrictToWindowEdges]}\n            sensors={sensors}\n            collisionDetection={closestCenter}\n            onDragEnd={(event) => {\n              const value = (item as SubMenuProps).subItems\n              if (value === undefined) {\n                return\n              }\n              const { active, over } = event\n              if (active && over && active.id !== over.id) {\n                const oldIndex = value.findIndex(\n                  (item) => item.id === active.id,\n                )\n                const newIndex = value.findIndex((item) => item.id === over.id)\n                const finalColumns = arrayMove(value, oldIndex, newIndex)\n                handleUpdateMultiAttrDSL?.({\n                  [`${attrName}.${index}.subItems`]: finalColumns,\n                })\n                return finalColumns\n              }\n            }}\n          >\n            <SortableContext\n              items={\n                (item as SubMenuProps).subItems?.map((child) => child.id!) ?? []\n              }\n              strategy={verticalListSortingStrategy}\n            >\n              {\"subItems\" in item &&\n                ((item as SubMenuProps).subItems?.length ?? 0) > 0 &&\n                (item as SubMenuProps).subItems?.map((child, i) => (\n                  <SetterMenuItem\n                    id={child.id!}\n                    key={child.id}\n                    onDelete={() => {\n                      const newValues: MenuItemProps[] = [...value]\n                      const newSubItems =\n                        item.subItems?.filter(\n                          (subItem, subIndex) => subIndex !== i,\n                        ) ?? []\n                      if (newSubItems.length !== 0) {\n                        newValues[index] = {\n                          ...item,\n                          subItems: newSubItems,\n                        } as SubMenuProps\n                      } else {\n                        const newItem = { ...item }\n                        delete newItem.subItems\n                        newValues[index] = newItem\n                      }\n                      handleUpdateMultiAttrDSL?.({\n                        [attrName]: newValues,\n                      })\n                    }}\n                    attrPath={`${attrName}.${index}.subItems.${i}`}\n                    childrenSetter={childrenSetter}\n                    widgetDisplayName={widgetDisplayName}\n                    label={\n                      isString(\n                        get(executeValue, `${index}.subItems.${i}.label`),\n                      )\n                        ? get(executeValue, `${index}.subItems.${i}.label`) ??\n                          \"\"\n                        : JSON.stringify(\n                            get(executeValue, `${index}.subItems.${i}.label`),\n                          )\n                    }\n                    value={child.value}\n                  />\n                ))}\n            </SortableContext>\n          </DndContext>\n        </SetterSubMenu>\n      ))}\n    </ColumnContainer>\n  )\n}\n\nMenuOptionSetter.displayName = \"MenuOptionSetter\"\nexport default MenuOptionSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/interface.ts",
    "content": "import { HTMLAttributes } from \"react\"\nimport { ButtonProps, MenuItemType } from \"@illa-design/react\"\nimport { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface MenuOptionSetterProps extends BaseSetter {\n  value: MenuItemType[]\n  childrenSetter?: PanelFieldConfig[]\n}\n\nexport interface SetterSubMenuProps extends HTMLAttributes<HTMLDivElement> {\n  id: string\n  widgetDisplayName: string\n  attrPath: string\n  value: string\n  childrenSetter?: PanelFieldConfig[]\n  label: string\n  onClickAdd: (value: string) => void\n  onDelete: () => void\n}\n\nexport interface NewButtonProps extends ButtonProps {\n  title: string\n}\n\nexport interface SetterMenuItemProps extends HTMLAttributes<HTMLDivElement> {\n  id: string\n  widgetDisplayName: string\n  attrPath: string\n  childrenSetter?: PanelFieldConfig[]\n  value: string\n  label: string\n  onDelete: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/newButton.tsx",
    "content": "import { FC } from \"react\"\nimport { AddIcon, Button } from \"@illa-design/react\"\nimport { NewButtonProps } from \"@/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/interface\"\n\nexport const NewButton: FC<NewButtonProps> = (props) => {\n  const { title, ...otherProps } = props\n\n  return (\n    <Button\n      pd={\"1px 8px\"}\n      variant={\"text\"}\n      colorScheme={\"techPurple\"}\n      leftIcon={<AddIcon size={\"14px\"} />}\n      {...otherProps}\n    >\n      {title}\n    </Button>\n  )\n}\n\nNewButton.displayName = \"NewButton\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/setterMenuItem.tsx",
    "content": "import { useSortable } from \"@dnd-kit/sortable\"\nimport { CSS } from \"@dnd-kit/utilities\"\nimport { FC, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button, DragPointIcon, Trigger, getColor } from \"@illa-design/react\"\nimport { SetterMenuItemProps } from \"@/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/interface\"\nimport {\n  deleteButtonContainer,\n  setterMenuItemContainerStyle,\n  setterSubMenuLabelStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/style\"\nimport { BaseModal } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal\"\n\nexport const SetterMenuItem: FC<SetterMenuItemProps> = (props) => {\n  const { id, label, onDelete, attrPath, childrenSetter, widgetDisplayName } =\n    props\n\n  const { attributes, listeners, setNodeRef, transform, transition } =\n    useSortable({ id })\n\n  const style = {\n    transform: CSS.Transform.toString(transform),\n    transition,\n  }\n\n  const [triggerVisible, setTriggerVisible] = useState(false)\n\n  const { t } = useTranslation()\n\n  return (\n    <div\n      css={setterMenuItemContainerStyle}\n      ref={setNodeRef}\n      style={style}\n      {...attributes}\n    >\n      <DragPointIcon\n        className=\"dragIcon\"\n        fs=\"16px\"\n        c={getColor(\"grayBlue\", \"04\")}\n        {...listeners}\n      />\n      <Trigger\n        withoutPadding\n        colorScheme=\"white\"\n        trigger=\"click\"\n        onVisibleChange={(visible) => {\n          setTriggerVisible(visible)\n        }}\n        popupVisible={triggerVisible}\n        content={\n          <BaseModal\n            title={label as string}\n            attrPath={`${attrPath}`}\n            widgetDisplayName={widgetDisplayName}\n            childrenSetter={childrenSetter}\n            handleCloseModal={() => {\n              setTriggerVisible(false)\n            }}\n            extraElement={\n              <div css={deleteButtonContainer}>\n                <Button\n                  w=\"100%\"\n                  variant=\"light\"\n                  colorScheme=\"red\"\n                  onClick={() => {\n                    onDelete()\n                  }}\n                >\n                  {t(\"editor.inspect.setter_content.menu_setter.delete\")}\n                </Button>\n              </div>\n            }\n          />\n        }\n        showArrow={false}\n        position=\"left\"\n        clickOutsideToClose\n      >\n        <span css={setterSubMenuLabelStyle}>{label}</span>\n      </Trigger>\n    </div>\n  )\n}\n\nSetterMenuItem.displayName = \"SetterMenuItem\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/setterSubMenu.tsx",
    "content": "import { useSortable } from \"@dnd-kit/sortable\"\nimport { CSS } from \"@dnd-kit/utilities\"\nimport { FC, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button, DragPointIcon, Trigger, getColor } from \"@illa-design/react\"\nimport { SetterSubMenuProps } from \"@/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/interface\"\nimport { NewButton } from \"@/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/newButton\"\nimport {\n  deleteButtonContainer,\n  setterSubMenuAllContainerStyle,\n  setterSubMenuContainerStyle,\n  setterSubMenuLabelStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/style\"\nimport { BaseModal } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal\"\n\nexport const SetterSubMenu: FC<SetterSubMenuProps> = (props) => {\n  const {\n    id,\n    label,\n    value,\n    onDelete,\n    onClickAdd,\n    children,\n    attrPath,\n    childrenSetter,\n    widgetDisplayName,\n    onClick,\n  } = props\n\n  const { t } = useTranslation()\n\n  const { attributes, listeners, setNodeRef, transform, transition } =\n    useSortable({ id })\n\n  const style = {\n    transform: CSS.Transform.toString(\n      transform\n        ? {\n            y: transform?.y ?? 0,\n            x: transform?.x ?? 0,\n            scaleX: 1,\n            scaleY: 1,\n          }\n        : null,\n    ),\n    transition,\n  }\n\n  const [triggerVisible, setTriggerVisible] = useState(false)\n\n  return (\n    <div\n      css={setterSubMenuAllContainerStyle}\n      ref={setNodeRef}\n      style={style}\n      onClick={onClick}\n      {...attributes}\n    >\n      <div css={setterSubMenuContainerStyle}>\n        <DragPointIcon\n          className=\"dragIcon\"\n          fs=\"16px\"\n          c={getColor(\"grayBlue\", \"04\")}\n          {...listeners}\n        />\n        <Trigger\n          withoutPadding\n          colorScheme=\"white\"\n          trigger=\"click\"\n          onVisibleChange={(visible) => {\n            setTriggerVisible(visible)\n          }}\n          popupVisible={triggerVisible}\n          content={\n            <BaseModal\n              title={label as string}\n              attrPath={`${attrPath}`}\n              widgetDisplayName={widgetDisplayName}\n              childrenSetter={childrenSetter}\n              handleCloseModal={() => {\n                setTriggerVisible(false)\n              }}\n              extraElement={\n                <div css={deleteButtonContainer}>\n                  <Button\n                    w=\"100%\"\n                    variant=\"light\"\n                    colorScheme=\"red\"\n                    onClick={() => {\n                      onDelete()\n                    }}\n                  >\n                    {t(\"editor.inspect.setter_content.menu_setter.delete\")}\n                  </Button>\n                </div>\n              }\n            />\n          }\n          showArrow={false}\n          position=\"left\"\n          clickOutsideToClose\n        >\n          <span css={setterSubMenuLabelStyle}>{label}</span>\n        </Trigger>\n        <NewButton\n          title={t(\"editor.inspect.setter_content.menu_setter.sub\")}\n          onClick={() => {\n            onClickAdd(value)\n          }}\n        />\n      </div>\n      {children}\n    </div>\n  )\n}\n\nSetterSubMenu.displayName = \"SetterSubMenu\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const menuOptionSetterContainerStyle = css`\n  box-sizing: border-box;\n  margin: 8px 16px;\n  min-height: 264px;\n  border-radius: 8px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  overflow: hidden;\n`\n\nexport const optionListHeaderStyle = css`\n  width: 100%;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  height: 40px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-weight: 500;\n  box-sizing: border-box;\n  padding: 0 8px 0 16px;\n`\n\nexport const optionSubItemStyle = css`\n  cursor: pointer;\n  padding: 0 8px;\n  font-size: 14px;\n  height: 24px;\n  display: inline-flex;\n  color: ${getColor(\"techPurple\", \"03\")};\n  align-items: center;\n  flex-direction: row;\n`\n\nexport const setterSubMenuAllContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n`\n\nexport const setterSubMenuContainerStyle = css`\n  height: 40px;\n  width: 100%;\n  cursor: pointer;\n  display: flex;\n  padding-right: 8px;\n  flex-direction: row;\n  box-sizing: border-box;\n  align-items: center;\n  .dragIcon {\n    visibility: hidden;\n  }\n  &:hover {\n    .dragIcon {\n      visibility: visible;\n    }\n  }\n`\n\nexport const setterMenuItemContainerStyle = css`\n  height: 40px;\n  cursor: pointer;\n  width: 100%;\n  padding-left: 16px;\n  padding-right: 8px;\n  display: flex;\n  flex-direction: row;\n  box-sizing: border-box;\n  align-items: center;\n  .dragIcon {\n    visibility: hidden;\n  }\n  &:hover {\n    .dragIcon {\n      visibility: visible;\n    }\n  }\n`\n\nexport const setterSubMenuLabelStyle = css`\n  font-weight: 400;\n  width: 100%;\n  height: 100%;\n  line-height: 40px;\n  flex-grow: 1;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n`\n\nexport const setterDivStyle = css`\n  flex-grow: 1;\n`\n\nexport const removeNativeStyle = css`\n  list-style: none;\n  padding: 0;\n  margin: 0;\n`\n\nexport const deleteButtonContainer = css`\n  padding: 0 16px 16px 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/OptionListSetter/index.tsx",
    "content": "import { get, isString } from \"lodash-es\"\nimport { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { v4 } from \"uuid\"\nimport { Column } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Column\"\nimport { ColumnContainer } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/ColumnContainer\"\nimport { ColumnEmpty } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Empty\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { OptionListSetterProps } from \"./interface\"\n\nconst OptionListSetter: FC<OptionListSetterProps> = (props) => {\n  const {\n    value,\n    attrName,\n    widgetDisplayName,\n    childrenSetter,\n    handleUpdateMultiAttrDSL,\n    itemName = \"Option\",\n  } = props\n\n  const execResult = useSelector(getExecutionResult)\n  const executeValue = get(execResult, `${widgetDisplayName}.${attrName}`, [])\n\n  return (\n    <ColumnContainer\n      attrName={attrName}\n      value={value}\n      handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n      columnNum={value.length}\n      items={value.map((item) => item.id)}\n      onClickNew={() => {\n        const newItem = {\n          id: `${itemName}-${v4()}`,\n          key: `${itemName}-${v4()}`,\n          label: `${itemName} ${value.length + 1}`,\n        }\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: [...value, newItem],\n        })\n      }}\n    >\n      {value.length > 0 ? (\n        value.map((item, index) => {\n          return (\n            <Column\n              onCopy={() => {\n                const newItem = {\n                  ...value[index],\n                  id: `${itemName}-${v4()}`,\n                  key: `${itemName}-${v4()}`,\n                }\n                const updatedArray = [...value, newItem]\n                handleUpdateMultiAttrDSL?.({\n                  [attrName]: updatedArray,\n                })\n              }}\n              onDelete={(id) => {\n                const newV = value.filter((item) => item.id !== id)\n                handleUpdateMultiAttrDSL?.({\n                  [attrName]: newV,\n                })\n              }}\n              showCopy\n              showDelete\n              key={item.id}\n              id={item.id}\n              label={\n                isString(get(executeValue, `${index}.label`))\n                  ? get(executeValue, `${index}.label`)\n                  : JSON.stringify(get(executeValue, `${index}.label`))\n              }\n              widgetDisplayName={widgetDisplayName}\n              childrenSetter={childrenSetter}\n              attrPath={`${attrName}.${index}`}\n            />\n          )\n        })\n      ) : (\n        <ColumnEmpty />\n      )}\n    </ColumnContainer>\n  )\n}\n\nOptionListSetter.displayName = \"OptionListSetter\"\nexport default OptionListSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/OptionListSetter/interface.ts",
    "content": "import { PanelFieldConfig } from \"../../interface\"\nimport { BaseSetter } from \"../interface\"\n\nexport interface OptionItemShape {\n  id: string\n  value?: string\n  label?: string\n  disabled?: string\n}\n\nexport interface OptionListSetterProps extends BaseSetter {\n  value: OptionItemShape[]\n  childrenSetter?: PanelFieldConfig[]\n  headerName?: string\n  itemName?: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/DynamicIcon/index.tsx",
    "content": "import { FC } from \"react\"\nimport { FxIcon } from \"@illa-design/react\"\nimport { DynamicIconProps } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/DynamicIcon/interface\"\nimport { applyCustomIconStyle } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/DynamicIcon/style\"\n\nexport const DynamicIcon: FC<DynamicIconProps> = (props) => {\n  const { isDynamic, hasRightContent, onClick } = props\n  return (\n    <div\n      css={applyCustomIconStyle(isDynamic, hasRightContent)}\n      onClick={onClick}\n    >\n      <FxIcon />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/DynamicIcon/interface.ts",
    "content": "export interface DynamicIconProps {\n  isDynamic: boolean\n  onClick: () => void\n  hasRightContent: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/DynamicIcon/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const applyCustomIconStyle = (\n  isDynamic: boolean = false,\n  hasRightContent: boolean = false,\n): SerializedStyles => {\n  return css`\n    color: ${isDynamic\n      ? getColor(\"techPurple\", \"03\")\n      : getColor(\"grayBlue\", \"06\")};\n    width: 16px;\n    height: 16px;\n    font-size: 16px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    margin-right: ${hasRightContent ? \"10px\" : 0};\n\n    :hover {\n      cursor: pointer;\n      color: ${getColor(\"techPurple\", \"03\")};\n    }\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/Label/addActionLabel.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { AddIcon, Button, globalColor, illaPrefix } from \"@illa-design/react\"\nimport { AddActionLabelProps } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Label/interface\"\nimport { headerWrapperStyle } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Label/style\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\n\nexport const AddActionLabel: FC<AddActionLabelProps> = (props) => {\n  const { labelName, labelDesc, handleAddItem } = props\n  const { t } = useTranslation()\n\n  return (\n    <div css={headerWrapperStyle}>\n      <PanelLabel labelName={labelName} labelDesc={labelDesc} />\n      <Button\n        pd=\"1px 8px\"\n        colorScheme=\"techPurple\"\n        size=\"small\"\n        variant=\"text\"\n        onClick={handleAddItem}\n        leftIcon={\n          <AddIcon color={globalColor(`--${illaPrefix}-techPurple-03`)} />\n        }\n      >\n        {t(\"editor.inspect.setter_content.event_handler_list.new\")}\n      </Button>\n    </div>\n  )\n}\n\nAddActionLabel.displayName = \"AddActionLabel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/Label/interface.ts",
    "content": "import { PanelLabelProps } from \"@/page/App/components/InspectPanel/components/Label/interface\"\n\nexport interface AddActionLabelProps\n  extends Pick<PanelLabelProps, \"labelName\" | \"labelDesc\"> {\n  handleAddItem: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/Label/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const headerWrapperStyle = css`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal/baseBody.tsx",
    "content": "import { FC } from \"react\"\nimport { BaseBodyProps } from \"./interface\"\nimport { listWrapperStyle } from \"./style\"\n\nexport const BaseModalBody: FC<BaseBodyProps> = (props) => {\n  const { children } = props\n\n  return <div css={listWrapperStyle}>{children}</div>\n}\n\nBaseModalBody.displayName = \"ModalBody\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal/body.tsx",
    "content": "import { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport RenderFieldAndLabel from \"@/page/App/components/InspectPanel/components/FieldAndLabel\"\nimport { getGuideInfo } from \"@/redux/guide/guideSelector\"\nimport { BodyProps } from \"./interface\"\nimport { listWrapperStyle } from \"./style\"\n\nexport const ModalBody: FC<BodyProps> = (props) => {\n  const { childrenSetter, widgetDisplayName, attrPath } = props\n  const guideInfo = useSelector(getGuideInfo)\n\n  return (\n    <div css={listWrapperStyle}>\n      {childrenSetter?.map((child) => {\n        const { id } = child\n        return (\n          <RenderFieldAndLabel\n            key={`${id}-${widgetDisplayName}`}\n            config={child}\n            displayName={widgetDisplayName ?? \"\"}\n            parentAttrName={attrPath}\n            guideInfo={guideInfo}\n          />\n        )\n      })}\n    </div>\n  )\n}\n\nModalBody.displayName = \"ModalBody\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal/header.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC } from \"react\"\nimport { Link } from \"react-router-dom\"\nimport { CloseIcon, DocsIcon } from \"@illa-design/react\"\nimport { HeaderProps } from \"./interface\"\nimport {\n  closeIconStyle,\n  headerStyle,\n  modalHeaderText,\n  titleContainerStyle,\n} from \"./style\"\n\nexport const ModalHeader: FC<HeaderProps> = (props) => {\n  const { title, handleCloseModal, docLink } = props\n\n  return (\n    <div css={headerStyle}>\n      <div css={titleContainerStyle}>\n        <div css={modalHeaderText}>{title}</div>\n        {docLink && (\n          <Link to={docLink} target=\"_blank\">\n            <IconHotSpot>\n              <DocsIcon />\n            </IconHotSpot>\n          </Link>\n        )}\n      </div>\n      <div css={closeIconStyle} onClick={handleCloseModal}>\n        <CloseIcon />\n      </div>\n    </div>\n  )\n}\nModalHeader.displayName = \"ModalHeader\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal/index.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport { FC, Suspense, useMemo } from \"react\"\nimport { ModalBody } from \"./body\"\nimport { ModalHeader } from \"./header\"\nimport { ModalProps } from \"./interface\"\nimport { modalWrapperStyle } from \"./style\"\n\nexport const BaseModal: FC<ModalProps> = (props) => {\n  const {\n    title,\n    handleCloseModal,\n    childrenSetter,\n    widgetDisplayName,\n    attrPath,\n    children,\n    _css,\n    header,\n    extraElement,\n    docLink,\n  } = props\n\n  const renderBody = useMemo(() => {\n    if (!childrenSetter || !widgetDisplayName || !attrPath) {\n      return children\n    }\n    return (\n      <ModalBody\n        childrenSetter={childrenSetter}\n        widgetDisplayName={widgetDisplayName}\n        attrPath={attrPath}\n      />\n    )\n  }, [childrenSetter, widgetDisplayName, attrPath, children])\n\n  return (\n    <div css={css(modalWrapperStyle, _css)}>\n      {header ?? (\n        <ModalHeader\n          title={title}\n          handleCloseModal={handleCloseModal}\n          docLink={docLink}\n        />\n      )}\n      <Suspense>{renderBody}</Suspense>\n      {extraElement}\n    </div>\n  )\n}\nBaseModal.displayName = \"BaseModal\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal/interface.ts",
    "content": "import { SerializedStyles } from \"@emotion/react\"\nimport { ReactNode } from \"react\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface HeaderProps {\n  title: string\n  handleCloseModal: () => void\n  docLink?: string\n}\n\nexport interface BaseBodyProps {\n  children: ReactNode\n}\n\nexport interface BodyProps {\n  childrenSetter: PanelFieldConfig[]\n  widgetDisplayName: string\n  attrPath: string\n}\n\nexport interface ModalProps extends HeaderProps {\n  childrenSetter?: PanelFieldConfig[]\n  widgetDisplayName?: string\n  attrPath?: string\n  children?: ReactNode\n  _css?: SerializedStyles\n  header?: ReactNode\n  extraElement?: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const headerStyle = css`\n  width: 100%;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  height: 48px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  font-size: 16px;\n  padding: 0 16px;\n  font-weight: 500;\n\n  span {\n    display: flex;\n    align-items: center;\n  }\n`\n\nexport const titleContainerStyle = css`\n  flex-grow: 1;\n  margin-right: 8px;\n  display: flex;\n  align-items: center;\n  gap: 4px;\n`\n\nexport const modalHeaderText = css`\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n`\n\nexport const closeIconStyle = css`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 14px;\n  height: 14px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  cursor: pointer;\n`\n\nexport const modalWrapperStyle = css`\n  width: 400px;\n`\nexport const listWrapperStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  box-sizing: border-box;\n  padding-bottom: 12px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/RadioGroupSetter/baseRadioGroup.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC } from \"react\"\nimport { RadioGroup } from \"@illa-design/react\"\nimport {\n  applyRadioGroupWrapperStyle,\n  baseRadioGroupContainerStyle,\n  radioGroupStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/RadioGroupSetter/style\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { BaseRadioGroupProps } from \"./interface\"\n\nconst BaseRadioGroupSetter: FC<BaseRadioGroupProps> = (props) => {\n  const {\n    value,\n    options,\n    defaultValue,\n    isSetterSingleRow = false,\n    attrName,\n    widgetType,\n    labelName,\n    labelDesc,\n    handleUpdateDsl,\n  } = props\n\n  return (\n    <div css={baseRadioGroupContainerStyle(isSetterSingleRow)}>\n      {labelName && (\n        <span>\n          <PanelLabel\n            labelName={labelName}\n            labelDesc={labelDesc}\n            labelSize=\"medium\"\n          />\n        </span>\n      )}\n      <div css={applyRadioGroupWrapperStyle(isSetterSingleRow)}>\n        <RadioGroup\n          onChange={(value) => {\n            handleUpdateDsl(attrName, value)\n            trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n              element: \"component_inspect_radio\",\n              parameter1: widgetType,\n              parameter2: attrName,\n            })\n          }}\n          forceEqualWidth={true}\n          value={value}\n          defaultValue={defaultValue}\n          options={options}\n          type=\"button\"\n          size=\"medium\"\n          colorScheme=\"grayBlue\"\n          css={radioGroupStyle}\n        />\n      </div>\n    </div>\n  )\n}\n\nBaseRadioGroupSetter.displayName = \"BaseRadioGroupSetter\"\n\nexport default BaseRadioGroupSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/RadioGroupSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\n\nexport interface BaseRadioGroupProps extends BaseSetter {\n  options?: any\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/RadioGroupSetter/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { fixedWidthStyle } from \"@/page/App/components/InspectPanel/PanelSetters/style\"\n\nexport const applyRadioGroupWrapperStyle = (\n  isSetterSingleRow: boolean = false,\n): SerializedStyles => {\n  return isSetterSingleRow\n    ? css`\n        width: 100%;\n      `\n    : fixedWidthStyle\n}\n\nexport const radioGroupStyle = css`\n  width: 100%;\n`\n\nexport const baseRadioGroupContainerStyle = (\n  isSetterSingleRow: boolean = false,\n) => {\n  const basicStyle = css`\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n  `\n  const singleRowStyle = css`\n    flex-direction: column;\n    gap: 8px;\n  `\n  return css`\n    display: flex;\n    padding: 8px 0;\n    ${isSetterSingleRow ? singleRowStyle : basicStyle};\n    width: 100%;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/CustomBgSelect/index.tsx",
    "content": "import { FC, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Select, SelectValue } from \"@illa-design/react\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport ColorPickerSetter from \"../../ColorPickerSetter\"\nimport { ShadowSelectProps } from \"./interface\"\nimport { containerStyle, setterContainerStyle } from \"./style\"\n\nenum CUSTOM_BG_SELECT_OPTIONS {\n  AUTO = \"auto\",\n  CUSTOM = \"custom\",\n}\n\nconst CustomBgSelect: FC<ShadowSelectProps> = (props) => {\n  const {\n    attrName,\n    handleUpdateMultiAttrDSL,\n    value,\n    labelName,\n    useCustomLayout,\n  } = props\n\n  const { t } = useTranslation()\n\n  const options = [\n    {\n      label: t(\"editor.inspect.setter_group.custom_bg.options.auto\"),\n      value: CUSTOM_BG_SELECT_OPTIONS.AUTO,\n    },\n    {\n      label: t(\"editor.inspect.setter_group.custom_bg.options.custom\"),\n      value: CUSTOM_BG_SELECT_OPTIONS.CUSTOM,\n    },\n  ]\n\n  const [selectValue, setSelectValue] = useState<SelectValue | undefined>(\n    value ? CUSTOM_BG_SELECT_OPTIONS.CUSTOM : CUSTOM_BG_SELECT_OPTIONS.AUTO,\n  )\n\n  const handleUpdateSelectState = (value: SelectValue | undefined) => {\n    setSelectValue(value)\n    if (value === CUSTOM_BG_SELECT_OPTIONS.AUTO) {\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: undefined,\n      })\n    }\n  }\n\n  return (\n    <div css={containerStyle}>\n      <div css={setterContainerStyle}>\n        <PanelLabel\n          labelName={labelName}\n          labelSize={useCustomLayout ? \"small\" : \"medium\"}\n        />\n        <Select\n          onChange={handleUpdateSelectState}\n          value={selectValue}\n          dropdownProps={{\n            position: \"top\",\n          }}\n          w={useCustomLayout ? \"170px\" : \"182px\"}\n          colorScheme=\"techPurple\"\n          options={options}\n        />\n      </div>\n      {selectValue === \"custom\" && (\n        <ColorPickerSetter\n          labelName={t(\"editor.inspect.setter_group.color\")}\n          labelSize={useCustomLayout ? \"small\" : \"medium\"}\n          value={value}\n          defaultValue=\"blue\"\n          attrName={attrName}\n          handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n        />\n      )}\n    </div>\n  )\n}\n\nCustomBgSelect.displayName = \"CustomBgSelect\"\n\nexport default CustomBgSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/CustomBgSelect/interface.ts",
    "content": "import { BaseSetter } from \"../../interface\"\n\nexport interface ShadowSelectProps extends BaseSetter {\n  handleUpdateMultiAttrDSL?: (updateSlice: Record<string, any>) => void\n  value: string\n  useCustomLayout?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/CustomBgSelect/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  width: 100%;\n  overflow: hidden;\n`\n\nexport const setterContainerStyle = css`\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 8px 0;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/MeasureSelectSetter/index.tsx",
    "content": "import { isString } from \"lodash-es\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Select } from \"@illa-design/react\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { MeasureSelectSetterProps } from \"./interface\"\nimport { containerStyle, setterContainerStyle } from \"./style\"\n\nconst MeasureSelectSetter: FC<MeasureSelectSetterProps> = (props) => {\n  const {\n    attrName,\n    handleUpdateMultiAttrDSL,\n    value,\n    defaultValue,\n    labelName,\n    useCustomLayout,\n    options,\n  } = props\n\n  const { t } = useTranslation()\n\n  return (\n    <div css={containerStyle}>\n      <div css={setterContainerStyle}>\n        <PanelLabel\n          labelName={labelName}\n          labelSize={useCustomLayout ? \"small\" : \"medium\"}\n        />\n        <Select\n          defaultValue={defaultValue}\n          onChange={(value) => {\n            handleUpdateMultiAttrDSL?.({\n              [attrName]: value,\n            })\n          }}\n          value={value}\n          dropdownProps={{\n            position: \"top\",\n          }}\n          w={useCustomLayout ? \"170px\" : \"182px\"}\n          colorScheme=\"techPurple\"\n          options={options?.map((i) => {\n            return {\n              label: isString(i.label) ? t(i.label) : i.value,\n              value: i.value,\n            }\n          })}\n        />\n      </div>\n    </div>\n  )\n}\n\nMeasureSelectSetter.displayName = \"CustomBgSelect\"\n\nexport default MeasureSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/MeasureSelectSetter/interface.ts",
    "content": "import { SelectOptionObject, SelectValue } from \"@illa-design/react\"\nimport { BaseSetter } from \"../../interface\"\n\nexport interface MeasureSelectSetterProps extends BaseSetter {\n  handleUpdateMultiAttrDSL?: (updateSlice: Record<string, any>) => void\n  value: SelectValue\n  defaultValue?: SelectValue\n  useCustomLayout?: boolean\n  options?: SelectOptionObject[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/MeasureSelectSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  width: 100%;\n  overflow: hidden;\n`\n\nexport const setterContainerStyle = css`\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 8px 0;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/ShadowSelect/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Select, SelectValue } from \"@illa-design/react\"\nimport ShadowIcon from \"@/assets/shadow-icon.svg?react\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ShadowSelectProps } from \"./interface\"\nimport { setterContainerStyle } from \"./style\"\n\nconst ShadowSelect: FC<ShadowSelectProps> = (props) => {\n  const { attrName, handleUpdateMultiAttrDSL, value, widgetType, labelName } =\n    props\n\n  const { t } = useTranslation()\n\n  const options = [\n    {\n      label: t(\"editor.inspect.setter_option.shadow.none\"),\n      value: \"none\",\n    },\n    {\n      label: t(\"editor.inspect.setter_option.shadow.large\"),\n      value: \"large\",\n    },\n    {\n      label: t(\"editor.inspect.setter_option.shadow.medium\"),\n      value: \"medium\",\n    },\n    {\n      label: t(\"editor.inspect.setter_option.shadow.small\"),\n      value: \"small\",\n    },\n  ]\n\n  const handleUpdateShadow = (value: SelectValue | undefined) => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CHANGE, {\n      element: \"component_inspect_select\",\n      parameter1: widgetType,\n      parameter2: attrName,\n      parameter3: value,\n    })\n    handleUpdateMultiAttrDSL?.({\n      [attrName]: value,\n    })\n  }\n\n  return (\n    <div css={setterContainerStyle}>\n      <PanelLabel labelName={labelName} labelSize=\"small\" />\n      <Select\n        onChange={handleUpdateShadow}\n        value={value}\n        prefix={<ShadowIcon />}\n        w=\"170px\"\n        colorScheme=\"techPurple\"\n        options={options}\n      />\n    </div>\n  )\n}\n\nShadowSelect.displayName = \"ShadowSelect\"\n\nexport default ShadowSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/ShadowSelect/interface.ts",
    "content": "export interface ShadowSelectProps {\n  attrName: string\n  handleUpdateMultiAttrDSL?: (updateSlice: Record<string, any>) => void\n  labelName?: string\n  value: string\n  widgetType: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/ShadowSelect/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const setterContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 8px 0;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/baseDynamicSelect.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, useCallback } from \"react\"\nimport { Select } from \"@illa-design/react\"\nimport { CodeEditor } from \"@/components/CodeEditor\"\nimport {\n  CODE_LANG,\n  CODE_TYPE,\n} from \"@/components/CodeEditor/CodeMirror/extensions/interface\"\nimport { DynamicIcon } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/DynamicIcon\"\nimport { BaseDynamicSelectSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/interface\"\nimport {\n  basicDynamicSetterContainerStyle,\n  dynamicSelectHeaderStyle,\n  dynamicSelectSetterStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/style\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\n\nconst BaseDynamicSelect: FC<BaseDynamicSelectSetterProps> = (props) => {\n  const {\n    labelName,\n    labelDesc,\n    isDynamic,\n    onClickFxButton,\n    value,\n    onChangeInput,\n    onChangeSelect,\n    expectedType,\n    options,\n    selectPlaceholder,\n    inputPlaceholder,\n    isError,\n    widgetType,\n    attrName,\n    detailedDescription,\n  } = props\n\n  const handleClickFxButton = useCallback(() => {\n    if (isDynamic) {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"fx\",\n        parameter1: widgetType,\n        parameter2: attrName,\n        parameter3: \"off\",\n      })\n    } else {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"fx\",\n        parameter1: widgetType,\n        parameter2: attrName,\n        parameter3: \"on\",\n      })\n    }\n    onClickFxButton?.()\n  }, [attrName, isDynamic, onClickFxButton, widgetType])\n\n  const onChangeSelectInner = useCallback(\n    (value: any) => {\n      onChangeSelect(value)\n    },\n    [onChangeSelect],\n  )\n\n  return (\n    <div css={basicDynamicSetterContainerStyle}>\n      <div css={dynamicSelectHeaderStyle}>\n        <PanelLabel labelName={labelName} labelDesc={labelDesc} />\n        <DynamicIcon\n          isDynamic={isDynamic}\n          onClick={handleClickFxButton}\n          hasRightContent={false}\n        />\n      </div>\n      <div css={dynamicSelectSetterStyle}>\n        {isDynamic ? (\n          <CodeEditor\n            value={value ?? \"\"}\n            onChange={onChangeInput}\n            showLineNumbers={false}\n            placeholder={inputPlaceholder}\n            expectValueType={expectedType}\n            lang={CODE_LANG.JAVASCRIPT}\n            maxHeight=\"208px\"\n            minHeight=\"30px\"\n            maxWidth=\"100%\"\n            codeType={CODE_TYPE.EXPRESSION}\n            modalTitle={labelName}\n            modalDescription={labelDesc ?? detailedDescription}\n            scopeOfAutoComplete=\"page\"\n          />\n        ) : (\n          <Select\n            colorScheme=\"techPurple\"\n            placeholder={selectPlaceholder}\n            options={options}\n            value={value}\n            onChange={onChangeSelectInner}\n            showSearch\n            allowClear\n            error={isError}\n          />\n        )}\n      </div>\n    </div>\n  )\n}\n\nBaseDynamicSelect.displayName = \"BaseDynamicSelect\"\n\nexport default BaseDynamicSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/baseSelect.tsx",
    "content": "import { FC } from \"react\"\nimport { Select } from \"@illa-design/react\"\nimport {\n  applyBaseSelectWrapperStyle,\n  setterContainerStyle,\n} from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/style\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { BaseSelectSetterProps } from \"./interface\"\n\nconst BaseSelectSetter: FC<BaseSelectSetterProps> = (props) => {\n  const {\n    isSetterSingleRow,\n    options,\n    attrName,\n    handleUpdateDsl,\n    value,\n    allowClear,\n    defaultValue,\n    onChange,\n    showSearch,\n    labelName,\n    labelDesc,\n    labelSize,\n  } = props\n\n  return (\n    <div css={setterContainerStyle(isSetterSingleRow)}>\n      <span>\n        {labelName && (\n          <PanelLabel\n            labelName={labelName}\n            labelDesc={labelDesc}\n            labelSize={labelSize}\n          />\n        )}\n      </span>\n      <div css={applyBaseSelectWrapperStyle(isSetterSingleRow)}>\n        <Select\n          options={options}\n          size=\"medium\"\n          defaultValue={defaultValue}\n          value={value}\n          colorScheme=\"techPurple\"\n          onChange={(value) => {\n            handleUpdateDsl(attrName, value)\n            onChange?.(value)\n          }}\n          allowClear={allowClear}\n          showSearch={showSearch}\n        />\n      </div>\n    </div>\n  )\n}\n\nBaseSelectSetter.displayName = \"BaseSelect\"\n\nexport default BaseSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/dataSourceSelectSetter.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { ChartDataSourceSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/interface\"\nimport BaseDynamicSelect from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/baseDynamicSelect\"\nimport { publicPaddingStyle } from \"@/page/App/components/InspectPanel/style\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport { searchDSLByDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport { getExecutionError } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst DataSourceSetter: FC<ChartDataSourceSetterProps> = (props) => {\n  const { handleUpdateDsl, widgetDisplayName, labelName, labelDesc } = props\n  const actions = useSelector(getActionList)\n  const executionErrors = useSelector(getExecutionError)\n  const isError = useMemo(() => {\n    return (\n      (executionErrors[`${widgetDisplayName}.dataSource`] ?? [])?.length > 0\n    )\n  }, [executionErrors, widgetDisplayName])\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      return searchDSLByDisplayName(widgetDisplayName, rootState)?.props || {}\n    },\n  )\n\n  const isDynamic = useMemo(() => {\n    const dataSourceMode = get(targetComponentProps, \"dataSourceMode\", \"select\")\n    return dataSourceMode === \"dynamic\"\n  }, [targetComponentProps])\n\n  const finalValue = useMemo(() => {\n    if (isDynamic) {\n      return get(targetComponentProps, \"dataSourceJS\")\n    } else {\n      return get(targetComponentProps, \"dataSource\")\n    }\n  }, [isDynamic, targetComponentProps])\n\n  const selectedOptions = useMemo(() => {\n    return actions.map((action) => ({\n      label: action.displayName,\n      value: `{{${action.displayName}.data}}`,\n    }))\n  }, [actions])\n\n  const handleClickFxButton = useCallback(() => {\n    const isInOption = selectedOptions.some(\n      (option) => option.value === finalValue,\n    )\n    if (isDynamic) {\n      handleUpdateDsl(\"dataSourceMode\", \"select\")\n      if (!isInOption) {\n        handleUpdateDsl(\"dataSource\", \"\")\n      } else {\n        handleUpdateDsl(\"dataSource\", finalValue)\n      }\n    } else {\n      handleUpdateDsl(\"dataSourceMode\", \"dynamic\")\n      if (isInOption) {\n        handleUpdateDsl(\"dataSourceJS\", finalValue)\n      }\n    }\n  }, [handleUpdateDsl, isDynamic, selectedOptions, finalValue])\n\n  const handleChangeInput = useCallback(\n    (value: string) => {\n      handleUpdateDsl(\"dataSourceJS\", value)\n    },\n    [handleUpdateDsl],\n  )\n\n  const handleChangeSelect = useCallback(\n    (value: any) => {\n      handleUpdateDsl(\"dataSource\", value)\n    },\n    [handleUpdateDsl],\n  )\n\n  return (\n    <div css={publicPaddingStyle}>\n      <BaseDynamicSelect\n        {...props}\n        isDynamic={isDynamic}\n        onClickFxButton={handleClickFxButton}\n        selectPlaceholder=\"Select a query or transformer\"\n        inputPlaceholder=\"{{}}\"\n        onChangeInput={handleChangeInput}\n        path={`${widgetDisplayName}.dataSourceJS`}\n        options={selectedOptions}\n        expectedType={VALIDATION_TYPES.ARRAY}\n        onChangeSelect={handleChangeSelect}\n        value={finalValue}\n        labelName={labelName}\n        labelDesc={labelDesc}\n        isError={isError}\n      />\n    </div>\n  )\n}\n\nDataSourceSetter.displayName = \"DataSourceSetter\"\nexport default DataSourceSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/dynamicSelectSetter.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport BaseDynamicSelect from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/baseDynamicSelect\"\nimport { publicPaddingStyle } from \"@/page/App/components/InspectPanel/style\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { getExecutionError } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { BaseSelectSetterProps } from \"./interface\"\n\nconst DynamicSelectSetter: FC<BaseSelectSetterProps> = (props) => {\n  const {\n    widgetDisplayName,\n    attrName,\n    value,\n    labelName,\n    labelDesc,\n    options,\n    defaultValue,\n    handleUpdateMultiAttrDSL,\n  } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const handleUpdateDsl = useCallback(\n    (attrName: string, newValue: any) => {\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: newValue,\n      })\n    },\n    [handleUpdateMultiAttrDSL],\n  )\n\n  const executionErrors = useSelector(getExecutionError)\n  const isError = useMemo(() => {\n    return (\n      (executionErrors[`${widgetDisplayName}.${attrName}JS`] ?? [])?.length > 0\n    )\n  }, [attrName, executionErrors, widgetDisplayName])\n\n  const isDynamic =\n    get(\n      targetComponentProps,\n      `${widgetDisplayName}.${attrName}JS`,\n      \"select\",\n    ) === \"dynamic\"\n\n  const handleClickFxButton = useCallback(() => {\n    if (isDynamic) {\n      handleUpdateDsl(`${widgetDisplayName}.${attrName}JS`, \"select\")\n      handleUpdateDsl(attrName, defaultValue)\n    } else {\n      handleUpdateDsl(`${widgetDisplayName}.${attrName}JS`, \"dynamic\")\n    }\n  }, [attrName, defaultValue, handleUpdateDsl, isDynamic, widgetDisplayName])\n\n  const handleChangeSelect = useCallback(\n    (value: string) => {\n      handleUpdateDsl?.(attrName, value)\n    },\n    [attrName, handleUpdateDsl],\n  )\n\n  const handleChangeInput = useCallback(\n    (value: string) => {\n      handleUpdateDsl(attrName, value)\n    },\n    [attrName, handleUpdateDsl],\n  )\n\n  return (\n    <div css={publicPaddingStyle}>\n      <BaseDynamicSelect\n        {...props}\n        isDynamic={isDynamic}\n        options={options}\n        onClickFxButton={handleClickFxButton}\n        onChangeSelect={handleChangeSelect}\n        value={value}\n        onChangeInput={handleChangeInput}\n        expectedType={VALIDATION_TYPES.STRING}\n        path={`${widgetDisplayName}.${attrName}`}\n        labelName={labelName}\n        labelDesc={labelDesc}\n        isError={isError}\n      />\n    </div>\n  )\n}\n\nDynamicSelectSetter.displayName = \"DynamicSelectSetter\"\n\nexport default DynamicSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventActionTypeSelect.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { getWidgetExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { BaseSelectSetterProps } from \"./interface\"\nimport SearchSelectSetter from \"./searchSelect\"\n\nconst EventActionTypeSelect: FC<BaseSelectSetterProps> = (props) => {\n  const {\n    attrName,\n    parentAttrName,\n    handleUpdateDsl,\n    widgetDisplayName,\n    widgetOrAction,\n  } = props\n\n  const widgetDisplayNameMapProps = useSelector(getWidgetExecutionResult)\n  const selectedAction = useSelector(getCachedAction)\n\n  const oldEvent = useMemo(() => {\n    if (widgetOrAction === \"WIDGET\") {\n      return get(\n        widgetDisplayNameMapProps,\n        `${widgetDisplayName}.${parentAttrName}`,\n        {},\n      )\n    } else {\n      return get(selectedAction, `content.${parentAttrName}`, {})\n    }\n  }, [\n    widgetOrAction,\n    widgetDisplayNameMapProps,\n    widgetDisplayName,\n    parentAttrName,\n    selectedAction,\n  ])\n\n  const _finalAttrPath = parentAttrName ? parentAttrName : attrName\n  const handleUpdateDSLInner = useCallback(\n    (attrPath: string, value: unknown) => {\n      handleUpdateDsl(attrPath, {\n        actionType: value,\n        id: oldEvent?.id,\n        eventType: oldEvent?.eventType,\n      })\n    },\n    [handleUpdateDsl, oldEvent?.eventType, oldEvent?.id],\n  )\n\n  return (\n    <SearchSelectSetter\n      {...props}\n      attrName={_finalAttrPath}\n      handleUpdateDsl={handleUpdateDSLInner}\n    />\n  )\n}\nEventActionTypeSelect.displayName = \"EventActionTypeSelect\"\nexport default EventActionTypeSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventBodyViewSelect.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { get, toPath } from \"lodash-es\"\nimport { FC, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { BaseSelectSetterProps } from \"./interface\"\nimport SearchSelectSetter from \"./searchSelect\"\n\nconst EventTargetViewSelect: FC<BaseSelectSetterProps> = (props) => {\n  const { attrName, value, componentNode, widgetOrAction, panelConfig } = props\n\n  let parentAttrNameArray = toPath(attrName)\n  parentAttrNameArray.splice(-1, 1)\n\n  const parentAttr =\n    widgetOrAction === \"WIDGET\"\n      ? get(componentNode, `props.${convertPathToString(parentAttrNameArray)}`)\n      : get(panelConfig, convertPathToString(parentAttrNameArray))\n\n  const pagePath = get(parentAttr, \"pagePath\")\n  const componentsMap = useSelector(getComponentMap)\n  const pageComponent = searchComponentFromMap(componentsMap, pagePath)\n\n  const finalOptions = useMemo(() => {\n    if (!pageComponent) return []\n    const options: { label: string; value: string }[] = []\n    const walkedConfig = new Map<string, Record<string, any>>()\n    pageComponent.childrenNode.forEach((node) => {\n      const component = searchComponentFromMap(componentsMap, node)\n      const { props } = component ?? {}\n      if (\n        props &&\n        Array.isArray(props.viewSortedKey) &&\n        Array.isArray(props.sectionViewConfigs)\n      ) {\n        props.sectionViewConfigs.forEach((config) => {\n          if (walkedConfig.get(config.path)) return\n          walkedConfig.set(config.path, config)\n          options.push({\n            label: config.path,\n            value: config.path,\n          })\n        })\n      }\n    })\n    return options\n  }, [componentsMap, pageComponent])\n\n  const finalValue = useMemo(() => {\n    const index = finalOptions.findIndex((option) => {\n      return option.value === value\n    })\n    if (index !== -1) return value\n    return undefined\n  }, [finalOptions, value])\n\n  return (\n    <SearchSelectSetter\n      {...props}\n      value={finalValue as string}\n      options={finalOptions}\n    />\n  )\n}\n\nEventTargetViewSelect.displayName = \"EventTargetViewSelect\"\n\nexport default EventTargetViewSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventCalendarSelect.tsx",
    "content": "import { FC, useMemo } from \"react\"\nimport BaseSelectSetter from \"./baseSelect\"\nimport { BaseSelectSetterProps } from \"./interface\"\n\nconst EventCalendarSelect: FC<BaseSelectSetterProps> = (props) => {\n  const { value, options, panelConfig } = props\n  const finalOptions = useMemo(() => {\n    if (panelConfig && panelConfig.showResource) {\n      return options.filter(({ _, value }: Record<string, any>) => {\n        return value !== \"month\" && value !== \"agenda\"\n      })\n    } else {\n      return options\n    }\n  }, [options, panelConfig])\n\n  const finalValue = useMemo(() => {\n    if (panelConfig && panelConfig.showResource) {\n      if (value !== \"week\" && value !== \"day\") {\n        return \"day\"\n      }\n    }\n    return value\n  }, [panelConfig, value])\n  return (\n    <BaseSelectSetter {...props} value={finalValue} options={finalOptions} />\n  )\n}\n\nEventCalendarSelect.displayName = \"EventCalendarSelect\"\n\nexport default EventCalendarSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventTargetActionSelect.tsx",
    "content": "import { FC, useContext, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { SelectedPanelContext } from \"@/page/App/components/InspectPanel/context/selectedContext\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport { BaseSelectSetterProps } from \"./interface\"\nimport SearchSelectSetter from \"./searchSelect\"\n\nconst EventTargetActionSelect: FC<BaseSelectSetterProps> = (props) => {\n  const actionList = useSelector(getActionList)\n\n  const selectedContext = useContext(SelectedPanelContext)\n  const selectedAction = useSelector(getCachedAction)\n\n  const actionOptions = useMemo(() => {\n    if (selectedContext.widgetOrAction === \"ACTION\") {\n      return actionList\n        .filter((value) => {\n          return value.displayName !== selectedAction?.displayName\n        })\n        .map((item) => item.displayName)\n    }\n    if (selectedContext.widgetOrAction === \"WIDGET\") {\n      return actionList.map((item) => {\n        return item.displayName\n      })\n    }\n    return []\n  }, [actionList, selectedAction?.displayName, selectedContext.widgetOrAction])\n\n  return <SearchSelectSetter {...props} options={actionOptions} />\n}\n\nEventTargetActionSelect.displayName = \"EventTargetActionSelect\"\n\nexport default EventTargetActionSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventTargetStateSelect.tsx",
    "content": "import { FC, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getGlobalDataExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { BaseSelectSetterProps } from \"./interface\"\nimport SearchSelectSetter from \"./searchSelect\"\n\nconst EventtargetStateSelect: FC<BaseSelectSetterProps> = (props) => {\n  const { value } = props\n\n  const globalDataResult = useSelector(getGlobalDataExecutionResult)\n\n  const finalOptions = useMemo(() => {\n    return Object.keys(globalDataResult)\n      .filter((key) => !key.startsWith(\"$\"))\n      .map((key) => ({\n        label: key,\n        value: key,\n      }))\n  }, [globalDataResult])\n\n  const finalValue = useMemo(() => {\n    const index = finalOptions.findIndex((option) => {\n      return option.value === value\n    })\n    if (index !== -1) return value\n    return undefined\n  }, [finalOptions, value])\n\n  return (\n    <SearchSelectSetter\n      {...props}\n      value={finalValue as string}\n      options={finalOptions}\n    />\n  )\n}\n\nEventtargetStateSelect.displayName = \"EventtargetStateSelect\"\n\nexport default EventtargetStateSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventTargetWidgetSelect.tsx",
    "content": "import { FC, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport {\n  getCurrentPageWidgetExecutionResultArray,\n  getWidgetExecutionResult,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\nimport { BaseSelectSetterProps } from \"./interface\"\nimport SearchSelectSetter from \"./searchSelect\"\n\nconst EventTargetWidgetSelect: FC<BaseSelectSetterProps> = (props) => {\n  const { widgetDisplayName, value, widgetOrAction } = props\n\n  const widgetDisplayNameMapProps = useSelector(getWidgetExecutionResult)\n  const currentPageWidgetDisplayNameMapProps = useSelector(\n    getCurrentPageWidgetExecutionResultArray,\n  )\n\n  const finalOptions = useMemo(() => {\n    const tmpOptions: { label: string; value: string }[] = []\n    if (widgetOrAction === \"ACTION\") {\n      Object.keys(widgetDisplayNameMapProps).forEach((key) => {\n        if (key !== widgetDisplayName) {\n          const widgetType = widgetDisplayNameMapProps[key].$widgetType\n          const widgetMethod =\n            widgetBuilder(widgetType)?.eventHandlerConfig?.methods ?? []\n          if (widgetMethod.length > 0) {\n            tmpOptions.push({\n              label: key,\n              value: key,\n            })\n          }\n        }\n      })\n    }\n\n    if (widgetOrAction === \"WIDGET\") {\n      currentPageWidgetDisplayNameMapProps.forEach((node) => {\n        const key = node.displayName\n        if (key !== widgetDisplayName) {\n          const widgetType = node.$widgetType\n          const widgetMethod =\n            widgetBuilder(widgetType)?.eventHandlerConfig?.methods ?? []\n          if (widgetMethod.length > 0) {\n            tmpOptions.push({\n              label: key,\n              value: key,\n            })\n          }\n        }\n      })\n    }\n\n    return tmpOptions\n  }, [\n    currentPageWidgetDisplayNameMapProps,\n    widgetDisplayName,\n    widgetDisplayNameMapProps,\n    widgetOrAction,\n  ])\n\n  const actionFinalValue = useMemo(() => {\n    const index = finalOptions.findIndex((option) => {\n      return option.value === value\n    })\n    if (index !== -1) return value\n    return undefined\n  }, [finalOptions, value])\n\n  const widgetFinalValue = useMemo(() => {\n    const index = finalOptions.findIndex((option) => {\n      return option.value === value\n    })\n    if (index !== -1) return value\n    return undefined\n  }, [finalOptions, value])\n\n  const finalValue =\n    widgetOrAction === \"WIDGET\" ? widgetFinalValue : actionFinalValue\n\n  return (\n    <SearchSelectSetter\n      {...props}\n      value={finalValue as string}\n      options={finalOptions}\n    />\n  )\n}\n\nEventTargetWidgetSelect.displayName = \"EventTargetWidgetSelect\"\n\nexport default EventTargetWidgetSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventWidgetMethodSelect.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getCachedAction } from \"@/redux/config/configSelector\"\nimport { getWidgetExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\nimport { BaseSelectSetterProps } from \"./interface\"\nimport SearchSelectSetter from \"./searchSelect\"\n\nconst EventWidgetMethodSelect: FC<BaseSelectSetterProps> = (props) => {\n  const { parentAttrName, value, widgetDisplayName, widgetOrAction } = props\n\n  const widgetDisplayNameMapProps = useSelector(getWidgetExecutionResult)\n  const selectedAction = useSelector(getCachedAction)\n  const selectedWidgetID = useMemo(() => {\n    if (widgetOrAction === \"WIDGET\") {\n      return get(\n        widgetDisplayNameMapProps,\n        `${widgetDisplayName}.${parentAttrName}.widgetID`,\n      )\n    } else {\n      return get(selectedAction, `content.${parentAttrName}.widgetID`)\n    }\n  }, [\n    widgetDisplayNameMapProps,\n    widgetDisplayName,\n    parentAttrName,\n    selectedAction,\n    widgetOrAction,\n  ])\n  const selectedWidgetType = useMemo(() => {\n    return get(widgetDisplayNameMapProps, `${selectedWidgetID}.$widgetType`)\n  }, [widgetDisplayNameMapProps, selectedWidgetID])\n  const finalOptions = useMemo(() => {\n    let tmpOptions: string[] = []\n    const eventHandlerConfig =\n      widgetBuilder(selectedWidgetType)?.eventHandlerConfig\n    if (eventHandlerConfig) {\n      tmpOptions = eventHandlerConfig.methods\n    }\n    return tmpOptions\n  }, [selectedWidgetType])\n\n  const finalValue = useMemo(() => {\n    const index = finalOptions.findIndex((option) => {\n      return option === value\n    })\n    if (index !== -1 && selectedWidgetType !== undefined) return value\n    return undefined\n  }, [finalOptions, value, selectedWidgetType])\n\n  return (\n    <SearchSelectSetter\n      {...props}\n      value={finalValue as string}\n      options={finalOptions}\n    />\n  )\n}\nEventWidgetMethodSelect.displayName = \"EventWidgetMethodSelect\"\nexport default EventWidgetMethodSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/heightModeSelect.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport BaseSelectSetter from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/baseSelect\"\nimport { HeightModeSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/interface\"\nimport { DEFAULT_MAX_HEIGHT } from \"@/page/App/components/ScaleSquare/components/AutoHeightWithLimitedContainer\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { RootState } from \"@/store\"\nimport { RESIZE_DIRECTION } from \"@/widgetLibrary/interface\"\n\nconst HeightModeSelect: FC<HeightModeSetterProps> = (props) => {\n  const currentNode = useSelector((state: RootState) => {\n    const components = getComponentMap(state)\n    return searchComponentFromMap(components, props.widgetDisplayName)\n  })!\n  const { handleUpdateMultiAttrDSL, value: heightMode } = props\n  const handleUpdateHeightMode = useCallback(\n    (attrName: string, value: string) => {\n      if (heightMode === value) return\n      const resizeDirection =\n        value === \"fixed\" ? RESIZE_DIRECTION.ALL : RESIZE_DIRECTION.HORIZONTAL\n      const otherAttrs =\n        value === \"limited\"\n          ? {\n              dynamicMaxHeight:\n                currentNode.h * UNIT_HEIGHT + DEFAULT_MAX_HEIGHT,\n              dynamicMinHeight: currentNode.h * UNIT_HEIGHT,\n            }\n          : {\n              dynamicMaxHeight: undefined,\n              dynamicMinHeight: undefined,\n            }\n      handleUpdateMultiAttrDSL({\n        [attrName]: value,\n        resizeDirection,\n        ...otherAttrs,\n      })\n    },\n    [currentNode, handleUpdateMultiAttrDSL, heightMode],\n  )\n  return (\n    <BaseSelectSetter {...props} handleUpdateDsl={handleUpdateHeightMode} />\n  )\n}\n\nHeightModeSelect.displayName = \"HeightModeSelect\"\n\nexport default HeightModeSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\n\nexport interface BaseSelectSetterProps extends BaseSetter {\n  options?: any\n  allowClear?: boolean\n  onChange?: (value: any) => void\n  placeholder?: string\n  value: string\n  showSearch?: boolean\n  labelSize?: \"medium\" | \"small\"\n}\n\nexport interface BaseDynamicSelectSetterProps extends BaseSetter {\n  isDynamic: boolean\n  onClickFxButton: () => void\n  onChangeInput: (value: string) => void\n  onChangeSelect: (value: any) => void\n  path: string\n  options: any\n  value: any\n  selectPlaceholder?: string\n  inputPlaceholder?: string\n  isError: boolean\n  detailedDescription?: string\n}\n\nexport interface HeightModeSetterProps extends BaseSelectSetterProps {\n  handleUpdateMultiAttrDSL: (updateSlice: Record<string, any>) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/pageSelect.tsx",
    "content": "import { FC, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getPageExecutionResultArray } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { BaseSelectSetterProps } from \"./interface\"\nimport SearchSelectSetter from \"./searchSelect\"\n\nconst EventTargetPageSelect: FC<BaseSelectSetterProps> = (props) => {\n  const { value } = props\n  const pageArray = useSelector(getPageExecutionResultArray)\n\n  const finalOptions = useMemo(() => {\n    const tmpOptions: { label: string; value: string }[] = []\n    pageArray.forEach((pageNode) => {\n      tmpOptions.push({\n        label: pageNode.displayName,\n        value: pageNode.displayName,\n      })\n    })\n    return tmpOptions\n  }, [pageArray])\n\n  const finalValue = useMemo(() => {\n    const index = finalOptions.findIndex((option) => {\n      return option.value === value\n    })\n    if (index !== -1) return value\n    return undefined\n  }, [finalOptions, value])\n\n  return (\n    <SearchSelectSetter\n      {...props}\n      value={finalValue as string}\n      options={finalOptions}\n    />\n  )\n}\n\nEventTargetPageSelect.displayName = \"EventTargetPageSelect\"\nexport default EventTargetPageSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/searchSelect.tsx",
    "content": "import { FC } from \"react\"\nimport BaseSelectSetter from \"./baseSelect\"\nimport { BaseSelectSetterProps } from \"./interface\"\n\nconst SearchSelectSetter: FC<BaseSelectSetterProps> = (props) => {\n  return <BaseSelectSetter {...props} showSearch allowClear />\n}\n\nSearchSelectSetter.displayName = \"SearchSelectSetter\"\n\nexport default SearchSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SelectSetter/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { fixedWidthStyle } from \"@/page/App/components/InspectPanel/PanelSetters/style\"\n\nexport const applyBaseSelectWrapperStyle = (\n  isSetterSingleRow: boolean = false,\n): SerializedStyles => {\n  return isSetterSingleRow\n    ? css`\n        width: 100%;\n      `\n    : fixedWidthStyle\n}\n\nexport const setterContainerStyle = (isSetterSingleRow: boolean = false) => {\n  const basicStyle = css`\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n  `\n  const singleRowStyle = css`\n    flex-direction: column;\n    gap: 8px;\n  `\n  return css`\n    display: flex;\n    padding: 8px 0;\n    ${isSetterSingleRow ? singleRowStyle : basicStyle};\n    width: 100%;\n  `\n}\n\nexport const basicDynamicSetterContainerStyle = css`\n  display: flex;\n  padding: 8px 0;\n  flex-direction: column;\n  gap: 8px;\n  width: 100%;\n`\nexport const dynamicSelectHeaderStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n`\n\nexport const dynamicSelectSetterStyle = css`\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/StepsListSetter/index.tsx",
    "content": "import { FC } from \"react\"\nimport i18n from \"@/i18n/config\"\nimport OptionListSetter from \"@/page/App/components/InspectPanel/PanelSetters/OptionListSetter\"\nimport { StepsListSetterProps } from \"./interface\"\n\nconst StepsListSetter: FC<StepsListSetterProps> = (props) => {\n  return (\n    <OptionListSetter\n      headerName={i18n.t(\"widget.step.name\")}\n      itemName=\"Step\"\n      {...props}\n    />\n  )\n}\n\nStepsListSetter.displayName = \"StepsListSetter\"\n\nexport default StepsListSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/StepsListSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { StepsOptionsType } from \"@/widgetLibrary/StepsWidget/interface\"\n\nexport interface StepsListSetterProps extends BaseSetter {\n  value: StepsOptionsType[]\n  childrenSetter?: PanelFieldConfig[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/StyleContainerSetter/index.tsx",
    "content": "import { FC } from \"react\"\nimport RenderFieldAndLabel from \"@/page/App/components/InspectPanel/components/FieldAndLabel\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { StyleContainerSetterProps } from \"./interface\"\nimport { containerStyle, headerContainerStyle } from \"./style\"\n\nconst StyleContainerSetter: FC<StyleContainerSetterProps> = (props) => {\n  const { childrenSetter, widgetDisplayName, labelName } = props\n\n  return (\n    <div css={containerStyle}>\n      <div css={headerContainerStyle}>\n        <PanelLabel labelName={labelName} />\n      </div>\n      {childrenSetter?.map((child) => (\n        <RenderFieldAndLabel\n          key={`${child.id}-${widgetDisplayName}`}\n          config={child}\n          displayName={widgetDisplayName ?? \"\"}\n          parentAttrName=\"\"\n        />\n      ))}\n    </div>\n  )\n}\n\nexport default StyleContainerSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/StyleContainerSetter/interface.ts",
    "content": "import { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface StyleContainerSetterProps {\n  childrenSetter?: PanelFieldConfig[]\n  widgetDisplayName: string\n  labelName?: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/StyleContainerSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  padding: 0px 16px;\n  width: 100%;\n`\n\nexport const headerContainerStyle = css`\n  display: flex;\n  width: 100%;\n  justify-content: space-between;\n  align-items: center;\n  padding: 8px 0;\n`\n\nexport const setterContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 8px 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SwitchSetter/baseSwitch.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC } from \"react\"\nimport { Switch } from \"@illa-design/react\"\nimport { dynamicWidthStyle } from \"@/page/App/components/InspectPanel/PanelSetters/style\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { BaseSwitchProps } from \"./interface\"\nimport { setterContainerStyle } from \"./style\"\n\nconst BaseSwitchSetter: FC<BaseSwitchProps> = (props) => {\n  const {\n    value,\n    attrName,\n    handleUpdateDsl,\n    widgetType,\n    isSetterSingleRow,\n    labelDesc,\n    labelName,\n    labelSize,\n  } = props\n\n  return (\n    <div css={setterContainerStyle(isSetterSingleRow)}>\n      {labelName && (\n        <span>\n          <PanelLabel\n            labelName={labelName}\n            labelDesc={labelDesc}\n            labelSize={labelSize}\n          />\n        </span>\n      )}\n      <div css={dynamicWidthStyle}>\n        <Switch\n          onChange={(value) => {\n            handleUpdateDsl(attrName, value)\n            trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n              element: \"component_inspect_radio\",\n              parameter1: widgetType,\n              parameter2: attrName,\n            })\n          }}\n          checked={value}\n          colorScheme=\"techPurple\"\n        />\n      </div>\n    </div>\n  )\n}\n\nBaseSwitchSetter.displayName = \"BaseSwitchSetter\"\n\nexport default BaseSwitchSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SwitchSetter/driveWithStatusSwitch.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { debounce } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useMemo, useRef } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Switch, useModal } from \"@illa-design/react\"\nimport { dynamicWidthStyle } from \"@/page/App/components/InspectPanel/PanelSetters/style\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport {\n  fetchAnonymousPermission,\n  fetchCloseAnonymousPermission,\n  fetchOpenAnonymousPermission,\n} from \"@/services/drive\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { BaseSwitchProps } from \"./interface\"\nimport { setterContainerStyle } from \"./style\"\n\nconst DriveWithStatusSwitchSetter: FC<BaseSwitchProps> = (props) => {\n  const {\n    value,\n    attrName,\n    handleUpdateDsl,\n    widgetType,\n    handleUpdateMultiAttrDSL,\n    isSetterSingleRow,\n    labelDesc,\n    labelName,\n    labelSize,\n  } = props\n  const anonymousPermission = useRef<boolean>(true)\n  const modal = useModal()\n  const { t } = useTranslation()\n  const switchPermission = useCallback(\n    async (_v: boolean) => {\n      if (_v && !anonymousPermission.current) {\n        modal.show({\n          id: \"switchPermission\",\n          title: t(\n            \"editor.inspect.setter_option.drive_builder.anonymous_modal.title\",\n          ),\n          children: t(\n            \"editor.inspect.setter_option.drive_builder.anonymous_modal.desc\",\n          ),\n          okText: t(\n            \"editor.inspect.setter_option.drive_builder.anonymous_modal.submitBtn\",\n          ),\n          cancelText: t(\n            \"editor.inspect.setter_option.drive_builder.anonymous_modal.cancelBtn\",\n          ),\n          onOk: async () => {\n            try {\n              await fetchOpenAnonymousPermission()\n              anonymousPermission.current = true\n              const updateSlice: Record<string, unknown> = {\n                [attrName]: _v,\n              }\n              if (_v) {\n                updateSlice.ILLADriveFolder = \"\"\n              }\n              handleUpdateMultiAttrDSL?.(updateSlice)\n            } catch (e) {}\n          },\n        })\n      } else if (!_v && anonymousPermission.current) {\n        try {\n          await fetchCloseAnonymousPermission()\n          anonymousPermission.current = false\n          handleUpdateDsl(attrName, _v)\n        } catch (e) {}\n      } else {\n        const updateSlice: Record<string, unknown> = {\n          [attrName]: _v,\n        }\n        if (_v) {\n          updateSlice.ILLADriveFolder = \"\"\n        }\n        handleUpdateMultiAttrDSL?.(updateSlice)\n      }\n    },\n    [attrName, handleUpdateDsl, handleUpdateMultiAttrDSL, modal, t],\n  )\n  const debounceHandleOnSwitch = useMemo(() => {\n    return debounce(async (_v: boolean) => {\n      try {\n        await switchPermission(_v)\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n          element: \"component_inspect_radio\",\n          parameter1: widgetType,\n          parameter2: attrName,\n        })\n      } catch (e) {}\n    }, 500)\n  }, [attrName, switchPermission, widgetType])\n\n  useEffect(() => {\n    const request = async () => {\n      try {\n        const res = await fetchAnonymousPermission()\n        anonymousPermission.current = res.data?.anonymous\n      } catch (e) {}\n    }\n    request()\n  }, [attrName])\n\n  return (\n    <div css={setterContainerStyle(isSetterSingleRow)}>\n      <span>\n        {labelName && (\n          <PanelLabel\n            labelName={labelName}\n            labelDesc={labelDesc}\n            labelSize={labelSize}\n          />\n        )}\n      </span>\n      <div css={dynamicWidthStyle}>\n        <Switch\n          onChange={debounceHandleOnSwitch}\n          checked={value}\n          colorScheme=\"techPurple\"\n        />\n      </div>\n    </div>\n  )\n}\n\nDriveWithStatusSwitchSetter.displayName = \"DriveWithStatusSwitchSetter\"\nexport default DriveWithStatusSwitchSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SwitchSetter/dynamicSwitch.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { get } from \"lodash-es\"\nimport { FC, useCallback } from \"react\"\nimport { Switch } from \"@illa-design/react\"\nimport { DynamicIcon } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/DynamicIcon\"\nimport { PanelLabel } from \"@/page/App/components/InspectPanel/components/Label\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport BaseInput from \"../InputSetter/BaseInput\"\nimport { DynamicSwitchProps } from \"./interface\"\nimport {\n  applyLabelWrapperStyle,\n  customAndSwitchWrapperStyle,\n  dynamicSwitchWrapperStyle,\n} from \"./style\"\n\nconst DynamicSwitchSetter: FC<DynamicSwitchProps> = (props) => {\n  const {\n    attrName,\n    labelName,\n    labelDesc,\n    handleUpdateDsl,\n    defaultValue,\n    handleUpdateMultiAttrDSL,\n    value,\n    openDynamic,\n    detailedDescription,\n    widgetType,\n    componentNode,\n  } = props\n\n  const customSelected = get(componentNode, `props.${attrName}Dynamic`, false)\n\n  const handleClickDynamicIcon = useCallback(() => {\n    if (customSelected) {\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: undefined,\n        [`${attrName}Dynamic`]: false,\n      })\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"fx\",\n        parameter1: widgetType,\n        parameter2: attrName,\n        parameter3: \"off\",\n      })\n    } else {\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: undefined,\n        [`${attrName}Dynamic`]: true,\n      })\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"fx\",\n        parameter1: widgetType,\n        parameter2: attrName,\n        parameter3: \"on\",\n      })\n    }\n  }, [attrName, customSelected, handleUpdateMultiAttrDSL, widgetType])\n\n  return (\n    <div css={applyLabelWrapperStyle(customSelected)}>\n      <div css={dynamicSwitchWrapperStyle}>\n        {labelName && (\n          <PanelLabel labelName={labelName} labelDesc={labelDesc} />\n        )}\n        <div css={customAndSwitchWrapperStyle}>\n          {openDynamic && (\n            <DynamicIcon\n              isDynamic={customSelected}\n              hasRightContent\n              onClick={handleClickDynamicIcon}\n            />\n          )}\n          {!customSelected && (\n            <Switch\n              defaultValue={defaultValue}\n              onChange={(value) => {\n                handleUpdateDsl(attrName, value)\n                trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                  element: \"component_inspect_radio\",\n                  parameter1: widgetType,\n                  parameter2: attrName,\n                })\n              }}\n              checked={value as boolean}\n              colorScheme=\"techPurple\"\n            />\n          )}\n        </div>\n      </div>\n      {customSelected && (\n        <BaseInput\n          {...props}\n          value={value as string}\n          isSetterSingleRow\n          detailedDescription={detailedDescription ?? labelDesc}\n          onlyHasSetter={true}\n        />\n      )}\n    </div>\n  )\n}\n\nDynamicSwitchSetter.displayName = \"DynamicSwitchSetter\"\n\nexport default DynamicSwitchSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SwitchSetter/interface.tsx",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelLabelProps } from \"@/page/App/components/InspectPanel/components/Label/interface\"\n\nexport interface BaseSwitchProps extends BaseSetter {\n  value?: boolean\n  labelName?: string\n  detailedDescription?: string\n  labelDesc?: string\n  labelSize?: \"medium\" | \"small\"\n}\n\nexport interface DynamicSwitchProps extends BaseSetter, PanelLabelProps {\n  openDynamic?: boolean\n  value?: string | boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/SwitchSetter/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const dynamicSwitchWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  width: 100%;\n`\n\nexport const customAndSwitchWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  min-height: 28px;\n`\n\nexport const applyCustomIconStyle = (\n  isSelected: boolean = false,\n): SerializedStyles => {\n  const selectedStyle = isSelected\n    ? css`\n        color: ${globalColor(`--${illaPrefix}-purple-03`)};\n      `\n    : css`\n        color: ${globalColor(`--${illaPrefix}-grayBlue-06`)};\n        margin-right: 10px;\n      `\n  return css`\n    ${selectedStyle};\n    width: 16px;\n    height: 16px;\n    font-size: 16px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n\n    :hover {\n      cursor: pointer;\n      color: ${globalColor(`--${illaPrefix}-purple-03`)};\n    }\n  `\n}\n\nconst singleRowStyle = css`\n  width: 100%;\n  padding: 8px 16px;\n`\n\nconst doubleRowStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  padding: 8px 16px;\n  gap: 8px;\n`\n\nexport const applyLabelWrapperStyle = (\n  isCustom: boolean = false,\n): SerializedStyles => {\n  return isCustom ? doubleRowStyle : singleRowStyle\n}\n\nexport const setterContainerStyle = (isSetterSingleRow: boolean = false) => {\n  const basicStyle = css`\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n  `\n  const singleRowStyle = css`\n    flex-direction: column;\n    gap: 8px;\n  `\n  return css`\n    display: flex;\n    padding: 8px 0;\n    ${isSetterSingleRow ? singleRowStyle : basicStyle};\n    width: 100%;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/body.tsx",
    "content": "import { AnimatePresence, Reorder } from \"framer-motion\"\nimport { isEqual } from \"lodash-es\"\nimport { FC, useContext, useEffect, useState } from \"react\"\nimport { CellItemProps } from \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/interface\"\nimport { removeNativeStyle } from \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/style\"\nimport { ColumnItem } from \"./columnItem\"\nimport { ColumnListSetterContext } from \"./context/columnListContext\"\nimport { EmptyBody } from \"./empty\"\n\nexport const ListBody: FC = () => {\n  const { columnItems, handleUpdateDsl, attrPath } = useContext(\n    ColumnListSetterContext,\n  )\n  const [items, setItems] = useState(columnItems)\n\n  useEffect(() => {\n    if (!isEqual(columnItems, items)) {\n      setItems(columnItems)\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [columnItems])\n\n  const updateItem = (values: CellItemProps[]) => {\n    if (isEqual(values, items)) return\n    setItems(values)\n  }\n\n  if (!columnItems || !Array.isArray(columnItems) || columnItems.length === 0)\n    return <EmptyBody />\n\n  return (\n    <AnimatePresence initial={false}>\n      <Reorder.Group\n        axis=\"y\"\n        initial={false}\n        values={items}\n        onReorder={updateItem}\n        css={removeNativeStyle}\n      >\n        {items.map((item, index) => {\n          const { cellValue, id, label } = item\n          return (\n            <Reorder.Item\n              initial={false}\n              css={removeNativeStyle}\n              key={id}\n              value={item}\n              onDragEnd={() => {\n                const orderItems = items.map((item, index) => {\n                  return { ...item, index }\n                })\n                handleUpdateDsl(attrPath, orderItems)\n              }}\n            >\n              <ColumnItem\n                key={id}\n                label={label}\n                cellValue={cellValue}\n                index={index}\n                id={id}\n              />\n            </Reorder.Item>\n          )\n        })}\n      </Reorder.Group>\n    </AnimatePresence>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/columnItem.tsx",
    "content": "import { FC, useRef } from \"react\"\nimport { DragIconAndLabel } from \"./dragIconAndLabel\"\nimport { ColumnItemProps } from \"./interface\"\nimport { optionListItemStyle } from \"./style\"\n\nexport const ColumnItem: FC<ColumnItemProps> = (props) => {\n  const { index, cellValue, label, id } = props\n  const ref = useRef<HTMLDivElement>(null)\n\n  return (\n    <div ref={ref} css={optionListItemStyle}>\n      <DragIconAndLabel\n        id={id}\n        index={index}\n        label={label}\n        cellValue={cellValue}\n      />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/context/columnListContext.tsx",
    "content": "import { FC, ReactNode, createContext, useCallback } from \"react\"\nimport { CellItemProps } from \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { generateCellItemId } from \"../utils/generateNewColumns\"\n\ninterface ProviderProps {\n  columnItems: CellItemProps[]\n  childrenSetter: PanelFieldConfig[]\n  widgetDisplayName: string\n  attrPath: string\n  handleUpdateDsl: (attrPath: string, value: any) => void\n  children: ReactNode\n}\n\ninterface Inject extends Omit<ProviderProps, \"children\"> {\n  handleDeleteColumnItem: (index: number) => void\n  handleCopyColumnItem: (index: number) => void\n  handleMoveColumnItem: (dragIndex: number, hoverIndex: number) => void\n  handleUpdateItemVisible: (attrName: string, visible?: boolean) => void\n}\n\nexport const ColumnListSetterContext = createContext<Inject>({} as Inject)\n\nexport const ColumnsSetterProvider: FC<ProviderProps> = (props) => {\n  const { columnItems, attrPath, handleUpdateDsl } = props\n\n  const handleDeleteColumnItem = useCallback(\n    (index: number) => {\n      const updatedArray = columnItems.filter(\n        (optionItem: Record<string, any>, i: number) => {\n          return i !== index\n        },\n      )\n      handleUpdateDsl(attrPath, updatedArray)\n    },\n    [columnItems, handleUpdateDsl, attrPath],\n  )\n\n  const handleCopyColumnItem = useCallback(\n    (index: number) => {\n      let targetOptionItem = columnItems.find(\n        (optionItem: Record<string, any>, i: number) => {\n          return i === index\n        },\n      )\n      if (!targetOptionItem) return\n      targetOptionItem = {\n        ...targetOptionItem,\n        id: generateCellItemId(),\n      }\n      const updatedArray = [...columnItems, targetOptionItem]\n      handleUpdateDsl(attrPath, updatedArray)\n    },\n    [columnItems, handleUpdateDsl, attrPath],\n  )\n\n  const handleMoveColumnItem = useCallback(\n    (dragIndex: number, hoverIndex: number) => {\n      const dragOptionItem = columnItems[dragIndex]\n      const newOptions = [...columnItems]\n      newOptions.splice(dragIndex, 1)\n      newOptions.splice(hoverIndex, 0, dragOptionItem)\n      handleUpdateDsl(attrPath, newOptions)\n    },\n    [attrPath, columnItems, handleUpdateDsl],\n  )\n\n  const handleUpdateItemVisible = useCallback(\n    (attrName: string, visible?: boolean) => {\n      handleUpdateDsl(attrName, visible)\n    },\n    [handleUpdateDsl],\n  )\n\n  const value = {\n    ...props,\n    handleDeleteColumnItem,\n    handleCopyColumnItem,\n    handleMoveColumnItem,\n    handleUpdateItemVisible,\n  }\n\n  return (\n    <ColumnListSetterContext.Provider value={value}>\n      {props.children}\n    </ColumnListSetterContext.Provider>\n  )\n}\n\nColumnsSetterProvider.displayName = \"ColumnsSetterProvider\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/dragIconAndLabel.tsx",
    "content": "import { FC, useCallback, useContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { DragPointIcon, ReduceIcon, Trigger } from \"@illa-design/react\"\nimport { BaseModal } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal\"\nimport { ColumnListSetterContext } from \"./context/columnListContext\"\nimport { DragIconAndLabelProps } from \"./interface\"\nimport {\n  baseIconStyle,\n  dragItemStyle,\n  iconAreaStyle,\n  labelNameAndIconStyle,\n  labelNameWrapperStyle,\n  movableIconWrapperStyle,\n} from \"./style\"\n\nexport const DragIconAndLabel: FC<DragIconAndLabelProps> = (props) => {\n  const { index, label } = props\n  const [modalVisible, setModalVisible] = useState(false)\n  const {\n    columnItems,\n    widgetDisplayName,\n    attrPath,\n    childrenSetter,\n    handleDeleteColumnItem,\n  } = useContext(ColumnListSetterContext)\n\n  const { t } = useTranslation()\n\n  const handleCloseModal = useCallback(() => {\n    setModalVisible(false)\n  }, [])\n\n  return (\n    <Trigger\n      withoutPadding\n      colorScheme=\"white\"\n      popupVisible={modalVisible}\n      content={\n        <BaseModal\n          title={label ?? \"\"}\n          handleCloseModal={handleCloseModal}\n          attrPath={`${attrPath}.${index}`}\n          widgetDisplayName={widgetDisplayName}\n          childrenSetter={childrenSetter}\n        />\n      }\n      trigger=\"click\"\n      showArrow={false}\n      position=\"left\"\n      clickOutsideToClose\n      onVisibleChange={(visible) => {\n        setModalVisible(visible)\n      }}\n    >\n      <div css={dragItemStyle}>\n        <div css={labelNameAndIconStyle}>\n          <span css={movableIconWrapperStyle} className=\"movableIconWrapper\">\n            <DragPointIcon />\n          </span>\n          <span css={labelNameWrapperStyle}>\n            {label ||\n              t(\"editor.inspect.setter_content.option_list.list_no_label\")}\n          </span>\n        </div>\n        <div css={iconAreaStyle}>\n          {columnItems?.length > 1 ? (\n            <span\n              css={baseIconStyle}\n              onClick={(event) => {\n                handleDeleteColumnItem(index)\n                event.stopPropagation()\n              }}\n            >\n              <ReduceIcon />\n            </span>\n          ) : null}\n        </div>\n      </div>\n    </Trigger>\n  )\n}\n\nDragIconAndLabel.displayName = \"DragIconAndLabel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/empty.tsx",
    "content": "import { FC } from \"react\"\nimport { emptyEmptyBodyStyle } from \"./style\"\n\nexport const EmptyBody: FC = () => {\n  return <div css={emptyEmptyBodyStyle}>No columns</div>\n}\n\nEmptyBody.displayName = \"ColumnsEmptyBody\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/header.tsx",
    "content": "import { FC } from \"react\"\nimport { HeaderProps } from \"./interface\"\nimport { optionListHeaderStyle } from \"./style\"\n\nexport const OptionListHeader: FC<HeaderProps> = (props) => {\n  const { labelName } = props\n\n  return (\n    <div css={optionListHeaderStyle}>\n      <div>{labelName}</div>\n    </div>\n  )\n}\n\nOptionListHeader.displayName = \"OptionListHeader\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/index.tsx",
    "content": "import { FC, useCallback, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { AddIcon } from \"@illa-design/react\"\nimport { ListBody } from \"./body\"\nimport { ColumnsSetterProvider } from \"./context/columnListContext\"\nimport { CellSetterProps } from \"./interface\"\nimport {\n  ListStyle,\n  addIconStyle,\n  columnLabelStyle,\n  headerActionButtonStyle,\n} from \"./style\"\nimport {\n  generateNewButtonCellContent,\n  generateNewIconCellContent,\n} from \"./utils/generateNewColumns\"\n\nconst CellSetter: FC<CellSetterProps> = (props) => {\n  const {\n    attrName,\n    handleUpdateDsl,\n    value = [],\n    childrenSetter,\n    widgetDisplayName,\n  } = props\n\n  const { t } = useTranslation()\n\n  const realAttrName = useMemo(() => attrName?.split(\".\")?.pop(), [attrName])\n\n  const handleAddOption = useCallback(() => {\n    const num = value.length + 1\n    if (realAttrName === \"buttonGroupContent\") {\n      const newItem = generateNewButtonCellContent(num)\n      handleUpdateDsl(attrName, [...value, newItem])\n    } else if (realAttrName === \"iconGroupContent\") {\n      const newItem = generateNewIconCellContent(num)\n      handleUpdateDsl(attrName, [...value, newItem])\n    }\n  }, [value, attrName, handleUpdateDsl, realAttrName])\n\n  if (!Array.isArray(childrenSetter) || childrenSetter.length === 0) {\n    return null\n  }\n\n  return (\n    <ColumnsSetterProvider\n      childrenSetter={childrenSetter}\n      widgetDisplayName={widgetDisplayName}\n      columnItems={value}\n      attrPath={attrName}\n      handleUpdateDsl={handleUpdateDsl}\n    >\n      <div css={columnLabelStyle}>\n        <div>\n          {t(\"editor.inspect.setter_content.column_setter.label\", {\n            number: value.length,\n          })}\n        </div>\n        <div css={headerActionButtonStyle} onClick={handleAddOption}>\n          <AddIcon _css={addIconStyle} />\n          <span>{t(\"editor.inspect.setter_content.column_setter.new\")}</span>\n        </div>\n      </div>\n      <div css={ListStyle}>\n        <ListBody />\n      </div>\n    </ColumnsSetterProvider>\n  )\n}\n\nCellSetter.displayName = \"CellSetter\"\n\nexport default CellSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { ColumnItemShape } from \"@/widgetLibrary/TableWidget/interface\"\n\nexport interface HeaderProps {\n  labelName: string\n  handleAddOption: () => void\n}\n\nexport interface CellItemProps {\n  cellValue: string\n  id: string\n  label?: string\n  index: number\n}\n\nexport interface ColumnItemProps extends CellItemProps {}\n\nexport interface DragIconAndLabelProps extends CellItemProps {}\n\nexport interface ColumnListSetterProps extends BaseSetter {\n  value: ColumnItemShape[]\n  childrenSetter?: PanelFieldConfig[]\n}\n\nexport interface CellSetterProps extends BaseSetter {\n  value: CellItemProps[]\n  childrenSetter?: PanelFieldConfig[]\n}\n\nexport interface DragItem {\n  index: number\n  id: string\n  type: string\n}\n\nexport interface ActionMenuProps {\n  index: number\n  handleCloseMode: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\nimport { publicPaddingStyle } from \"@/page/App/components/InspectPanel/style\"\n\nexport const optionListHeaderStyle = css`\n  width: 100%;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  height: 40px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  font-weight: 500;\n  box-sizing: border-box;\n  ${publicPaddingStyle}\n`\n\nexport const headerActionButtonStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: ${globalColor(`--${illaPrefix}-techPurple-03`)};\n  cursor: pointer;\n  font-weight: 400;\n  margin: 0 8px;\n`\n\nexport const columnLabelStyle = css`\n  display: flex;\n  justify-content: space-between;\n  margin: 0 16px 16px;\n  font-size: 14px;\n  font-weight: 600;\n  line-height: 22px;\n`\n\nexport const addIconStyle = css`\n  margin-right: 4px;\n  font-size: 12px;\n`\n\nexport const ListStyle = css`\n  border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  margin: 0 16px;\n  border-radius: 8px;\n  overflow: hidden;\n`\n\nexport const optionListItemStyle = css`\n  display: flex;\n  justify-content: space-between;\n  padding-right: 16px;\n  height: 40px;\n  align-items: center;\n  cursor: pointer;\n\n  &:hover {\n    .movableIconWrapper {\n      opacity: 1;\n    }\n  }\n`\n\nexport const dragItemStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n`\n\nexport const labelNameAndIconStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n`\n\nexport const labelNameWrapperStyle = css`\n  font-size: 14px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const movableIconWrapperStyle = css`\n  opacity: 0;\n  cursor: grab;\n  display: flex;\n  align-items: center;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const emptyEmptyBodyStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 100%;\n  height: 40px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const iconAreaStyle = css`\n  display: flex;\n  flex-direction: row;\n  gap: 16px;\n`\n\nexport const baseIconStyle = css`\n  font-size: 16px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  cursor: pointer;\n  :hover {\n    color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  }\n`\n\nexport const eyeIconStyle = css`\n  visibility: hidden;\n  ${baseIconStyle}\n`\n\nexport const removeNativeStyle = css`\n  list-style: none;\n  padding: 0;\n  margin: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/utils/generateNewColumns.ts",
    "content": "import { v4 } from \"uuid\"\n\nexport const generateCellItemId = () => `cell-${v4()}`\n\nexport const generateNewButtonCellContent = (number: number) => {\n  const id = generateCellItemId()\n  return {\n    label: `Button${number}`,\n    cellValue: `Button${number}`,\n    colorScheme: \"blue\",\n    variant: \"fill\",\n    id,\n    index: number - 1,\n  }\n}\n\nexport const generateNewIconCellContent = (number: number) => {\n  const id = generateCellItemId()\n  return {\n    label: `Icon${number}`,\n    cellValue: \"BsHandThumbsUp\",\n    colorScheme: \"grayBlue\",\n    id,\n    index: number - 1,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/body.tsx",
    "content": "import { AnimatePresence, Reorder } from \"framer-motion\"\nimport { isEqual } from \"lodash-es\"\nimport { FC, useContext, useEffect, useState } from \"react\"\nimport { removeNativeStyle } from \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/style\"\nimport { ColumnItemShape } from \"@/widgetLibrary/TableWidget/interface\"\nimport { ColumnItem } from \"./columnItem\"\nimport { ColumnListSetterContext } from \"./context/columnListContext\"\nimport { EmptyBody } from \"./empty\"\n\nexport const ListBody: FC = () => {\n  const { columnItems, handleUpdateDsl, attrPath } = useContext(\n    ColumnListSetterContext,\n  )\n  const [items, setItems] = useState(columnItems)\n\n  useEffect(() => {\n    if (!isEqual(columnItems, items)) {\n      setItems(columnItems)\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [columnItems])\n\n  const updateItem = (values: ColumnItemShape[]) => {\n    if (isEqual(values, items)) return\n    setItems(values)\n  }\n\n  if (!columnItems || !Array.isArray(columnItems) || columnItems.length === 0)\n    return <EmptyBody />\n\n  return (\n    <AnimatePresence initial={false}>\n      <Reorder.Group\n        axis=\"y\"\n        initial={false}\n        values={items}\n        onReorder={updateItem}\n        css={removeNativeStyle}\n      >\n        {items.map((item, index) => {\n          const { value, header, accessorKey, visible, custom, id } = item\n          return (\n            <Reorder.Item\n              initial={false}\n              css={removeNativeStyle}\n              key={item.accessorKey}\n              value={item}\n              onDragEnd={() => {\n                const orderItems = items.map((item, index) => {\n                  return { ...item, columnIndex: index }\n                })\n                handleUpdateDsl(attrPath, orderItems)\n              }}\n            >\n              <ColumnItem\n                key={accessorKey}\n                accessorKey={accessorKey}\n                header={header}\n                value={value}\n                visible={visible}\n                custom={custom}\n                index={index}\n                id={id}\n              />\n            </Reorder.Item>\n          )\n        })}\n      </Reorder.Group>\n    </AnimatePresence>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/columnItem.tsx",
    "content": "import { FC, useRef } from \"react\"\nimport { DragIconAndLabel } from \"./dragIconAndLabel\"\nimport { ColumnItemProps } from \"./interface\"\nimport { optionListItemStyle } from \"./style\"\n\nexport const ColumnItem: FC<ColumnItemProps> = (props) => {\n  const { header, visible, custom, index } = props\n  const ref = useRef<HTMLDivElement>(null)\n\n  return (\n    <div ref={ref} css={optionListItemStyle}>\n      <DragIconAndLabel\n        index={index}\n        label={header}\n        visible={visible}\n        custom={custom}\n      />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/context/columnListContext.tsx",
    "content": "import { FC, ReactNode, createContext, useCallback } from \"react\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { ColumnItemShape } from \"@/widgetLibrary/TableWidget/interface\"\nimport { generateColumnItemId } from \"../utils/generateNewColumns\"\n\ninterface ProviderProps {\n  columnItems: ColumnItemShape[]\n  childrenSetter: PanelFieldConfig[]\n  widgetDisplayName: string\n  attrPath: string\n  handleUpdateDsl: (attrPath: string, value: any) => void\n  children: ReactNode\n}\n\ninterface Inject extends Omit<ProviderProps, \"children\"> {\n  handleDeleteColumnItem: (index: number) => void\n  handleCopyColumnItem: (index: number) => void\n  handleMoveColumnItem: (dragIndex: number, hoverIndex: number) => void\n  handleUpdateItemVisible: (attrName: string, visible?: boolean) => void\n}\n\nexport const ColumnListSetterContext = createContext<Inject>({} as Inject)\n\nexport const ColumnsSetterProvider: FC<ProviderProps> = (props) => {\n  const { columnItems, attrPath, handleUpdateDsl } = props\n\n  const handleDeleteColumnItem = useCallback(\n    (index: number) => {\n      const updatedArray = columnItems.filter(\n        (optionItem: Record<string, any>, i: number) => {\n          return i !== index\n        },\n      )\n      handleUpdateDsl(attrPath, updatedArray)\n    },\n    [columnItems, handleUpdateDsl, attrPath],\n  )\n\n  const handleCopyColumnItem = useCallback(\n    (index: number) => {\n      let targetOptionItem = columnItems.find(\n        (optionItem: Record<string, any>, i: number) => {\n          return i === index\n        },\n      )\n      if (!targetOptionItem) return\n      targetOptionItem = {\n        ...targetOptionItem,\n        accessorKey: generateColumnItemId(),\n      }\n      const updatedArray = [...columnItems, targetOptionItem]\n      handleUpdateDsl(attrPath, updatedArray)\n    },\n    [columnItems, handleUpdateDsl, attrPath],\n  )\n\n  const handleMoveColumnItem = useCallback(\n    (dragIndex: number, hoverIndex: number) => {\n      const dragOptionItem = columnItems[dragIndex]\n      const newOptions = [...columnItems]\n      newOptions.splice(dragIndex, 1)\n      newOptions.splice(hoverIndex, 0, dragOptionItem)\n      handleUpdateDsl(attrPath, newOptions)\n    },\n    [attrPath, columnItems, handleUpdateDsl],\n  )\n\n  const handleUpdateItemVisible = useCallback(\n    (attrName: string, visible?: boolean) => {\n      handleUpdateDsl(attrName, visible)\n    },\n    [handleUpdateDsl],\n  )\n\n  const value = {\n    ...props,\n    handleDeleteColumnItem,\n    handleCopyColumnItem,\n    handleMoveColumnItem,\n    handleUpdateItemVisible,\n  }\n\n  return (\n    <ColumnListSetterContext.Provider value={value}>\n      {props.children}\n    </ColumnListSetterContext.Provider>\n  )\n}\n\nColumnsSetterProvider.displayName = \"ColumnsSetterProvider\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/dragIconAndLabel.tsx",
    "content": "import { FC, useCallback, useContext, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  DragPointIcon,\n  EyeOffIcon,\n  EyeOnIcon,\n  ReduceIcon,\n  Trigger,\n} from \"@illa-design/react\"\nimport { BaseModal } from \"@/page/App/components/InspectPanel/PanelSetters/PublicComponent/Modal\"\nimport { ColumnListSetterContext } from \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/context/columnListContext\"\nimport { DragIconAndLabelProps } from \"./interface\"\nimport {\n  baseIconStyle,\n  dragItemStyle,\n  iconAreaStyle,\n  labelNameAndIconStyle,\n  labelNameWrapperStyle,\n  movableIconWrapperStyle,\n} from \"./style\"\n\nexport const DragIconAndLabel: FC<DragIconAndLabelProps> = (props) => {\n  const { index, label, visible, custom } = props\n  const [modalVisible, setModalVisible] = useState(false)\n  const {\n    widgetDisplayName,\n    attrPath,\n    childrenSetter,\n    handleUpdateItemVisible,\n    handleDeleteColumnItem,\n  } = useContext(ColumnListSetterContext)\n\n  const { t } = useTranslation()\n\n  const handleCloseModal = useCallback(() => {\n    setModalVisible(false)\n  }, [])\n\n  return (\n    <Trigger\n      withoutPadding\n      colorScheme=\"white\"\n      popupVisible={modalVisible}\n      content={\n        <BaseModal\n          title={label ?? \"\"}\n          handleCloseModal={handleCloseModal}\n          attrPath={`${attrPath}.${index}`}\n          widgetDisplayName={widgetDisplayName}\n          childrenSetter={childrenSetter}\n        />\n      }\n      trigger=\"click\"\n      showArrow={false}\n      position=\"left\"\n      clickOutsideToClose\n      onVisibleChange={(visible) => {\n        setModalVisible(visible)\n      }}\n    >\n      <div css={dragItemStyle}>\n        <div css={labelNameAndIconStyle}>\n          <span css={movableIconWrapperStyle} className=\"movableIconWrapper\">\n            <DragPointIcon />\n          </span>\n          <span css={labelNameWrapperStyle}>\n            {label ||\n              t(\"editor.inspect.setter_content.option_list.list_no_label\")}\n          </span>\n        </div>\n        <div css={iconAreaStyle}>\n          <span\n            css={baseIconStyle}\n            onClick={(event) => {\n              handleUpdateItemVisible(`${attrPath}.${index}.visible`, !visible)\n              event.stopPropagation()\n            }}\n          >\n            {visible ? <EyeOnIcon /> : <EyeOffIcon />}\n          </span>\n          {custom ? (\n            <span\n              css={baseIconStyle}\n              onClick={(event) => {\n                handleDeleteColumnItem(index)\n                event.stopPropagation()\n              }}\n            >\n              <ReduceIcon />\n            </span>\n          ) : null}\n        </div>\n      </div>\n    </Trigger>\n  )\n}\n\nDragIconAndLabel.displayName = \"DragIconAndLabel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/empty.tsx",
    "content": "import { FC } from \"react\"\nimport { emptyEmptyBodyStyle } from \"./style\"\n\nexport const EmptyBody: FC = () => {\n  return <div css={emptyEmptyBodyStyle}>No columns</div>\n}\n\nEmptyBody.displayName = \"ColumnsEmptyBody\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/header.tsx",
    "content": "import { FC } from \"react\"\nimport { HeaderProps } from \"./interface\"\nimport { optionListHeaderStyle } from \"./style\"\n\nexport const OptionListHeader: FC<HeaderProps> = (props) => {\n  const { labelName } = props\n\n  return (\n    <div css={optionListHeaderStyle}>\n      <div>{labelName}</div>\n    </div>\n  )\n}\n\nOptionListHeader.displayName = \"OptionListHeader\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/index.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { AddIcon } from \"@illa-design/react\"\nimport { ListBody } from \"./body\"\nimport { ColumnsSetterProvider } from \"./context/columnListContext\"\nimport { ColumnListSetterProps } from \"./interface\"\nimport {\n  ListStyle,\n  addIconStyle,\n  columnLabelStyle,\n  headerActionButtonStyle,\n  optionListHeaderStyle,\n} from \"./style\"\nimport { generateNewColumnItem } from \"./utils/generateNewColumns\"\n\nconst ColumnSetter: FC<ColumnListSetterProps> = (props) => {\n  const {\n    attrName,\n    handleUpdateDsl,\n    value = [],\n    childrenSetter,\n    widgetDisplayName,\n  } = props\n\n  const { t } = useTranslation()\n\n  const handleAddOption = useCallback(() => {\n    const num = value.length + 1\n    const newItem = generateNewColumnItem(num)\n    handleUpdateDsl(attrName, [...value, newItem])\n  }, [value, attrName, handleUpdateDsl])\n\n  if (!Array.isArray(childrenSetter) || childrenSetter.length === 0) {\n    return null\n  }\n\n  return (\n    <ColumnsSetterProvider\n      childrenSetter={childrenSetter}\n      widgetDisplayName={widgetDisplayName}\n      columnItems={value}\n      attrPath={attrName}\n      handleUpdateDsl={handleUpdateDsl}\n    >\n      <div css={columnLabelStyle}>\n        <div>\n          {t(\"editor.inspect.setter_content.column_setter.label\", {\n            number: value.length,\n          })}\n        </div>\n        <div css={headerActionButtonStyle} onClick={handleAddOption}>\n          <AddIcon _css={addIconStyle} />\n          <span>{t(\"editor.inspect.setter_content.column_setter.new\")}</span>\n        </div>\n      </div>\n      <div css={ListStyle}>\n        <div css={optionListHeaderStyle}>\n          <div>{t(\"editor.inspect.setter_content.column_setter.title\")}</div>\n        </div>\n        <ListBody />\n      </div>\n    </ColumnsSetterProvider>\n  )\n}\n\nColumnSetter.displayName = \"ColumnSetter\"\n\nexport default ColumnSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { ColumnItemShape } from \"@/widgetLibrary/TableWidget/interface\"\n\nexport interface HeaderProps {\n  labelName: string\n  handleAddOption: () => void\n}\n\nexport interface ColumnItemProps\n  extends Omit<ColumnItemShape, \"disabled\" | \"cell\"> {\n  index: number\n}\n\nexport interface DragIconAndLabelProps {\n  index: number\n  label?: string\n  visible?: boolean\n  custom?: boolean\n}\n\nexport interface ColumnListSetterProps extends BaseSetter {\n  value: ColumnItemShape[]\n  childrenSetter?: PanelFieldConfig[]\n}\n\nexport interface DragItem {\n  index: number\n  id: string\n  type: string\n}\n\nexport interface ActionMenuProps {\n  index: number\n  handleCloseMode: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\nimport { publicPaddingStyle } from \"@/page/App/components/InspectPanel/style\"\n\nexport const optionListHeaderStyle = css`\n  width: 100%;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  height: 40px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  font-weight: 500;\n  box-sizing: border-box;\n  ${publicPaddingStyle}\n`\n\nexport const headerActionButtonStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: ${globalColor(`--${illaPrefix}-techPurple-03`)};\n  cursor: pointer;\n  font-weight: 400;\n  margin: 0 8px;\n`\n\nexport const columnLabelStyle = css`\n  display: flex;\n  justify-content: space-between;\n  margin: 0 16px 16px;\n  font-size: 14px;\n  font-weight: 600;\n  line-height: 22px;\n`\n\nexport const addIconStyle = css`\n  margin-right: 4px;\n  font-size: 12px;\n`\n\nexport const ListStyle = css`\n  border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  margin: 0 16px;\n  border-radius: 8px;\n  overflow: hidden;\n`\n\nexport const optionListItemStyle = css`\n  display: flex;\n  justify-content: space-between;\n  padding-right: 16px;\n  height: 40px;\n  align-items: center;\n  cursor: pointer;\n\n  &:hover {\n    .movableIconWrapper {\n      opacity: 1;\n    }\n  }\n`\n\nexport const dragItemStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n`\n\nexport const labelNameAndIconStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n`\n\nexport const labelNameWrapperStyle = css`\n  font-size: 14px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const movableIconWrapperStyle = css`\n  opacity: 0;\n  cursor: grab;\n  display: flex;\n  align-items: center;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const emptyEmptyBodyStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 100%;\n  height: 40px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const iconAreaStyle = css`\n  display: flex;\n  flex-direction: row;\n  gap: 16px;\n`\n\nexport const baseIconStyle = css`\n  font-size: 16px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  cursor: pointer;\n  :hover {\n    color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  }\n`\n\nexport const eyeIconStyle = css`\n  visibility: hidden;\n  ${baseIconStyle}\n`\n\nexport const removeNativeStyle = css`\n  list-style: none;\n  padding: 0;\n  margin: 0;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter/utils/generateNewColumns.ts",
    "content": "import { v4 } from \"uuid\"\nimport {\n  ColumnItemShape,\n  defaultColumnItem,\n} from \"@/widgetLibrary/TableWidget/interface\"\n\nexport const generateColumnItemId = () => `column-${v4()}`\n\nexport const generateNewColumnItem = (number: number): ColumnItemShape => {\n  const id = generateColumnItemId()\n  return {\n    ...defaultColumnItem,\n    custom: true,\n    header: `Column ${number}`,\n    id,\n    accessorKey: id,\n    columnIndex: number - 1,\n  } as ColumnItemShape\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/columnTypeSelectSetter.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport BaseSelectSetter from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/baseSelect\"\nimport { BaseSelectSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/interface\"\nimport {\n  generateNewButtonCellContent,\n  generateNewIconCellContent,\n} from \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/utils/generateNewColumns\"\nimport {\n  ColumnType,\n  ColumnTypeOption,\n  Columns,\n} from \"@/widgetLibrary/TableWidget/interface\"\n\ninterface ColumnTypeSelectSetterProps extends BaseSelectSetterProps {}\n\nconst ColumnTypeSelectSetter: FC<ColumnTypeSelectSetterProps> = (props) => {\n  const { parentAttrName, handleUpdateMultiAttrDSL } = props\n\n  const handleUpdateDsl = useCallback(\n    (attrName: string, value: ColumnType) => {\n      let columnProps: Record<string, unknown> = {}\n      switch (value) {\n        case Columns.Date:\n          columnProps[`${parentAttrName}.format`] = \"YYYY-MM-DD\"\n          break\n        case Columns.DateTime:\n          columnProps[`${parentAttrName}.format`] = \"YYYY-MM-DD HH:mm:ss\"\n          break\n        case Columns.Time:\n          columnProps[`${parentAttrName}.format`] = \"HH:mm:ss\"\n          break\n        case Columns.ButtonGroup:\n          columnProps[`${parentAttrName}.buttonGroupContent`] = [\n            generateNewButtonCellContent(1),\n            generateNewButtonCellContent(2),\n          ]\n          break\n        case Columns.IconGroup:\n          columnProps[`${parentAttrName}.iconGroupContent`] = [\n            generateNewIconCellContent(1),\n          ]\n          break\n      }\n      handleUpdateMultiAttrDSL?.({\n        ...columnProps,\n        [attrName]: value,\n      })\n    },\n    [handleUpdateMultiAttrDSL, parentAttrName],\n  )\n\n  return (\n    <BaseSelectSetter\n      {...props}\n      handleUpdateDsl={handleUpdateDsl}\n      options={ColumnTypeOption}\n    />\n  )\n}\n\nColumnTypeSelectSetter.displayName = \"ColumnTypeSelectSetter\"\n\nexport default ColumnTypeSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/columsSelectSetter.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { ColumnItemShape } from \"@/widgetLibrary/TableWidget/interface\"\nimport SearchSelectSetter from \"../SelectSetter/searchSelect\"\nimport { ColumnsSelectSetterProps, SelectOptions } from \"./interface\"\n\nconst ColumnsSelectSetter: FC<ColumnsSelectSetterProps> = (props) => {\n  const {\n    widgetDisplayName,\n    attrName,\n    isSetterSingleRow,\n    widgetOrAction,\n    widgetType,\n    expectedType,\n    allowClear,\n    value,\n    handleUpdateMultiAttrDSL,\n    ...otherProps\n  } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const options = useMemo(() => {\n    const columns = get(targetComponentProps, \"columns\", [])\n    const opt: SelectOptions = [\n      {\n        value: \"default\",\n        label: \"—\",\n      },\n    ]\n    columns.forEach((item: ColumnItemShape) => {\n      opt.push({\n        value: item.accessorKey ?? \"\",\n        label: item.header ?? \"\",\n      })\n    })\n    return opt\n  }, [targetComponentProps])\n\n  const handleUpdateDsl = useCallback(\n    (attrName: string, newValue: any) => {\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: newValue,\n      })\n    },\n    [handleUpdateMultiAttrDSL],\n  )\n\n  return (\n    <SearchSelectSetter\n      {...otherProps}\n      isSetterSingleRow={isSetterSingleRow}\n      options={options}\n      attrName={attrName}\n      handleUpdateDsl={handleUpdateDsl}\n      value={value}\n      expectedType={expectedType}\n      widgetDisplayName={widgetDisplayName}\n      widgetOrAction={widgetOrAction}\n      widgetType={widgetType}\n      allowClear={allowClear}\n    />\n  )\n}\n\nColumnsSelectSetter.displayName = \"ColumnsSelectSetter\"\n\nexport default ColumnsSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/interface.ts",
    "content": "import { BaseInputSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/interface\"\nimport { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelLabelProps } from \"@/page/App/components/InspectPanel/components/Label/interface\"\n\nexport type SelectOptions = (\n  | string\n  | number\n  | {\n      label: string\n      value: string | number\n    }\n)[]\n\nexport interface ColumnsSelectSetterProps extends BaseSetter, PanelLabelProps {\n  allowClear?: boolean\n  value: string\n}\nexport interface TableDataSourceSetterProps\n  extends BaseSetter,\n    PanelLabelProps {\n  allowClear?: boolean\n}\n\nexport interface TableDataInputSetterProps extends BaseInputSetterProps {}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/tableDataSourceSelectSetter.tsx",
    "content": "import { get, isEqual } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport BaseDynamicSelect from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/baseDynamicSelect\"\nimport { TableDataSourceSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/interface\"\nimport { publicPaddingStyle } from \"@/page/App/components/InspectPanel/style\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport { searchDSLByDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport {\n  getExecutionError,\n  getExecutionResult,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { evaluateDynamicString } from \"@/utils/evaluateDynamicString\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { ColumnItemShape } from \"@/widgetLibrary/TableWidget/interface\"\nimport {\n  tansDataFromOld,\n  tansTableDataToColumns,\n} from \"@/widgetLibrary/TableWidget/utils\"\n\nconst TableDataSourceSelectSetter: FC<TableDataSourceSetterProps> = (props) => {\n  const {\n    widgetDisplayName,\n    labelName,\n    labelDesc,\n    detailedDescription,\n    handleUpdateDsl,\n    handleUpdateMultiAttrDSL,\n  } = props\n\n  const actions = useSelector(getActionList)\n  const executionResult = useSelector(getExecutionResult)\n\n  const executionErrors = useSelector(getExecutionError)\n  const isError = useMemo(() => {\n    return (\n      (executionErrors[`${widgetDisplayName}.dataSource`] ?? [])?.length > 0\n    )\n  }, [executionErrors, widgetDisplayName])\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      return searchDSLByDisplayName(widgetDisplayName, rootState)?.props || {}\n    },\n  )\n\n  const columns = useMemo(() => {\n    return get(targetComponentProps, \"columns\", []) as ColumnItemShape[]\n  }, [targetComponentProps])\n\n  const customColumns = useMemo(() => {\n    return columns.filter((item) => item.custom)\n  }, [columns])\n\n  const isDynamic = useMemo(() => {\n    const dataSourceMode = get(targetComponentProps, \"dataSourceMode\", \"select\")\n    return dataSourceMode === \"dynamic\"\n  }, [targetComponentProps])\n\n  const finalValue = useMemo(() => {\n    if (isDynamic) {\n      return get(targetComponentProps, \"dataSourceJS\", [])\n    } else {\n      return get(targetComponentProps, \"dataSource\", [])\n    }\n  }, [isDynamic, targetComponentProps])\n\n  useEffect(() => {\n    const oldKeyOrder: string[] = []\n    const oldKeyMap: Record<string, ColumnItemShape> = {}\n    columns?.forEach((item) => {\n      oldKeyMap[item.accessorKey] = item\n      oldKeyOrder.push(item.accessorKey)\n    })\n    let data\n    try {\n      data = evaluateDynamicString(\"\", finalValue, executionResult)\n    } catch (e) {}\n    if (!Array.isArray(data)) return\n    const newColumns = tansDataFromOld(data, oldKeyMap, oldKeyOrder)\n    if (newColumns?.length && !isEqual(newColumns, columns)) {\n      handleUpdateMultiAttrDSL?.({ columns: newColumns })\n    }\n  }, [columns, executionResult, finalValue, handleUpdateMultiAttrDSL])\n\n  const selectedOptions = useMemo(() => {\n    return actions.map((action) => ({\n      label: action.displayName,\n      value: `{{${action.displayName}.data}}`,\n    }))\n  }, [actions])\n\n  const handleClickFxButton = useCallback(() => {\n    const isInOption = selectedOptions.some(\n      (option) => option.value === finalValue,\n    )\n    if (isDynamic) {\n      handleUpdateDsl(\"dataSourceMode\", \"select\")\n      if (!isInOption) {\n        handleUpdateDsl(\"dataSource\", \"\")\n      } else {\n        handleUpdateDsl(\"dataSource\", finalValue)\n      }\n    } else {\n      handleUpdateDsl(\"dataSourceMode\", \"dynamic\")\n      if (isInOption) {\n        handleUpdateDsl(\"dataSourceJS\", finalValue)\n      }\n    }\n  }, [handleUpdateDsl, isDynamic, selectedOptions, finalValue])\n\n  const getNewColumn = useCallback(\n    (value: string) => {\n      const data = evaluateDynamicString(\"\", value, executionResult)\n      if (Array.isArray(data)) {\n        let newColumns = tansTableDataToColumns(data)\n        if (newColumns?.length) {\n          return newColumns.concat(\n            customColumns.map((item: ColumnItemShape, index) => {\n              return { ...item, columnIndex: newColumns.length + index }\n            }),\n          )\n        }\n      }\n    },\n    [customColumns, executionResult],\n  )\n\n  const handleChangeInput = useCallback(\n    (value: string) => {\n      const newColumns = getNewColumn(value)\n      if (newColumns) {\n        handleUpdateMultiAttrDSL?.({\n          columns: newColumns,\n          dataSourceJS: value,\n        })\n        return\n      }\n      handleUpdateMultiAttrDSL?.({\n        dataSourceJS: value,\n      })\n    },\n    [getNewColumn, handleUpdateMultiAttrDSL],\n  )\n\n  const handleChangeSelect = useCallback(\n    (value: any) => {\n      const newColumns = getNewColumn(value)\n      if (newColumns) {\n        handleUpdateMultiAttrDSL?.({\n          columns: newColumns,\n          dataSource: value,\n        })\n        return\n      }\n      handleUpdateMultiAttrDSL?.({\n        dataSource: value,\n      })\n    },\n    [getNewColumn, handleUpdateMultiAttrDSL],\n  )\n\n  return (\n    <div css={publicPaddingStyle}>\n      <BaseDynamicSelect\n        {...props}\n        isDynamic={isDynamic}\n        onClickFxButton={handleClickFxButton}\n        selectPlaceholder=\"Select a query or transformer\"\n        inputPlaceholder=\"{{}}\"\n        onChangeInput={handleChangeInput}\n        path={`${widgetDisplayName}.dataSourceJS`}\n        options={selectedOptions}\n        expectedType={VALIDATION_TYPES.ARRAY}\n        onChangeSelect={handleChangeSelect}\n        value={finalValue}\n        labelName={labelName}\n        labelDesc={labelDesc}\n        detailedDescription={detailedDescription}\n        isError={isError}\n      />\n    </div>\n  )\n}\n\nTableDataSourceSelectSetter.displayName = \"TableDataSourceSelectSetter\"\nexport default TableDataSourceSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TableSetter/tableMappedValueInputSetter.tsx",
    "content": "import { get, toPath } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { BaseInputSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/interface\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { JSToString, stringToJS } from \"@/utils/evaluateDynamicString/utils\"\nimport BaseInput from \"../InputSetter/BaseInput\"\n\nconst realInputValue = (\n  attrValue: string | undefined,\n  dataPath: string,\n  widgetDisplayName: string,\n) => {\n  if (attrValue === \"\" || attrValue == undefined) return \"\"\n  const value = `${attrValue.substring(\n    `{{${widgetDisplayName}.${dataPath}.map((currentRow) => ( `.length,\n    attrValue.length - 4,\n  )}`\n  return attrValue.includes(\"currentRow\") ? JSToString(value) : attrValue\n}\n\nconst getNeedComputedValue = (\n  value: string,\n  dataPath: string,\n  widgetDisplayName: string,\n) => {\n  const stringToCanEvaluate = stringToJS(value)\n  if (stringToCanEvaluate === \"\") {\n    return stringToCanEvaluate\n  }\n  return `{{${widgetDisplayName}.${dataPath}.map((currentRow) => ( ${stringToCanEvaluate}))}}`\n}\n\nconst TableMappedValueInputSetter: FC<BaseInputSetterProps> = (props) => {\n  const { parentAttrName, handleUpdateDsl, value, widgetDisplayName } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const isDynamic = useMemo(() => {\n    const dataSourceMode = get(targetComponentProps, \"dataSourceMode\", \"select\")\n    return dataSourceMode === \"dynamic\"\n  }, [targetComponentProps])\n\n  const fromCurrentRow = useMemo(() => {\n    return get(\n      targetComponentProps,\n      `${parentAttrName}.fromCurrentRow`,\n      {},\n    ) as Record<string, boolean>\n  }, [targetComponentProps, parentAttrName])\n\n  const dataPath = useMemo(() => {\n    if (isDynamic) {\n      return \"dataSourceJS\"\n    }\n    return \"dataSource\"\n  }, [isDynamic])\n\n  const handleValueChange = useCallback(\n    (attrName: string, value: string) => {\n      const isFromCurrentRow = value.includes(\"currentRow\")\n      const output = isFromCurrentRow\n        ? getNeedComputedValue(value, dataPath, widgetDisplayName)\n        : value\n      const paths = toPath(attrName)\n      const name = paths.at(-1) as string\n      handleUpdateDsl(attrName, output)\n      handleUpdateDsl(`${parentAttrName}.fromCurrentRow`, {\n        ...fromCurrentRow,\n        [name]: isFromCurrentRow,\n      })\n    },\n    [\n      dataPath,\n      fromCurrentRow,\n      handleUpdateDsl,\n      parentAttrName,\n      widgetDisplayName,\n    ],\n  )\n\n  const wrappedCodeFunc = useCallback(\n    (code: string) => {\n      const fromCurrentRow = code.includes(\"currentRow\")\n      const output = fromCurrentRow\n        ? getNeedComputedValue(code, dataPath, widgetDisplayName)\n        : code\n      return output\n    },\n    [dataPath, widgetDisplayName],\n  )\n\n  return (\n    <BaseInput\n      {...props}\n      value={realInputValue(value, dataPath, widgetDisplayName)}\n      wrappedCodeFunc={wrappedCodeFunc}\n      handleUpdateDsl={handleValueChange}\n    />\n  )\n}\n\nTableMappedValueInputSetter.displayName = \"TableMappedValueInputSetter\"\nexport default TableMappedValueInputSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TabsSetter/DefaultTabKeySetter/index.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { ViewItemShape } from \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter/interface\"\nimport BaseInput from \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/BaseInput\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { TabsDefaultKeySetterProps } from \"./interface\"\n\nconst TabsDefaultKeySetter: FC<TabsDefaultKeySetterProps> = (props) => {\n  const { handleUpdateMultiAttrDSL, widgetDisplayName } = props\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const tabList = get(targetComponentProps, \"tabList\", []) as ViewItemShape[]\n\n  const handleUpdateDefaultTab = useCallback(\n    (attrPath: string, value: string) => {\n      const defaultTabIndex = tabList.findIndex((view) => view.key === value)\n      let currentIndex\n      if (defaultTabIndex > -1) {\n        currentIndex = defaultTabIndex\n      }\n      handleUpdateMultiAttrDSL?.({\n        [attrPath]: value,\n        currentIndex,\n      })\n    },\n    [handleUpdateMultiAttrDSL, tabList],\n  )\n\n  return <BaseInput {...props} handleUpdateDsl={handleUpdateDefaultTab} />\n}\n\nTabsDefaultKeySetter.displayName = \"TabsDefaultKeySetter\"\nexport default TabsDefaultKeySetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TabsSetter/DefaultTabKeySetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface TabsDefaultKeySetterProps extends BaseSetter {\n  value?: string\n  expectedType?: VALIDATION_TYPES\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TabsSetter/TabListSetter/index.tsx",
    "content": "import { get, isString } from \"lodash-es\"\nimport { FC, memo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { v4 } from \"uuid\"\nimport { Column } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Column\"\nimport { ColumnContainer } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/ColumnContainer\"\nimport { ColumnEmpty } from \"@/page/App/components/InspectPanel/PanelSetters/DragMoveComponent/Empty\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { ViewSetterProps } from \"./interface\"\n\nconst TabListSetter: FC<ViewSetterProps> = memo((props: ViewSetterProps) => {\n  const {\n    value,\n    attrName,\n    widgetDisplayName,\n    childrenSetter,\n    handleUpdateMultiAttrDSL,\n  } = props\n\n  const execResult = useSelector(getExecutionResult)\n  const executeValue = get(execResult, `${widgetDisplayName}.${attrName}`, [])\n\n  return (\n    <ColumnContainer\n      attrName={attrName}\n      value={value}\n      handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n      columnNum={value.length}\n      items={value.map((item) => item.id)}\n      onClickNew={() => {\n        const newItem = {\n          id: `views-${v4()}`,\n          key: `views-${v4()}`,\n          label: `Tab ${value.length + 1}`,\n        }\n        handleUpdateMultiAttrDSL?.({\n          [attrName]: [...value, newItem],\n        })\n      }}\n    >\n      {value.length > 0 ? (\n        value.map((item, index) => {\n          return (\n            <Column\n              onCopy={() => {\n                const newItem = {\n                  id: `views-${v4()}`,\n                  key: `views-${v4()}`,\n                  label: value[index].label,\n                  disabled: value[index].disabled,\n                }\n                const updatedArray = [...value, newItem]\n                handleUpdateMultiAttrDSL?.({\n                  [attrName]: updatedArray,\n                })\n              }}\n              onDelete={(id) => {\n                const newV = value.filter((item) => item.id !== id)\n                handleUpdateMultiAttrDSL?.({\n                  [attrName]: newV,\n                  currentIndex: 0,\n                  currentKey: newV[0]?.key,\n                })\n              }}\n              showCopy\n              showDelete\n              key={item.id}\n              id={item.id}\n              label={\n                isString(get(executeValue, `${index}.label`))\n                  ? get(executeValue, `${index}.label`)\n                  : JSON.stringify(get(executeValue, `${index}.label`))\n              }\n              widgetDisplayName={widgetDisplayName}\n              childrenSetter={childrenSetter}\n              attrPath={`${attrName}.${index}`}\n            />\n          )\n        })\n      ) : (\n        <ColumnEmpty />\n      )}\n    </ColumnContainer>\n  )\n})\n\nTabListSetter.displayName = \"TabListSetter\"\nexport default TabListSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TabsSetter/TabListSetter/interface.ts",
    "content": "import { BaseSetter } from \"@/page/App/components/InspectPanel/PanelSetters/interface\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface ViewItemShape {\n  id: string\n  key: string\n  label: string\n  disabled?: string\n  hidden?: string\n}\n\nexport interface ViewSetterProps extends BaseSetter {\n  value: ViewItemShape[]\n  childrenSetter?: PanelFieldConfig[]\n}\n\nexport interface DragIconAndLabelProps {\n  index: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TabsSetter/TabsContainerSelectSetter/index.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { BaseSelectSetterProps } from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/interface\"\nimport SearchSelectSetter from \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/searchSelect\"\nimport DynamicSwitchSetter from \"@/page/App/components/InspectPanel/PanelSetters/SwitchSetter/dynamicSwitch\"\nimport { getAllContainerWidget } from \"@/redux/currentApp/components/componentsSelector\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { containerStyle, selectContainerStyle } from \"./style\"\n\nconst TabsContainerSelectSetter: FC<BaseSelectSetterProps> = (props) => {\n  const {\n    handleUpdateMultiAttrDSL,\n    handleUpdateOtherMultiAttrDSL,\n    widgetDisplayName,\n    handleUpdateDsl,\n  } = props\n  const containers = useSelector(getAllContainerWidget)\n  const { t } = useTranslation()\n\n  const targetComponentProps = useSelector<RootState, Record<string, any>>(\n    (rootState) => {\n      const executionTree = getExecutionResult(rootState)\n      return get(executionTree, widgetDisplayName, {})\n    },\n  )\n\n  const linkWidgetDisplayName = get(\n    targetComponentProps,\n    \"linkWidgetDisplayName\",\n    \"\",\n  ) as string\n\n  const isLinkToContainer = get(\n    targetComponentProps,\n    \"navigateContainer\",\n    false,\n  )\n\n  const selectedOptions = useMemo(() => {\n    if (!containers) return\n    return Object.keys(containers)\n  }, [containers])\n\n  const handleUpdateViewList = useCallback(\n    (attrName: string, targetDisplayName: string) => {\n      try {\n        const newList = get(containers, `${targetDisplayName}.viewList`, {})\n        const currentIndex = get(\n          containers,\n          `${targetDisplayName}.currentIndex`,\n          0,\n        )\n        const currentKey = get(\n          containers,\n          `${targetDisplayName}.currentKey`,\n          \"\",\n        )\n        handleUpdateMultiAttrDSL?.({\n          viewList: newList,\n          currentIndex,\n          currentKey,\n          [attrName]: targetDisplayName,\n        })\n        const targetLinkedDisplayNames = get(\n          containers,\n          `${targetDisplayName}.linkWidgetDisplayName`,\n          [],\n        )\n        const oldLinkedDisplayNames = get(\n          containers,\n          `${linkWidgetDisplayName}.linkWidgetDisplayName`,\n          [],\n        )\n        // del old link\n        if (oldLinkedDisplayNames && Array.isArray(oldLinkedDisplayNames)) {\n          const needUpdateDisplayNames = oldLinkedDisplayNames.filter(\n            (name) => name !== widgetDisplayName,\n          )\n          handleUpdateOtherMultiAttrDSL?.(linkWidgetDisplayName, {\n            linkWidgetDisplayName: needUpdateDisplayNames,\n          })\n        }\n        // ad new link\n        if (\n          Array.isArray(targetLinkedDisplayNames) &&\n          !targetLinkedDisplayNames.includes(widgetDisplayName)\n        ) {\n          handleUpdateOtherMultiAttrDSL?.(targetDisplayName, {\n            linkWidgetDisplayName: [\n              ...targetLinkedDisplayNames,\n              widgetDisplayName,\n            ],\n          })\n        } else {\n          handleUpdateOtherMultiAttrDSL?.(targetDisplayName, {\n            linkWidgetDisplayName: [widgetDisplayName],\n          })\n        }\n      } catch (e) {}\n      handleUpdateMultiAttrDSL?.({\n        [attrName]: targetDisplayName,\n      })\n    },\n    [\n      containers,\n      handleUpdateMultiAttrDSL,\n      handleUpdateOtherMultiAttrDSL,\n      linkWidgetDisplayName,\n      widgetDisplayName,\n    ],\n  )\n\n  const handleUpdateLinkContainer = useCallback(\n    (attrName: string, v: unknown) => {\n      if (!v && linkWidgetDisplayName) {\n        handleUpdateMultiAttrDSL?.({\n          linkWidgetDisplayName: undefined,\n        })\n        const targetLinkedDisplayNames = get(\n          containers,\n          `${linkWidgetDisplayName}.linkWidgetDisplayName`,\n          [],\n        )\n        if (Array.isArray(targetLinkedDisplayNames)) {\n          handleUpdateOtherMultiAttrDSL?.(linkWidgetDisplayName, {\n            linkWidgetDisplayName: targetLinkedDisplayNames.filter(\n              (item) => item !== widgetDisplayName,\n            ),\n          })\n        }\n      }\n      handleUpdateDsl(attrName, v)\n    },\n    [\n      containers,\n      handleUpdateDsl,\n      handleUpdateMultiAttrDSL,\n      handleUpdateOtherMultiAttrDSL,\n      linkWidgetDisplayName,\n      widgetDisplayName,\n    ],\n  )\n\n  return (\n    <div css={containerStyle}>\n      <DynamicSwitchSetter\n        {...props}\n        labelName={t(\"editor.inspect.setter_label.link_to_container\")}\n        value={isLinkToContainer}\n        openDynamic\n        attrName=\"navigateContainer\"\n        expectedType={VALIDATION_TYPES.BOOLEAN}\n        handleUpdateDsl={handleUpdateLinkContainer}\n      />\n      {isLinkToContainer && (\n        <div css={selectContainerStyle}>\n          <SearchSelectSetter\n            {...props}\n            options={selectedOptions}\n            handleUpdateDsl={handleUpdateViewList}\n          />\n        </div>\n      )}\n    </div>\n  )\n}\n\nTabsContainerSelectSetter.displayName = \"TabsContainerSelectSetter\"\n\nexport default TabsContainerSelectSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/TabsSetter/TabsContainerSelectSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n`\nexport const selectContainerStyle = css`\n  width: 100%;\n  padding: 8px 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/index.tsx",
    "content": "import { lazy } from \"react\"\n\nconst DeprecatedSetterTypeMapSetter = {\n  COLUMN_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/ColumnSetter\"\n      ),\n  ),\n  COLUMN_TYPE_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/columnTypeSelectSetter\"\n      ),\n  ),\n  COLUMNS_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/columsSelectSetter\"\n      ),\n  ),\n  TABLE_MAPPED_VALUE_INPUT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/tableMappedValueInputSetter\"\n      ),\n  ),\n  TABLE_DATASOURCE_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/tableDataSourceSelectSetter\"\n      ),\n  ),\n  CELL_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter\"\n      ),\n  ),\n}\n\nconst SetterTypeMapSetter = {\n  INPUT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/BaseInput\"\n      ),\n  ),\n  SCRIPT_INPUT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/ScriptInput\"\n      ),\n  ),\n  ICON_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/IconSetter/IconSelector\"\n      ),\n  ),\n  RADIO_GROUP_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/RadioGroupSetter/baseRadioGroup\"\n      ),\n  ),\n  SWITCH_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SwitchSetter/baseSwitch\"\n      ),\n  ),\n  SEARCH_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/searchSelect\"\n      ),\n  ),\n  DYNAMIC_SWITCH_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SwitchSetter/dynamicSwitch\"\n      ),\n  ),\n  BASE_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/baseSelect\"\n      ),\n  ),\n  OPTION_LIST_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/OptionListSetter\"\n      ),\n  ),\n  STEPS_LIST_SETTER: lazy(\n    () =>\n      import(\"@/page/App/components/InspectPanel/PanelSetters/StepsListSetter\"),\n  ),\n  CAROUSEL_LIST_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/CarouselListSetter\"\n      ),\n  ),\n  DATA_GRID_COLUMNS_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnsSelectSetter\"\n      ),\n  ),\n  DATA_GRID_COLUMN_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter\"\n      ),\n  ),\n  DATA_GRID_COLUMN_BUTTON_GROUP_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnButtonGroupSetter\"\n      ),\n  ),\n  DATA_GRID_MAPPED_INPUT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnMappedInput\"\n      ),\n  ),\n  DATA_GRID_COLUMN_SWITCH_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSwitchSetter\"\n      ),\n  ),\n  DATA_GRID_TYPE_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnTypeSelectSetter\"\n      ),\n  ),\n  DATA_GRID_MAPPED_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnMappedSelect\"\n      ),\n  ),\n  TABS_LIST_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/TabsSetter/TabListSetter\"\n      ),\n  ),\n  TABS_DEFAULT_KEY_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/TabsSetter/DefaultTabKeySetter\"\n      ),\n  ),\n  TABS_CONTAINER_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/TabsSetter/TabsContainerSelectSetter\"\n      ),\n  ),\n  OPTION_MAPPED_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/MappedOptionSetter\"\n      ),\n  ),\n  EVENT_HANDLER_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/EventHandlerSetter\"\n      ),\n  ),\n  EVENT_TARGET_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventTargetWidgetSelect\"\n      ),\n  ),\n  EVENT_TARGET_ACTION_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventTargetActionSelect\"\n      ),\n  ),\n  EVENT_TARGET_PAGE_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/pageSelect\"\n      ),\n  ),\n  EVENT_TARGET_VIEW_PATH_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventBodyViewSelect\"\n      ),\n  ),\n  OPTION_MAPPED_INPUT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/OptionMappedInput/optionMappedInputSetter\"\n      ),\n  ),\n  EVENT_WIDGET_METHOD_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventWidgetMethodSelect\"\n      ),\n  ),\n  EVENT_ACTION_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventActionTypeSelect\"\n      ),\n  ),\n  CHART_KEYS_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartKeysSelectSetter\"\n      ),\n  ),\n  CHART_KEYS_DYNAMIC_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartKeysDynamicSelectSetter\"\n      ),\n  ),\n  CHART_DATASETS_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter\"\n      ),\n  ),\n  CHART_COLOR_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartColorSelectSetter\"\n      ),\n  ),\n  CHART_TYPE_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartTypeSelectSetter\"\n      ),\n  ),\n  CONTAINER_VIEW_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/ViewsSetter\"\n      ),\n  ),\n  CONTAINER_DEFAULT_VIEW_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/ContainerSetter/defaultViewKeySetter\"\n      ),\n  ),\n  MENU_OPTION_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/MenuSetter/MenuOptionSetter\"\n      ),\n  ),\n  DATA_SOURCE_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/dataSourceSelectSetter\"\n      ),\n  ),\n  HEIGHT_MODE_SELECT: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/heightModeSelect\"\n      ),\n  ),\n  SHADOW_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/ShadowSelect\"\n      ),\n  ),\n  EVENT_TARGET_STATE_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventTargetStateSelect\"\n      ),\n  ),\n  CALENDAR_EVENT_LIST_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/CalendarEventListSetter\"\n      ),\n  ),\n  EVENT_CALENDAR_SELECT: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/eventCalendarSelect\"\n      ),\n  ),\n  DRIVE_WITH_STATUS_SWITCH_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SwitchSetter/driveWithStatusSwitch\"\n      ),\n  ),\n  PADDING_INPUT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/PaddingInput\"\n      ),\n  ),\n  BORDER_SETTER: lazy(\n    () =>\n      import(\"@/page/App/components/InspectPanel/PanelSetters/BorderSetter\"),\n  ),\n  STYLE_CONTAINER_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/StyleContainerSetter\"\n      ),\n  ),\n  COLOR_PICKER_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/ColorPickerSetter\"\n      ),\n  ),\n  MEASURE_CHECK_INPUT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/MeasureCheckInput\"\n      ),\n  ),\n  FILE_MIN_MAX_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/InputSetter/FileMinMaxSetter\"\n      ),\n  ),\n  DRIVE_SOURCE_GROUP_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/DriveSourceGroupSetter\"\n      ),\n  ),\n  ITEM_BORDER_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/ItemBorderSetter\"\n      ),\n  ),\n  LIST_GAP_SETTER: lazy(\n    () =>\n      import(\"@/page/App/components/InspectPanel/PanelSetters/ListGapSetter\"),\n  ),\n  CUSTOM_BG_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/CustomBgSelect\"\n      ),\n  ),\n  MEASURE_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/MeasureSelectSetter\"\n      ),\n  ),\n  DYNAMIC_SELECT_SETTER: lazy(\n    () =>\n      import(\n        \"@/page/App/components/InspectPanel/PanelSetters/SelectSetter/dynamicSelectSetter\"\n      ),\n  ),\n  ...DeprecatedSetterTypeMapSetter,\n}\n\nexport type SetterType = keyof typeof SetterTypeMapSetter\n\nexport const getSetterByType = (type: SetterType) => {\n  return SetterTypeMapSetter[type]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/interface.ts",
    "content": "import { ComponentMapNode } from \"@illa-public/public-types\"\nimport { ReactNode } from \"react\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport interface BaseSetter {\n  className?: string\n  isSetterSingleRow?: boolean\n  value?: unknown\n  attrName: string\n  parentAttrName?: string\n  panelConfig?: Record<string, any>\n  handleUpdateDsl: (attrPath: string, value: any) => void\n  handleUpdateMultiAttrDSL?: (updateSlice: Record<string, any>) => void\n  handleUpdateOtherMultiAttrDSL?: (\n    displayName: string,\n    updateSlice: Record<string, unknown>,\n  ) => void\n  handleUpdateExecutionResult?: (\n    displayName: string,\n    updateSlice: Record<string, unknown>,\n  ) => void\n  expectedType?: VALIDATION_TYPES\n  attrNames?: string[]\n  widgetDisplayName: string\n  widgetType: string\n  widgetOrAction: \"ACTION\" | \"WIDGET\"\n  defaultValue?: any\n  componentNode?: ComponentMapNode\n  detailedDescription?: string\n  labelName?: string\n  labelDesc?: string\n  isGuideMode?: boolean\n  icon?: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/PanelSetters/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const fixedWidthStyle = css`\n  width: 184px;\n`\n\nexport const dynamicWidthStyle = css`\n  width: auto;\n  align-self: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/ActionMenu/index.tsx",
    "content": "import { FC, useCallback, useContext } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch } from \"react-redux\"\nimport { DropList, DropListItem } from \"@illa-design/react\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { ShortCutContext } from \"@/utils/shortcut/shortcutProvider\"\nimport { widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\nimport { PanelHeaderActionProps } from \"./interface\"\n\nexport const ActionMenu: FC<PanelHeaderActionProps> = (props) => {\n  const { widgetDisplayName, componentType } = props\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n\n  const shortcut = useContext(ShortCutContext)\n\n  const handleClickDropListItem = useCallback(() => {\n    const defaults = widgetBuilder(componentType)?.config?.defaults\n    if (!widgetDisplayName) return\n    let defaultProps: unknown = defaults\n    if (typeof defaults === \"function\") {\n      defaultProps = defaults()\n    }\n    if (typeof defaultProps !== \"object\") return\n\n    dispatch(\n      componentsActions.updateComponentPropsReducer({\n        displayName: widgetDisplayName,\n        updateSlice: (defaultProps as Record<string, unknown>) || {},\n      }),\n    )\n  }, [componentType, dispatch, widgetDisplayName])\n\n  return (\n    <DropList w=\"184px\">\n      <DropListItem\n        value=\"reset\"\n        key=\"reset\"\n        title={t(\"editor.inspect.header.action_menu.reset_state\")}\n        onClick={handleClickDropListItem}\n      />\n      <DropListItem\n        key=\"delete\"\n        value=\"delete\"\n        title={t(\"editor.inspect.header.action_menu.delete\")}\n        deleted\n        onClick={() => {\n          shortcut.showDeleteDialog([widgetDisplayName], \"widget\", {\n            source: \"left_delete\",\n          })\n        }}\n      />\n    </DropList>\n  )\n}\n\nActionMenu.displayName = \"ActionMenu\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/ActionMenu/interface.ts",
    "content": "export interface PanelHeaderActionProps {\n  widgetDisplayName: string\n  componentType: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/EmptySelected/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Empty } from \"@illa-design/react\"\nimport NoComponentSelected from \"@/assets/no-component-selected-icon.svg?react\"\nimport {\n  unselectedTipIconStyle,\n  unselectedTipTextStyle,\n  unselectedTipWrapperStyle,\n} from \"./style\"\n\nexport const EmptySelected: FC = () => {\n  const { t } = useTranslation()\n  return (\n    <div css={unselectedTipWrapperStyle}>\n      <Empty\n        icon={\n          <div css={unselectedTipIconStyle}>\n            <NoComponentSelected />\n          </div>\n        }\n        description={\n          <>\n            <div css={unselectedTipTextStyle}>\n              {t(\"editor.inspect.unselected_tip1\")}\n            </div>\n            <div css={unselectedTipTextStyle}>\n              {t(\"editor.inspect.unselected_tip2\")}\n            </div>\n          </>\n        }\n      />\n    </div>\n  )\n}\n\nEmptySelected.displayName = \"EmptySelected\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/EmptySelected/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const unselectedTipWrapperStyle = css`\n  width: 100%;\n  height: 319px;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n`\n\nexport const unselectedTipIconStyle = css`\n  font-size: 30px;\n`\n\nexport const unselectedTipTextStyle = css`\n  margin-top: 4px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/FieldAndLabel/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getGuideInfo } from \"@/redux/guide/guideSelector\"\nimport RenderGuideModePanelSetter from \"../GuideModePanelSetter\"\nimport RenderPanelSetter from \"../PanelSetter\"\nimport { RenderFieldAndLabelProps } from \"./interface\"\n\nconst RenderFieldAndLabel: FC<RenderFieldAndLabelProps> = (props) => {\n  const { config, displayName, parentAttrName } = props\n\n  const guideInfo = useSelector(getGuideInfo) ?? {\n    isOpen: false,\n    currentStep: 0,\n  }\n\n  if (guideInfo.isOpen) {\n    return (\n      <RenderGuideModePanelSetter\n        config={config}\n        displayName={displayName}\n        parentAttrName={parentAttrName}\n        currentStep={guideInfo.currentStep}\n      />\n    )\n  }\n\n  return (\n    <RenderPanelSetter\n      config={config}\n      displayName={displayName}\n      parentAttrName={parentAttrName}\n    />\n  )\n}\n\nRenderFieldAndLabel.displayName = \"RenderFieldAndLabel\"\n\nexport default RenderFieldAndLabel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/FieldAndLabel/interface.ts",
    "content": "import { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { Guide } from \"@/redux/guide/guideState\"\n\nexport interface RenderFieldAndLabelProps {\n  config: PanelFieldConfig\n  displayName: string\n  parentAttrName: string\n  guideInfo?: Guide\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/FieldFactory/index.tsx",
    "content": "import { FC } from \"react\"\nimport {\n  PanelConfig,\n  PanelFieldConfig,\n  PanelFieldGroupConfig,\n} from \"@/page/App/components/InspectPanel/interface\"\nimport { canRenderField } from \"@/page/App/components/InspectPanel/utils/fieldFactory\"\nimport RenderFieldAndLabel from \"../FieldAndLabel\"\nimport RenderPanelBar from \"../Panelbar\"\nimport { FieldFactoryProps } from \"./interface\"\n\nconst FieldFactory: FC<FieldFactoryProps> = (props) => {\n  const { panelConfig, displayName, widgetProps } = props\n\n  if (!displayName || !panelConfig || !panelConfig.length) return null\n  return (\n    <>\n      {panelConfig.map((item: PanelConfig) => {\n        const canRender = canRenderField(item as PanelFieldConfig, widgetProps)\n\n        if (!canRender) return null\n        const { id } = item as PanelFieldGroupConfig\n\n        const key = `${id}-${displayName}`\n\n        if ((item as PanelFieldGroupConfig).groupName) {\n          return (\n            <RenderPanelBar\n              key={key}\n              config={item as PanelFieldGroupConfig}\n              displayName={displayName}\n              widgetProps={widgetProps}\n            />\n          )\n        } else if ((item as PanelFieldConfig).setterType) {\n          return (\n            <RenderFieldAndLabel\n              key={key}\n              config={item as PanelFieldConfig}\n              displayName={displayName}\n              parentAttrName=\"\"\n            />\n          )\n        }\n\n        return null\n      })}\n    </>\n  )\n}\n\nFieldFactory.displayName = \"FieldFactory\"\n\nexport default FieldFactory\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/FieldFactory/interface.ts",
    "content": "import { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface FieldFactoryProps {\n  panelConfig: PanelConfig[]\n  displayName: string\n  widgetProps: Record<string, any>\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/GuideModePanelSetter/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Trigger } from \"@illa-design/react\"\nimport { GuidePoint } from \"@/components/Guide/GuidePoint\"\nimport { GuidePopover } from \"@/components/Guide/GuidePopover\"\nimport { triggerStyle } from \"@/components/Guide/GuidePopover/style\"\nimport { GUIDE_STEP } from \"@/config/guide/config\"\nimport RenderPanelSetter from \"../PanelSetter\"\nimport { RenderGuideModePanelSetterProps } from \"./interface\"\n\nconst RenderGuideModePanelSetter: FC<RenderGuideModePanelSetterProps> = (\n  props,\n) => {\n  const { config, displayName, parentAttrName, currentStep } = props\n  const { id } = config\n  const currentStepInfo = GUIDE_STEP[currentStep]\n  const { hideTrigger, titleKey, descKey, selector, doItForMe } =\n    currentStepInfo\n\n  if (selector === id) {\n    if (hideTrigger) {\n      return (\n        <div key={`${id}-${displayName}`} style={{ position: \"relative\" }}>\n          <GuidePoint />\n          <RenderPanelSetter\n            config={config}\n            displayName={displayName}\n            parentAttrName={parentAttrName}\n          />\n        </div>\n      )\n    }\n    return (\n      <Trigger\n        _css={triggerStyle}\n        key={`${id}-${displayName}`}\n        popupVisible={true}\n        trigger=\"hover\"\n        content={\n          <GuidePopover\n            title={titleKey}\n            description={descKey}\n            onClickDoIt={doItForMe}\n          />\n        }\n        position=\"bottom\"\n        colorScheme=\"techPurple\"\n      >\n        <div style={{ position: \"relative\" }}>\n          <GuidePoint />\n          <RenderPanelSetter\n            config={config}\n            displayName={displayName}\n            parentAttrName={parentAttrName}\n          />\n        </div>\n      </Trigger>\n    )\n  }\n  return (\n    <RenderPanelSetter\n      config={config}\n      displayName={displayName}\n      parentAttrName={parentAttrName}\n    />\n  )\n}\n\nRenderGuideModePanelSetter.displayName = \"RenderGuideModePanelSetter\"\n\nexport default RenderGuideModePanelSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/GuideModePanelSetter/interface.ts",
    "content": "import { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface RenderGuideModePanelSetterProps {\n  config: PanelFieldConfig\n  displayName: string\n  parentAttrName: string\n  currentStep: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/Header/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { getDocLink } from \"@illa-public/public-configs\"\nimport { FC, useCallback, useContext } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { Link } from \"react-router-dom\"\nimport { DocsIcon, Dropdown, MoreIcon } from \"@illa-design/react\"\nimport { EditableText } from \"@/components/EditableText\"\nimport { SelectedPanelContext } from \"@/page/App/components/InspectPanel/context/selectedContext\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ActionMenu } from \"../ActionMenu\"\nimport { panelHeaderIconWrapperStyle, panelHeaderWrapperStyle } from \"./style\"\n\nexport const PanelHeader: FC = () => {\n  const { widgetDisplayName, widgetType } = useContext(SelectedPanelContext)\n  const dispatch = useDispatch()\n  const docLink = getDocLink(\"widget\", widgetType)\n\n  const handleUpdateDisplayNameByBlur = useCallback(\n    (newDisplayName: string) => {\n      dispatch(\n        componentsActions.updateComponentDisplayNameReducer({\n          displayName: widgetDisplayName,\n          newDisplayName,\n        }),\n      )\n    },\n    [dispatch, widgetDisplayName],\n  )\n\n  const onMouseHoverRename = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.HOVER, {\n      element: \"component_rename\",\n      parameter1: widgetType,\n    })\n  }, [widgetType])\n\n  const onMouseClickOnRename = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"component_rename\",\n      parameter1: widgetType,\n    })\n  }, [widgetType])\n\n  const onBlurOnRename = useCallback(\n    (value: string) => {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n        element: \"component_rename\",\n        parameter1: widgetType,\n        parameter3: value.length,\n      })\n    },\n    [widgetType],\n  )\n\n  const onValidateOnRename = useCallback(\n    (result: \"suc\" | \"failed\") => {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.VALIDATE, {\n        element: \"component_rename\",\n        parameter1: widgetType,\n        parameter3: result,\n      })\n    },\n    [widgetType],\n  )\n\n  return (\n    <div css={panelHeaderWrapperStyle}>\n      <EditableText\n        key={widgetDisplayName}\n        displayName={widgetDisplayName}\n        updateDisplayNameByBlur={handleUpdateDisplayNameByBlur}\n        onMouseEnter={onMouseHoverRename}\n        onClick={onMouseClickOnRename}\n        onBlur={onBlurOnRename}\n        onValidate={onValidateOnRename}\n      />\n      <div css={panelHeaderIconWrapperStyle}>\n        {docLink && (\n          <Link to={docLink} target=\"_blank\">\n            <IconHotSpot>\n              <DocsIcon />\n            </IconHotSpot>\n          </Link>\n        )}\n        <Dropdown\n          position=\"bottom-end\"\n          trigger=\"click\"\n          dropList={\n            <ActionMenu\n              widgetDisplayName={widgetDisplayName}\n              componentType={widgetType}\n            />\n          }\n          onVisibleChange={(visible) => {\n            if (visible) {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n                element: \"component_management_left\",\n                parameter1: widgetType,\n              })\n            }\n          }}\n        >\n          <IconHotSpot>\n            <MoreIcon />\n          </IconHotSpot>\n        </Dropdown>\n      </div>\n    </div>\n  )\n}\n\nPanelHeader.displayName = \"PanelHeader\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/Header/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const panelHeaderWrapperStyle = css`\n  display: flex;\n  width: 100%;\n  height: 48px;\n  justify-content: space-between;\n  align-items: center;\n  padding: 0 16px;\n`\n\nexport const panelHeaderIconWrapperStyle = css`\n  margin-left: 16px;\n  cursor: pointer;\n  gap: 8px;\n  display: flex;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/Label/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { Trigger } from \"@illa-design/react\"\nimport { ILLAMarkdown } from \"@/components/ILLAMarkdown\"\nimport { PanelLabelProps } from \"./interface\"\nimport { applyLabelTipsStyle } from \"./style\"\n\nexport const PanelLabel: FC<PanelLabelProps> = memo(\n  (props: PanelLabelProps) => {\n    const { labelDesc, labelName, labelSize = \"medium\" } = props\n\n    return !labelDesc ? (\n      <span css={applyLabelTipsStyle(!!labelDesc, labelSize)}>{labelName}</span>\n    ) : (\n      <Trigger\n        content={<ILLAMarkdown textString={labelDesc} />}\n        trigger=\"hover\"\n        position=\"left\"\n        maxW=\"240px\"\n        disabled={!labelDesc}\n      >\n        <span css={applyLabelTipsStyle(!!labelDesc, labelSize)}>\n          {labelName}\n        </span>\n      </Trigger>\n    )\n  },\n)\n\nPanelLabel.displayName = \"PanelLabel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/Label/interface.ts",
    "content": "export interface PanelLabelProps {\n  labelName?: string\n  labelDesc?: string\n  labelSize?: \"medium\" | \"small\"\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/Label/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nconst getLabelStyleBySize = (size: \"medium\" | \"small\") => {\n  switch (size) {\n    case \"medium\": {\n      return css`\n        font-size: 14px;\n        color: ${getColor(\"grayBlue\", \"02\")};\n      `\n    }\n    case \"small\": {\n      return css`\n        font-size: 12px;\n        color: ${getColor(\"grayBlue\", \"03\")};\n      `\n    }\n  }\n}\n\nexport function applyLabelTipsStyle(\n  hasLabelDesc: boolean,\n  size: \"medium\" | \"small\",\n) {\n  const borderBottomStyle = hasLabelDesc\n    ? css`\n        border-bottom: 1px dashed ${getColor(\"grayBlue\", \"06\")};\n      `\n    : css``\n  return css`\n    height: 22px;\n    line-height: 22px;\n    font-weight: 500;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    ${getLabelStyleBySize(size)}\n    ${borderBottomStyle};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/MultiSelectedPanel/multiSelectedPanel.tsx",
    "content": "import { FC, useContext } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { Button } from \"@illa-design/react\"\nimport { getSelectedComponentDisplayNames } from \"@/redux/config/configSelector\"\nimport { ShortCutContext } from \"@/utils/shortcut/shortcutProvider\"\nimport {\n  formContentItemStyle,\n  formContentStyle,\n  formHeaderStyle,\n  multiSelectedPanelWrapper,\n} from \"./style\"\n\nconst MultiSelectedPanel: FC = () => {\n  const selectedComponents = useSelector(getSelectedComponentDisplayNames)\n  const { t } = useTranslation()\n  const shortcut = useContext(ShortCutContext)\n\n  const handleClickDeleteButton = () => {\n    shortcut.showDeleteDialog(selectedComponents, \"widget\", {\n      source: \"left_multi_delete\",\n    })\n  }\n\n  return (\n    <div css={multiSelectedPanelWrapper}>\n      <div css={formHeaderStyle}>\n        {t(\"editor.inspect.multi_selected_header\", {\n          number: selectedComponents.length,\n        })}\n      </div>\n      <div css={formContentStyle}>\n        {selectedComponents.map((displayName) => {\n          return (\n            <div key={displayName} css={formContentItemStyle}>\n              {displayName}\n            </div>\n          )\n        })}\n      </div>\n      <Button\n        fullWidth\n        size=\"medium\"\n        colorScheme=\"red\"\n        variant=\"light\"\n        onClick={handleClickDeleteButton}\n      >\n        {t(\"editor.component.delete\")}\n      </Button>\n    </div>\n  )\n}\n\nMultiSelectedPanel.displayName = \"MultiSelectedPanel\"\nexport default MultiSelectedPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/MultiSelectedPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const multiSelectedPanelWrapper = css`\n  padding: 0 16px;\n  width: 100%;\n  font-size: 14px;\n  height: calc(100% - 1px);\n  display: flex;\n  flex-direction: column;\n  padding-bottom: 8px;\n`\n\nexport const formHeaderStyle = css`\n  height: 48px;\n  display: flex;\n  align-items: center;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-weight: 600;\n  flex: none;\n`\n\nexport const formContentStyle = css`\n  overflow: auto;\n  width: 100%;\n  margin-bottom: 16px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  padding: 8px 16px;\n  border-radius: 8px;\n`\n\nexport const formContentItemStyle = css`\n  :not(:nth-of-type(1)) {\n    margin-top: 8px;\n  }\n  line-height: 22px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/PanelSetter/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Setter } from \"@/page/App/components/InspectPanel/setter\"\nimport { RenderPanelSetterProps } from \"./interface\"\n\nconst RenderPanelSetter: FC<RenderPanelSetterProps> = (props) => {\n  const { config, displayName, parentAttrName } = props\n  const { id } = config\n  return (\n    <Setter\n      key={`${id}-${displayName}`}\n      {...config}\n      parentAttrName={parentAttrName}\n      displayName={displayName}\n    />\n  )\n}\n\nRenderPanelSetter.displayName = \"RenderPanelSetter\"\n\nexport default RenderPanelSetter\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/PanelSetter/interface.ts",
    "content": "import { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface RenderPanelSetterProps {\n  config: PanelFieldConfig\n  displayName: string\n  parentAttrName: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/Panelbar/index.tsx",
    "content": "import { FC } from \"react\"\nimport { PanelBar } from \"@/components/PanelBar\"\nimport FieldFactory from \"../FieldFactory\"\nimport { RenderPanelBarProps } from \"./interface\"\nimport { ghostEmptyStyle } from \"./style\"\n\nconst RenderPanelBar: FC<RenderPanelBarProps> = (props) => {\n  const { config, displayName, widgetProps } = props\n  const { groupName, children } = config\n\n  return (\n    <PanelBar title={groupName}>\n      {children && children.length > 0 && (\n        <div css={ghostEmptyStyle}>\n          <FieldFactory\n            panelConfig={children}\n            displayName={displayName}\n            widgetProps={widgetProps}\n          />\n        </div>\n      )}\n    </PanelBar>\n  )\n}\n\nRenderPanelBar.displayName = \"RenderPanelBar\"\n\nexport default RenderPanelBar\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/Panelbar/interface.ts",
    "content": "import { PanelFieldGroupConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport interface RenderPanelBarProps {\n  config: PanelFieldGroupConfig\n  displayName: string\n  widgetProps: Record<string, any>\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/Panelbar/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const ghostEmptyStyle = css`\n  padding-bottom: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/SingleSelectedPanel/singleSelectedPanel.tsx",
    "content": "import { FC, memo, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Alert, Divider } from \"@illa-design/react\"\nimport { PanelHeader } from \"@/page/App/components/InspectPanel/components/Header\"\nimport { SelectedProvider } from \"@/page/App/components/InspectPanel/context/selectedContext\"\nimport { panelBuilder } from \"@/page/App/components/InspectPanel/utils/panelBuilder\"\nimport { getComponentNodeBySingleSelected } from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport FieldFactory from \"../FieldFactory\"\nimport {\n  singleSelectedPanelSetterWrapperStyle,\n  singleSelectedPanelWrapperStyle,\n} from \"./style\"\n\nconst SingleSelectedPanel: FC = () => {\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n  const singleSelectedComponentNode = useSelector(\n    getComponentNodeBySingleSelected,\n  )\n\n  const widgetType = singleSelectedComponentNode?.type || \"\"\n\n  const widgetDisplayName = singleSelectedComponentNode?.displayName || \"\"\n\n  const widgetParentDisplayName = singleSelectedComponentNode?.parentNode || \"\"\n\n  const widgetProps = singleSelectedComponentNode?.props || {}\n\n  const handleUpdateDsl = useCallback(\n    (attrPath: string, value: unknown) => {\n      const updateSlice = { [attrPath]: value }\n      dispatch(\n        componentsActions.updateComponentPropsReducer({\n          displayName: widgetDisplayName,\n          updateSlice,\n        }),\n      )\n    },\n    [dispatch, widgetDisplayName],\n  )\n\n  const handleUpdateMultiAttrDSL = useCallback(\n    (updateSlice: Record<string, unknown>) => {\n      if (!isObject(updateSlice)) return\n      dispatch(\n        componentsActions.updateComponentPropsReducer({\n          displayName: widgetDisplayName,\n          updateSlice,\n        }),\n      )\n    },\n    [dispatch, widgetDisplayName],\n  )\n\n  const handleUpdateOtherMultiAttrDSL = useCallback(\n    (displayName: string, updateSlice: Record<string, any>) => {\n      if (!displayName || !isObject(updateSlice)) return\n      dispatch(\n        componentsActions.updateComponentPropsReducer({\n          displayName,\n          updateSlice,\n        }),\n      )\n    },\n    [dispatch],\n  )\n\n  const handleUpdateExecutionResult = useCallback(\n    (displayName: string, updateSlice: Record<string, unknown>) => {\n      if (!isObject(updateSlice)) return\n      dispatch(\n        executionActions.updateExecutionByDisplayNameReducer({\n          displayName,\n          value: updateSlice,\n        }),\n      )\n    },\n    [dispatch],\n  )\n\n  const builderPanelConfig = panelBuilder(widgetType)\n\n  return (\n    builderPanelConfig && (\n      <SelectedProvider\n        widgetType={widgetType}\n        widgetDisplayName={widgetDisplayName}\n        widgetParentDisplayName={widgetParentDisplayName}\n        widgetProps={widgetProps}\n        handleUpdateDsl={handleUpdateDsl}\n        handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n        handleUpdateOtherMultiAttrDSL={handleUpdateOtherMultiAttrDSL}\n        handleUpdateExecutionResult={handleUpdateExecutionResult}\n        widgetOrAction=\"WIDGET\"\n      >\n        <div css={singleSelectedPanelWrapperStyle}>\n          <PanelHeader />\n          <Divider />\n          {widgetType === \"TABLE_WIDGET\" && (\n            <Alert\n              type=\"warning\"\n              title={t(\"editor.inspect.setter_tips.table_update_title\")}\n              content={t(\"editor.inspect.setter_tips.table_update_content\")}\n            />\n          )}\n          <div css={singleSelectedPanelSetterWrapperStyle}>\n            <FieldFactory\n              panelConfig={builderPanelConfig}\n              displayName={widgetDisplayName}\n              widgetProps={widgetProps}\n            />\n          </div>\n        </div>\n      </SelectedProvider>\n    )\n  )\n}\n\nSingleSelectedPanel.displayName = \"SingleSelectedPanel\"\nexport default memo(SingleSelectedPanel)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/components/SingleSelectedPanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const singleSelectedPanelWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n`\n\nexport const singleSelectedPanelSetterWrapperStyle = css`\n  height: 100%;\n  overflow-y: auto;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/context/selectedContext.tsx",
    "content": "import { FC, ReactNode, createContext } from \"react\"\n\ninterface Injected {\n  widgetType: string\n  widgetDisplayName: string\n  widgetParentDisplayName: string | null\n  widgetProps: Record<string, any>\n  widgetOrAction: \"WIDGET\" | \"ACTION\"\n  handleUpdateDsl: (attrPath: string, value: any) => void\n  handleUpdateMultiAttrDSL: (updateSlice: Record<string, unknown>) => void\n  handleUpdateOtherMultiAttrDSL: (\n    displayName: string,\n    updateSlice: Record<string, any>,\n  ) => void\n  handleUpdateExecutionResult?: (\n    displayName: string,\n    updateSlice: Record<string, unknown>,\n  ) => void\n}\n\nexport const SelectedPanelContext = createContext<Injected>({} as Injected)\n\ninterface Props {\n  widgetType: string\n  widgetDisplayName: string\n  widgetParentDisplayName: string | null\n  widgetProps: Record<string, any>\n  handleUpdateDsl: (attrPath: string, value: any) => void\n  handleUpdateMultiAttrDSL: (updateSlice: Record<string, unknown>) => void\n  handleUpdateOtherMultiAttrDSL: (\n    displayName: string,\n    updateSlice: Record<string, unknown>,\n  ) => void\n  handleUpdateExecutionResult?: (\n    displayName: string,\n    updateSlice: Record<string, unknown>,\n  ) => void\n  widgetOrAction: \"WIDGET\" | \"ACTION\"\n  children?: ReactNode\n}\n\nexport const SelectedProvider: FC<Props> = (props) => {\n  const {\n    children,\n    widgetType,\n    widgetDisplayName,\n    widgetParentDisplayName,\n    widgetProps,\n    widgetOrAction,\n    handleUpdateDsl,\n    handleUpdateMultiAttrDSL,\n    handleUpdateOtherMultiAttrDSL,\n    handleUpdateExecutionResult,\n  } = props\n\n  const value = {\n    widgetType,\n    widgetDisplayName,\n    widgetParentDisplayName,\n    widgetProps,\n    widgetOrAction,\n    handleUpdateDsl,\n    handleUpdateMultiAttrDSL,\n    handleUpdateOtherMultiAttrDSL,\n    handleUpdateExecutionResult,\n  }\n\n  return (\n    <SelectedPanelContext.Provider value={value}>\n      {children}\n    </SelectedPanelContext.Provider>\n  )\n}\n\nSelectedProvider.displayName = \"SelectedProvider\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getSelectedComponentDisplayNames } from \"@/redux/config/configSelector\"\nimport { EmptySelected } from \"./components/EmptySelected\"\nimport MultiSelectedPanel from \"./components/MultiSelectedPanel/multiSelectedPanel\"\nimport SingleSelectedPanel from \"./components/SingleSelectedPanel/singleSelectedPanel\"\n\nconst InspectPanel: FC = () => {\n  const selectedComponentsDisplayNames = useSelector(\n    getSelectedComponentDisplayNames,\n  )\n\n  return selectedComponentsDisplayNames.length === 0 ? (\n    <EmptySelected />\n  ) : selectedComponentsDisplayNames.length > 1 ? (\n    <MultiSelectedPanel />\n  ) : (\n    <SingleSelectedPanel />\n  )\n}\n\nInspectPanel.displayName = \"InspectPanel\"\nexport default InspectPanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/interface.ts",
    "content": "import { ReactNode } from \"react\"\nimport { SetterType } from \"@/page/App/components/InspectPanel/PanelSetters\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\nimport { PanelLabelProps } from \"./components/Label/interface\"\n\nexport interface EventHandlerPanelConfig extends PanelFieldConfig {\n  eventHandlerConfig: EventHandlerConfig\n}\n\nexport interface PanelFieldConfig extends PanelLabelProps {\n  id: string\n  setterType: SetterType\n  expectedType?: VALIDATION_TYPES\n  attrName: string\n  childrenSetter?: PanelFieldConfig[]\n  useCustomLayout?: boolean\n  options?: any\n  isSetterSingleRow?: boolean\n  defaultValue?: any\n  placeholder?: string\n  icon?: ReactNode\n  shown?: (...params: any[]) => boolean\n  bindAttrName?: string | string[]\n  openDynamic?: boolean\n  allowClear?: boolean\n  detailedDescription?: string\n\n  // DynamicSelectSetter props\n  inputPlaceholder?: string\n  selectPlaceholder?: string\n  isDynamicAttrName?: string\n  selectAttrName?: string\n  inputAttrName?: string\n}\n\nexport interface PanelFieldGroupConfig {\n  id: string\n  groupName: string\n  children: PanelFieldConfig[]\n}\n\nexport type PanelConfig = PanelFieldConfig | PanelFieldGroupConfig\n\nexport interface PanelSetterProps extends Omit<PanelFieldConfig, \"id\"> {\n  parentAttrName: string\n  displayName: string\n}\n\nexport interface SelectedPanelProps {\n  selectedDisplayNames: string[]\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/setter.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { get, toPath } from \"lodash-es\"\nimport { memo, useContext, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getSetterByType } from \"@/page/App/components/InspectPanel/PanelSetters\"\nimport { SelectedPanelContext } from \"@/page/App/components/InspectPanel/context/selectedContext\"\nimport { getComponentNodeBySingleSelected } from \"@/redux/currentApp/components/componentsSelector\"\nimport { getGuideStatus } from \"@/redux/guide/guideSelector\"\nimport { PanelSetterProps } from \"./interface\"\nimport { applySetterWrapperStyle } from \"./style\"\n\nexport const Setter = memo<PanelSetterProps>((props: PanelSetterProps) => {\n  const {\n    setterType,\n    isSetterSingleRow,\n    labelName,\n    useCustomLayout = false,\n    shown,\n    bindAttrName,\n    attrName,\n    parentAttrName,\n    expectedType,\n    defaultValue,\n    icon,\n  } = props\n  const Comp = getSetterByType(setterType)\n  const isGuideMode = useSelector(getGuideStatus)\n  const componentNode = useSelector(getComponentNodeBySingleSelected)\n  const {\n    widgetProps,\n    widgetDisplayName,\n    widgetType,\n    widgetOrAction,\n    handleUpdateDsl,\n    handleUpdateMultiAttrDSL,\n    handleUpdateOtherMultiAttrDSL,\n    handleUpdateExecutionResult,\n  } = useContext(SelectedPanelContext)\n\n  const canRenderSetter = useMemo(() => {\n    if (!bindAttrName || !shown) return true\n    if (Array.isArray(bindAttrName)) {\n      const bindAttrNameValues = bindAttrName.map((bindAttrNameItem) => {\n        if (parentAttrName) {\n          return get(widgetProps, `${parentAttrName}.${bindAttrNameItem}`)\n        }\n        return get(widgetProps, bindAttrNameItem)\n      })\n      return shown(...bindAttrNameValues)\n    }\n    return true\n  }, [bindAttrName, shown, parentAttrName, widgetProps])\n\n  const _finalAttrName = useMemo(() => {\n    if (typeof attrName === \"string\") {\n      if (parentAttrName) {\n        const parentAttrNamePath = toPath(parentAttrName)\n        return convertPathToString([...parentAttrNamePath, attrName])\n      }\n      return attrName\n    }\n    return \"\"\n  }, [parentAttrName, attrName])\n\n  const isSetterSingleRowWrapper = isSetterSingleRow || !labelName\n\n  const finalValue = useMemo(() => {\n    if (typeof _finalAttrName === \"string\") {\n      return get(widgetProps, _finalAttrName)\n    }\n  }, [widgetProps, _finalAttrName])\n\n  return canRenderSetter ? (\n    <div css={applySetterWrapperStyle(isSetterSingleRow, useCustomLayout)}>\n      {Comp ? (\n        <Comp\n          {...props}\n          attrName={_finalAttrName}\n          isSetterSingleRow={isSetterSingleRowWrapper}\n          value={finalValue}\n          panelConfig={widgetProps}\n          handleUpdateDsl={handleUpdateDsl}\n          handleUpdateMultiAttrDSL={handleUpdateMultiAttrDSL}\n          handleUpdateOtherMultiAttrDSL={handleUpdateOtherMultiAttrDSL}\n          handleUpdateExecutionResult={handleUpdateExecutionResult}\n          widgetDisplayName={widgetDisplayName}\n          expectedType={expectedType}\n          widgetType={widgetType}\n          parentAttrName={parentAttrName}\n          widgetOrAction={widgetOrAction}\n          defaultValue={defaultValue}\n          icon={icon}\n          componentNode={componentNode!}\n          isGuideMode={isGuideMode}\n        />\n      ) : null}\n    </div>\n  ) : null\n})\n\nSetter.displayName = \"Setter\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\n\nexport const publicPaddingStyle = css`\n  padding: 0 16px;\n  box-sizing: border-box;\n`\n\nexport function applySetterWrapperStyle(\n  isSetterSingleRow: boolean = false,\n  useCustomLayout: boolean = false,\n): SerializedStyles {\n  if (useCustomLayout) {\n    return css``\n  }\n  if (isSetterSingleRow) {\n    return css`\n      padding: 0 16px;\n    `\n  }\n\n  return css`\n    padding: 0px 16px;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/utils/fieldFactory.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { PanelFieldConfig } from \"@/page/App/components/InspectPanel/interface\"\n\nexport const canRenderField = (\n  item: PanelFieldConfig,\n  widgetProps: Record<string, any>,\n) => {\n  const { bindAttrName, shown } = item\n  if (!bindAttrName || !shown) return true\n  if (Array.isArray(bindAttrName)) {\n    const values = bindAttrName.map((bindAttrNameItem) =>\n      get(widgetProps, bindAttrNameItem),\n    )\n    return shown(...values)\n  }\n\n  return true\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/InspectPanel/utils/panelBuilder.ts",
    "content": "import { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { WidgetType, widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\n\nexport const panelBuilder = (type: WidgetType): PanelConfig[] | null => {\n  if (!type) return null\n  if (!widgetBuilder(type)) return null\n  return widgetBuilder(type).panelConfig\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/MissingRosourceModal/index.tsx",
    "content": "import MissingResources, {\n  MissingResourcesProvider,\n} from \"@illa-public/missing-resource-module\"\nimport {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport { ActionContent, ActionItem, Resource } from \"@illa-public/public-types\"\nimport { FC, memo } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  getAIAgentIDMapAgent,\n  getDashboardTeamAIAgentList,\n} from \"@/redux/aiAgent/dashboardTeamAIAgentSelector\"\nimport {\n  getActionIDMapAction,\n  getMissingResourceActionGroupByTutorialOrResourceID,\n} from \"@/redux/currentApp/action/actionSelector\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport {\n  getAllResources,\n  getResourceIDMapResource,\n} from \"@/redux/resource/resourceSelector\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { fetchBatchUpdateAction } from \"@/services/action\"\nimport { track } from \"@/utils/mixpanelHelper\"\nimport { IMissingResourceModalProps } from \"./interface\"\n\nconst MissingResourceModal: FC<IMissingResourceModalProps> = (props) => {\n  const { shown, changeShown } = props\n  const resourceIDMapResource = useSelector(getResourceIDMapResource)\n  const missingActionsMap = useSelector(\n    getMissingResourceActionGroupByTutorialOrResourceID,\n  )\n  const resourceList = useSelector(getAllResources)\n  const aiAgentList = useSelector(getDashboardTeamAIAgentList)\n  const actionIDMapAction = useSelector(getActionIDMapAction)\n  const agentIDMapAgent = useSelector(getAIAgentIDMapAgent)\n  const dispatch = useDispatch()\n\n  const updateActions = async (actionList: ActionItem<ActionContent>[]) => {\n    await fetchBatchUpdateAction(actionList)\n    dispatch(actionActions.batchUpdateActionItemReducer(actionList))\n  }\n\n  const addResourceCallback = (resource: Resource) => {\n    dispatch(resourceActions.addResourceItemReducer(resource))\n  }\n\n  return (\n    shown &&\n    createPortal(\n      <MixpanelTrackProvider\n        basicTrack={track}\n        pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR}\n      >\n        <MissingResourcesProvider\n          resourceIDMapResource={resourceIDMapResource}\n          actionIDMapAction={actionIDMapAction}\n          missingActionsMap={missingActionsMap}\n          resourceList={resourceList}\n          aiAgentList={aiAgentList}\n          agentIDMapAgent={agentIDMapAgent}\n          updateActions={updateActions}\n          addResourceCallback={addResourceCallback}\n        >\n          <MissingResources shown={shown} changeShown={changeShown} />\n        </MissingResourcesProvider>\n      </MixpanelTrackProvider>,\n      document.body,\n    )\n  )\n}\n\nexport default memo(MissingResourceModal)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/MissingRosourceModal/interface.ts",
    "content": "export interface MissingTipButtonMethod {\n  changeShown: (shown: boolean) => void\n}\n\nexport interface IMissingResourceModalProps {\n  shown: boolean\n  changeShown: (shown: boolean) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/Label/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Trigger } from \"@illa-design/react\"\nimport { PageLabelProps } from \"./interface\"\nimport { labelStyle } from \"./style\"\n\nexport const PageLabel: FC<PageLabelProps> = (props) => {\n  const { tooltip, labelName, size } = props\n  return (\n    <Trigger\n      trigger=\"hover\"\n      position=\"left\"\n      content={tooltip}\n      disabled={!tooltip}\n    >\n      <span css={labelStyle(size, !tooltip)}>{labelName}</span>\n    </Trigger>\n  )\n}\n\nPageLabel.displayName = \"PageLabel\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/Label/interface.ts",
    "content": "export interface PageLabelProps {\n  tooltip?: string\n  labelName: string\n  size: \"big\" | \"small\"\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/Label/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nconst getLabelSizeFontStyle = (size: \"big\" | \"small\") => {\n  switch (size) {\n    case \"big\": {\n      return css`\n        font-size: 14px;\n        color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n      `\n    }\n    case \"small\": {\n      return css`\n        font-size: 12px;\n        color: ${globalColor(`--${illaPrefix}-grayBlue-03`)};\n      `\n    }\n  }\n}\n\nexport function labelStyle(size: \"big\" | \"small\", disabledTooltip: boolean) {\n  const borderStyle = disabledTooltip\n    ? null\n    : css`\n        border-bottom: 1px dashed ${globalColor(`--${illaPrefix}-grayBlue-03`)};\n      `\n  return css`\n    font-weight: 500;\n    height: 22px;\n    line-height: 22px;\n    ${borderStyle};\n    ${getLabelSizeFontStyle(size)};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/LayoutSelect/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch } from \"react-redux\"\nimport { DownIcon, Trigger, useModal } from \"@illa-design/react\"\nimport DefaultIcon from \"@/assets/rightPagePanel/layout/default.svg?react\"\nimport PresetAIcon from \"@/assets/rightPagePanel/layout/preset-a.svg?react\"\nimport PresetBIcon from \"@/assets/rightPagePanel/layout/preset-b.svg?react\"\nimport PresetCIcon from \"@/assets/rightPagePanel/layout/preset-c.svg?react\"\nimport PresetDIcon from \"@/assets/rightPagePanel/layout/preset-d.svg?react\"\nimport PresetEIcon from \"@/assets/rightPagePanel/layout/preset-e.svg?react\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport {\n  LayoutOptionItemProps,\n  LayoutOptionsPanelProps,\n  LayoutSelectProps,\n} from \"./interface\"\nimport {\n  applyLayoutOptionItemIconStyle,\n  layoutOptionItemLabelStyle,\n  layoutOptionItemWrapperStyle,\n  layoutOptionsPanelWrapperStyle,\n  layoutSelectWrapperStyle,\n} from \"./style\"\n\nexport const LAYOUT_OPTIONS = [\n  {\n    label: \"Default\",\n    value: \"default\",\n    icon: <DefaultIcon />,\n  },\n  { label: \"Preset A\", value: \"presetA\", icon: <PresetAIcon /> },\n  { label: \"Preset B\", value: \"presetB\", icon: <PresetBIcon /> },\n  { label: \"Preset C\", value: \"presetC\", icon: <PresetCIcon /> },\n  { label: \"Preset D\", value: \"presetD\", icon: <PresetDIcon /> },\n  { label: \"Preset E\", value: \"presetE\", icon: <PresetEIcon /> },\n]\n\nexport const findLayoutOptionItem = (layoutValue: string) => {\n  const targetItem = LAYOUT_OPTIONS.find((item) => item.value === layoutValue)\n  return targetItem?.label || \"Custom\"\n}\n\nexport const LayoutOptionItem: FC<LayoutOptionItemProps> = (props) => {\n  const { isSelected, label, value, icon, selectedValue, currentPageName } =\n    props\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const modal = useModal()\n\n  const handleChangeLayout = useCallback(() => {\n    if (selectedValue === value || !currentPageName) return\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SELECT, {\n      element: \"preset_selection\",\n      parameter3: value,\n    })\n    modal.show({\n      w: \"496px\",\n      children: t(\"editor.page.model_tips.change_layout_message\"),\n      cancelText: t(\"editor.page.model_tips.cancel_button\"),\n      okText: t(\"editor.page.model_tips.ok_button\"),\n      okButtonProps: {\n        colorScheme: \"red\",\n      },\n      closable: false,\n      onOk: () => {\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n          element: \"preset_confirm\",\n          parameter3: value,\n        })\n        dispatch(\n          componentsActions.updateTargetPageLayoutReducer({\n            pageName: currentPageName,\n            layout: value as\n              | \"default\"\n              | \"presetA\"\n              | \"presetB\"\n              | \"presetC\"\n              | \"presetD\"\n              | \"presetE\",\n          }),\n        )\n      },\n    })\n  }, [currentPageName, dispatch, modal, selectedValue, t, value])\n\n  return (\n    <div css={layoutOptionItemWrapperStyle} onClick={handleChangeLayout}>\n      <div css={applyLayoutOptionItemIconStyle(isSelected)} data-value={value}>\n        {icon}\n      </div>\n      <span css={layoutOptionItemLabelStyle} data-value={value}>\n        {label}\n      </span>\n    </div>\n  )\n}\n\nexport const LayoutOptionsPanel: FC<LayoutOptionsPanelProps> = (props) => {\n  const { selectedValue, currentPageName } = props\n\n  return (\n    <div css={layoutOptionsPanelWrapperStyle}>\n      {LAYOUT_OPTIONS.map((item) => {\n        return (\n          <LayoutOptionItem\n            key={`${item.label}-${item.value}`}\n            label={item.label}\n            value={item.value}\n            icon={item.icon}\n            isSelected={selectedValue === item.value}\n            selectedValue={selectedValue}\n            currentPageName={currentPageName}\n          />\n        )\n      })}\n    </div>\n  )\n}\n\nexport const LayoutSelect: FC<LayoutSelectProps> = (props) => {\n  const { value, currentPageName } = props\n  return (\n    <Trigger\n      trigger=\"click\"\n      content={\n        <LayoutOptionsPanel\n          selectedValue={value}\n          currentPageName={currentPageName}\n        />\n      }\n      position=\"bottom-end\"\n      colorScheme=\"white\"\n      withoutPadding\n      closeOnInnerClick\n      onVisibleChange={(visible) => {\n        if (visible) {\n          trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n            element: \"preset_selection\",\n          })\n        }\n      }}\n    >\n      <div css={layoutSelectWrapperStyle}>\n        <span>{findLayoutOptionItem(value)}</span>\n        <DownIcon />\n      </div>\n    </Trigger>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/LayoutSelect/interface.ts",
    "content": "import { ReactChild } from \"react\"\n\nexport interface LayoutOptionsPanelProps {\n  selectedValue: string\n  currentPageName: string\n}\n\nexport interface LayoutSelectProps {\n  value: string\n  currentPageName: string\n}\n\nexport interface LayoutOptionItemProps {\n  isSelected: boolean\n  label: string\n  value: string\n  icon: ReactChild\n  selectedValue: string\n  currentPageName: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/LayoutSelect/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const layoutSelectWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  height: 22px;\n  gap: 4px;\n  cursor: pointer;\n`\n\nexport const layoutOptionsPanelWrapperStyle = css`\n  padding: 16px;\n  background-color: ${globalColor(`--${illaPrefix}-white-01`)};\n  box-shadow: 0 2px 16px rgba(0, 0, 0, 0.08);\n  border-radius: 8px;\n  display: grid;\n  gap: 16px;\n  grid-template-columns: repeat(3, 88px);\n`\n\nexport const layoutOptionItemWrapperStyle = css`\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  gap: 4px;\n`\n\nexport const applyLayoutOptionItemIconStyle = (isSelected: boolean) => {\n  return css`\n    padding: 8px;\n    background-color: ${isSelected\n      ? globalColor(`--${illaPrefix}-techPurple-08`)\n      : globalColor(`--${illaPrefix}-grayBlue-09`)};\n    border-radius: 4px;\n    flex: none;\n    border: 1px solid\n      ${isSelected\n        ? globalColor(`--${illaPrefix}-techPurple-03`)\n        : \"transparent\"};\n    cursor: pointer;\n    transition: all 0.2s ease-in-out 0s;\n    :hover {\n      border: 1px solid ${globalColor(`--${illaPrefix}-techPurple-03`)};\n      box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.08);\n      background-color: ${globalColor(`--${illaPrefix}-techPurple-08`)};\n    }\n    :active {\n      border: 1px solid ${globalColor(`--${illaPrefix}-techPurple-03`)};\n      background-color: ${globalColor(`--${illaPrefix}-techPurple-08`)};\n    }\n  `\n}\n\nexport const layoutOptionItemLabelStyle = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  font-size: 14px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/PanelActionBar/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC } from \"react\"\nimport { MinusIcon, PlusIcon } from \"@illa-design/react\"\nimport { PanelActionBarProps } from \"./interface\"\nimport { panelActionBarWrapperStyle } from \"./style\"\n\nexport const PanelActionBar: FC<PanelActionBarProps> = (props) => {\n  const { hasPanel, addPanelAction, deletePanelAction } = props\n  return (\n    <div css={panelActionBarWrapperStyle}>\n      {/* {hasPanel ? (\n        isFixed ? (\n          <LockIcon css={baseIconStyle} />\n        ) : (\n          <UnlockIcon css={baseIconStyle} />\n        )\n      ) : null} */}\n      {hasPanel ? (\n        <IconHotSpot onClick={deletePanelAction}>\n          <MinusIcon />\n        </IconHotSpot>\n      ) : (\n        <IconHotSpot onClick={addPanelAction}>\n          <PlusIcon />\n        </IconHotSpot>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/PanelActionBar/interface.ts",
    "content": "export interface PanelActionBarProps {\n  isFixed: boolean\n  hasPanel: boolean\n  addPanelAction: () => void\n  deletePanelAction: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/PanelActionBar/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const panelActionBarWrapperStyle = css`\n  display: flex;\n  align-items: flex-start;\n  gap: 8px;\n  flex: none;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/ViewsList/body.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { SectionViewShape } from \"@illa-public/public-types\"\nimport { klona } from \"klona/json\"\nimport { set } from \"lodash-es\"\nimport { FC, useCallback, useContext } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ShortCutContext } from \"@/utils/shortcut/shortcutProvider\"\nimport { BodyProps } from \"./interface\"\nimport { Item } from \"./item\"\nimport { viewsListBodyWrapperStyle } from \"./style\"\n\nexport const ListBody: FC<BodyProps> = (props) => {\n  const {\n    sectionViewConfigs,\n    viewSortedKey,\n    parentNodeDisplayName,\n    sectionName,\n  } = props\n  const dispatch = useDispatch()\n  const shortcut = useContext(ShortCutContext)\n\n  const handleDeleteSectionView = useCallback(\n    (index: number) => {\n      if (index > sectionViewConfigs.length) return\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"delete_view\",\n        parameter2: sectionName.slice(0, -7),\n      })\n      const config = sectionViewConfigs[index] as SectionViewShape\n      const viewDisplayName = config.viewDisplayName\n      shortcut.showDeleteDialog([config.path], \"pageView\", {\n        parentNodeName: parentNodeDisplayName,\n        originPageSortedKey: viewSortedKey,\n        viewDisplayName: viewDisplayName,\n      })\n    },\n    [\n      parentNodeDisplayName,\n      sectionName,\n      sectionViewConfigs,\n      shortcut,\n      viewSortedKey,\n    ],\n  )\n\n  const handleUpdateItem = useCallback(\n    (path: string, value: string) => {\n      const newSectionViewConfigs = klona(sectionViewConfigs)\n      set(newSectionViewConfigs, path, value)\n      dispatch(\n        componentsActions.updateSectionViewPropsReducer({\n          parentNodeName: parentNodeDisplayName,\n          newProps: {\n            sectionViewConfigs: newSectionViewConfigs,\n          },\n        }),\n      )\n    },\n    [dispatch, parentNodeDisplayName, sectionViewConfigs],\n  )\n\n  return (\n    <div css={viewsListBodyWrapperStyle}>\n      {sectionViewConfigs.map((config: SectionViewShape, index: number) => {\n        const otherPaths = (\n          sectionViewConfigs.map(\n            (views: SectionViewShape, i: number) => views.path || i,\n          ) as string[]\n        ).filter((key: string, i: number) => i != index)\n        return (\n          <Item\n            key={config.id}\n            otherPaths={otherPaths}\n            path={config.path}\n            viewDisplayName={config.viewDisplayName}\n            index={index}\n            attrPath={`${index}`}\n            handleDeleteSectionView={handleDeleteSectionView}\n            handleUpdateItem={handleUpdateItem}\n            parentNodeDisplayName={parentNodeDisplayName}\n          />\n        )\n      })}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/ViewsList/emptyState.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { viewListEmptyBody } from \"./style\"\n\nexport const EmptyState: FC = () => {\n  const { t } = useTranslation()\n  return (\n    <div css={viewListEmptyBody}>{t(\"editor.inspect.page.blank_view\")}</div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/ViewsList/header.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { SectionViewShape } from \"@illa-public/public-types\"\nimport { difference } from \"lodash-es\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { AddIcon, Link, useMessage } from \"@illa-design/react\"\nimport {\n  getComponentMap,\n  searchDSLByDisplayName,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { generateSectionContainerConfig } from \"@/utils/generators/generatePageOrSectionConfig\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { HeaderProps } from \"./interface\"\nimport { headerLabelStyle, viewsListHeaderWrapperStyle } from \"./style\"\nimport { generateNewViewItemFromBodySectionConfig } from \"./utils\"\n\nexport const ViewListHeader: FC<HeaderProps> = (props) => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const message = useMessage()\n  const { sectionName, parentNodeDisplayName } = props\n  const components = useSelector(getComponentMap)\n\n  const handleClickAddButton = useCallback(() => {\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n      element: \"add_view\",\n      parameter2: sectionName.slice(0, -7),\n    })\n\n    const parentNode = searchDSLByDisplayName(parentNodeDisplayName)\n    if (!parentNode) return\n    if (!parentNode || !parentNode.props) return\n    let bodySectionSubPaths: string[] = []\n    if (sectionName !== \"bodySection\") {\n      const pageNode = searchDSLByDisplayName(parentNode.parentNode!)\n      if (!pageNode) return\n      const bodySectionNodeDisplayName = pageNode.childrenNode.find(\n        (node) => components[node].showName === \"bodySection\",\n      )\n      if (!bodySectionNodeDisplayName) return\n      bodySectionSubPaths =\n        components[bodySectionNodeDisplayName].props?.sectionViewConfigs.map(\n          (config: Record<string, string>) => config.path,\n        ) ?? []\n    }\n\n    const config = generateSectionContainerConfig(\n      parentNodeDisplayName,\n      `${sectionName}Container`,\n    )\n    const hasPaths = parentNode.props.sectionViewConfigs.map(\n      (item: SectionViewShape) => {\n        return item.path\n      },\n    )\n    const diffSubPaths = difference(bodySectionSubPaths, hasPaths)\n    if (diffSubPaths.length === 0 && sectionName !== \"bodySection\") {\n      message.info({\n        content: t(\"editor.page.message.new_path\"),\n      })\n    }\n\n    const newSectionViewConfig = generateNewViewItemFromBodySectionConfig(\n      hasPaths,\n      config.displayName,\n      parentNodeDisplayName,\n      diffSubPaths,\n    )\n    dispatch(\n      componentsActions.addSectionViewConfigByConfigReducer({\n        parentNodeName: parentNodeDisplayName,\n        sectionName,\n        sectionViewConfig: newSectionViewConfig,\n        sectionViewNode: config,\n      }),\n    )\n  }, [components, dispatch, message, parentNodeDisplayName, sectionName, t])\n\n  return (\n    <div css={viewsListHeaderWrapperStyle}>\n      <span css={headerLabelStyle}>{t(\"editor.page.label_name.views\")}</span>\n      <Link\n        colorScheme=\"techPurple\"\n        icon={<AddIcon />}\n        hoverable\n        onClick={handleClickAddButton}\n      >\n        <span>{t(\"editor.inspect.setter_content.column_setter.new\")}</span>\n      </Link>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/ViewsList/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport {\n  getRootNodeExecutionResult,\n  getSectionExecutionResultArray,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { ListBody } from \"./body\"\nimport { EmptyState } from \"./emptyState\"\nimport { ViewListHeader } from \"./header\"\nimport { ViewListProps } from \"./interface\"\nimport { viewsListWrapperStyle } from \"./style\"\n\nexport const ViewList: FC<ViewListProps> = (props) => {\n  const { sectionName } = props\n  const rootNodeProps = useSelector(getRootNodeExecutionResult)\n  const { currentPageIndex, pageSortedKey } = rootNodeProps\n  const currentPageDisplayName = pageSortedKey[currentPageIndex]\n\n  const sectionNodeExecutionResult = useSelector<RootState>((state) => {\n    const components = getComponentMap(state)\n    const currentPageNode = searchComponentFromMap(\n      components,\n      currentPageDisplayName,\n    )\n    if (!currentPageNode) return null\n    const currentSectionNodeDisplayName = currentPageNode.childrenNode.find(\n      (childDisplayName) =>\n        components[childDisplayName].showName === sectionName,\n    )\n    if (!currentSectionNodeDisplayName) return null\n    const execution = getSectionExecutionResultArray(state)\n    return execution[currentSectionNodeDisplayName] || null\n  }) as Record<string, any>\n\n  if (!sectionNodeExecutionResult) return null\n\n  return (\n    <div css={viewsListWrapperStyle}>\n      <ViewListHeader\n        sectionName={sectionName}\n        parentNodeDisplayName={sectionNodeExecutionResult.displayName}\n      />\n      {Array.isArray(sectionNodeExecutionResult.sectionViewConfigs) &&\n      sectionNodeExecutionResult.sectionViewConfigs.length > 0 ? (\n        <ListBody\n          sectionName={sectionName}\n          parentNodeDisplayName={sectionNodeExecutionResult.displayName}\n          currentViewIndex={sectionNodeExecutionResult.currentViewIndex}\n          viewSortedKey={sectionNodeExecutionResult.viewSortedKey}\n          sectionViewConfigs={sectionNodeExecutionResult.sectionViewConfigs}\n        />\n      ) : (\n        <EmptyState />\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/ViewsList/interface.ts",
    "content": "import { SectionViewShape } from \"@illa-public/public-types\"\n\nexport interface HeaderProps {\n  sectionName:\n    | \"leftSection\"\n    | \"rightSection\"\n    | \"headerSection\"\n    | \"footerSection\"\n    | \"bodySection\"\n  parentNodeDisplayName: string\n}\n\nexport interface ViewListProps {\n  sectionName:\n    | \"leftSection\"\n    | \"rightSection\"\n    | \"headerSection\"\n    | \"footerSection\"\n    | \"bodySection\"\n}\n\nexport interface BodyProps {\n  sectionName: string\n  parentNodeDisplayName: string\n  currentViewIndex: number\n  viewSortedKey: string[]\n  sectionViewConfigs: SectionViewShape[]\n}\n\nexport interface ItemProps extends Omit<SectionViewShape, \"id\" | \"key\"> {\n  otherPaths: string[]\n  index: number\n  handleDeleteSectionView: (index: number) => void\n  handleUpdateItem: (path: string, value: string) => void\n  attrPath: string\n  parentNodeDisplayName: string\n}\n\nexport interface LabelNameAndDragIconProps {\n  name: string\n  isDuplicationKey: boolean\n}\n\nexport interface ModalProps {\n  onCloseModal: () => void\n  path: string\n  handleUpdateItem: (value: string) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/ViewsList/item.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC, useCallback, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { ReduceIcon, Trigger, useMessage } from \"@illa-design/react\"\nimport {\n  getComponentMap,\n  searchDSLByDisplayName,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ItemProps } from \"./interface\"\nimport { LabelNameAndDragIcon } from \"./labelName\"\nimport { Modal } from \"./modal\"\nimport { itemWrapperStyle } from \"./style\"\n\nexport const Item: FC<ItemProps> = (props) => {\n  const {\n    otherPaths,\n    index,\n    handleDeleteSectionView,\n    path,\n    handleUpdateItem,\n    attrPath,\n    parentNodeDisplayName,\n  } = props\n  const [modalVisible, setModalVisible] = useState(false)\n  const message = useMessage()\n  const components = useSelector(getComponentMap)\n\n  const isDuplicationPath = otherPaths.some((viewKey) => viewKey == path)\n\n  const [currentPath, useCurrentPath] = useState(path)\n  const { t } = useTranslation()\n\n  const handleUpdatePath = useCallback(() => {\n    if (currentPath === path) return\n    const sectionNode = searchDSLByDisplayName(parentNodeDisplayName)\n    if (!sectionNode) return\n    const pageNode = searchDSLByDisplayName(sectionNode.parentNode!)\n    if (!pageNode) return\n    let bodySectionPaths: string[] = []\n    if (sectionNode.showName !== \"bodySection\") {\n      const bodySectionNode = pageNode.childrenNode.find(\n        (node) => components[node].showName === \"bodySection\",\n      )\n      if (!bodySectionNode) return\n      bodySectionPaths =\n        components[bodySectionNode].props?.sectionViewConfigs.map(\n          (config: Record<string, string>) => config.path,\n        ) ?? []\n    }\n\n    if (\n      !bodySectionPaths.includes(currentPath) &&\n      sectionNode.showName !== \"bodySection\"\n    ) {\n      message.info({\n        content: t(\"editor.page.message.new_path\"),\n      })\n    }\n\n    handleUpdateItem(`${attrPath}.path`, currentPath)\n  }, [\n    attrPath,\n    components,\n    currentPath,\n    handleUpdateItem,\n    message,\n    parentNodeDisplayName,\n    path,\n    t,\n  ])\n\n  return (\n    <Trigger\n      withoutPadding\n      colorScheme=\"white\"\n      popupVisible={modalVisible}\n      content={\n        <Modal\n          onCloseModal={() => {\n            setModalVisible(false)\n          }}\n          path={currentPath}\n          handleUpdateItem={useCurrentPath}\n        />\n      }\n      trigger=\"click\"\n      showArrow={false}\n      position=\"left\"\n      clickOutsideToClose\n      onVisibleChange={(visible) => {\n        if (visible) {\n          trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n            element: \"edit_view_show\",\n          })\n        } else {\n          handleUpdatePath()\n        }\n        setModalVisible(visible)\n      }}\n    >\n      <div css={itemWrapperStyle}>\n        <LabelNameAndDragIcon\n          name={path}\n          isDuplicationKey={isDuplicationPath}\n        />\n        <IconHotSpot\n          onClick={(e) => {\n            e.stopPropagation()\n            handleDeleteSectionView(index)\n          }}\n        >\n          <ReduceIcon\n            onClick={(e) => {\n              e.stopPropagation()\n              handleDeleteSectionView(index)\n            }}\n          />\n        </IconHotSpot>\n      </div>\n    </Trigger>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/ViewsList/labelName.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  Trigger,\n  WarningCircleIcon,\n  globalColor,\n  illaPrefix,\n} from \"@illa-design/react\"\nimport { LabelNameAndDragIconProps } from \"./interface\"\nimport {\n  labelNameAndDragIconWrapperStyle,\n  labelNameStyle,\n  selectedIconAndLabelNameWrapperStyle,\n} from \"./style\"\n\nexport const LabelNameAndDragIcon: FC<LabelNameAndDragIconProps> = (props) => {\n  const { name, isDuplicationKey } = props\n  const { t } = useTranslation()\n  return (\n    <div css={labelNameAndDragIconWrapperStyle}>\n      <div css={selectedIconAndLabelNameWrapperStyle}>\n        <span css={labelNameStyle}>{name}</span>\n        {isDuplicationKey && (\n          <Trigger\n            trigger=\"hover\"\n            showArrow={false}\n            position=\"bottom\"\n            content={`${t(\"widget.page.path_duplicated\")}`}\n          >\n            <WarningCircleIcon\n              color={globalColor(`--${illaPrefix}-orange-03`)}\n            />\n          </Trigger>\n        )}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/ViewsList/modal.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { CloseIcon, Input } from \"@illa-design/react\"\nimport { LeftAndRightLayout } from \"@/page/App/components/PagePanel/Layout/leftAndRight\"\nimport { SetterPadding } from \"@/page/App/components/PagePanel/Layout/setterPadding\"\nimport { PageLabel } from \"../Label\"\nimport { ModalProps } from \"./interface\"\nimport {\n  modalHeaderCloseIconHotSpot,\n  modalHeaderWrapper,\n  modalWrapperStyle,\n  titleStyle,\n} from \"./style\"\n\nexport const Modal: FC<ModalProps> = (props) => {\n  const { onCloseModal, path, handleUpdateItem } = props\n  const { t } = useTranslation()\n\n  return (\n    <div css={modalWrapperStyle}>\n      <div css={modalHeaderWrapper}>\n        <span css={titleStyle}>{t(\"editor.page.label_name.edit_view\")}</span>\n        <div css={modalHeaderCloseIconHotSpot} onClick={onCloseModal}>\n          <CloseIcon />\n        </div>\n      </div>\n      <LeftAndRightLayout>\n        <PageLabel\n          labelName={t(\"editor.page.label_name.view_path\")}\n          size=\"big\"\n          tooltip={t(\"editor.page.tooltips.view_path\")}\n        />\n        <SetterPadding>\n          <Input\n            w=\"200px\"\n            value={path}\n            colorScheme=\"techPurple\"\n            onChange={handleUpdateItem}\n          />\n        </SetterPadding>\n      </LeftAndRightLayout>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/ViewsList/style.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const viewsListWrapperStyle = css`\n  display: flex;\n  flex-direction: column;\n  border: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  border-radius: 8px;\n  overflow: hidden;\n`\n\nexport const viewsListHeaderWrapperStyle = css`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  width: 287px;\n  height: 40px;\n  padding: 8px 8px 8px 16px;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n`\nexport const viewsListBodyWrapperStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n`\n\nexport const headerLabelStyle = css`\n  font-size: 14px;\n  font-weight: 500;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const headerAddIconStyle = css`\n  width: 8px;\n  height: 8px;\n`\n\nexport const labelNameAndDragIconWrapperStyle = css`\n  display: flex;\n  align-items: center;\n`\n\nexport const selectedIconAndLabelNameWrapperStyle = css`\n  display: flex;\n  max-width: 191px;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const labelNameStyle = css`\n  max-width: 147px;\n  font-size: 14px;\n  font-weight: 400;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n`\n\nexport const itemWrapperStyle = css`\n  display: flex;\n  width: 100%;\n  justify-content: space-between;\n  align-items: center;\n  padding: 9px 16px;\n  gap: 4px;\n  height: 40px;\n  cursor: pointer;\n`\n\nexport const modalWrapperStyle = css`\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  background-color: ${globalColor(`--${illaPrefix}-white-01`)};\n  box-shadow: 0px 2px 16px rgba(0, 0, 0, 0.16);\n  border-radius: 8px;\n  overflow: hidden;\n  position: relative;\n`\n\nexport const modalHeaderWrapper = css`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 12px 16px;\n  width: 360px;\n`\n\nexport const modalHeaderCloseIconHotSpot = css`\n  width: 24px;\n  height: 24px;\n  font-size: 14px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  cursor: pointer;\n`\n\nexport const titleStyle = css`\n  font-weight: 500;\n  font-size: 16px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  max-width: 200px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n`\n\nexport const viewListEmptyBody = css`\n  padding: 8px 16px;\n  height: 40px;\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Components/ViewsList/utils.ts",
    "content": "import { SectionViewShape } from \"@illa-public/public-types\"\nimport { v4 } from \"uuid\"\n\nexport let viewNameSet = new Set<string>()\n\nconst generateDatasetName = (prefix: string) => {\n  let i = 1\n  let ViewName = `sub-page${i}`\n  while (viewNameSet.has(`${prefix}-${ViewName}`)) {\n    i++\n    ViewName = `sub-page${i}`\n  }\n  return ViewName\n}\n\nexport const generateNewViewItem = (\n  hasViewNameSet: string[],\n  viewDisplayName: string,\n  prefix: string,\n): SectionViewShape => {\n  viewNameSet = new Set<string>(hasViewNameSet)\n  const viewName = generateDatasetName(prefix)\n\n  return {\n    id: v4(),\n    key: viewName,\n    path: viewName,\n    viewDisplayName,\n  }\n}\n\nexport const generateNewViewItemFromBodySectionConfig = (\n  hasPaths: string[],\n  viewDisplayName: string,\n  prefix: string,\n  alternativeSubPaths: string[],\n): SectionViewShape => {\n  const prefixedViewPath = hasPaths.map((path) => `${prefix}-${path}`)\n  viewNameSet = new Set<string>(prefixedViewPath)\n  let viewName = \"\"\n  if (alternativeSubPaths.length > 0) {\n    viewName = alternativeSubPaths[0]\n  }\n  if (!viewName) viewName = generateDatasetName(prefix)\n\n  return {\n    id: v4(),\n    key: viewName,\n    path: viewName,\n    viewDisplayName,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/divider/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Divider } from \"@illa-design/react\"\nimport { PanelDividerProps } from \"./interface\"\nimport { applyPanelDividerCss } from \"./style\"\n\nexport const PanelDivider: FC<PanelDividerProps> = (props) => {\n  const { hasMargin = true } = props\n  return (\n    <div css={applyPanelDividerCss(hasMargin)}>\n      <Divider />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/divider/interface.ts",
    "content": "export interface PanelDividerProps {\n  hasMargin?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/divider/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const applyPanelDividerCss = (hasMargin: boolean) => {\n  return css`\n    padding: 0 16px;\n    margin-top: ${hasMargin ? \"8px\" : 0};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/leftAndRight/index.tsx",
    "content": "import { FC } from \"react\"\nimport { LeftAndRightLayoutProps } from \"./interface\"\nimport { leftAndRightCss } from \"./style\"\n\nexport const LeftAndRightLayout: FC<LeftAndRightLayoutProps> = (props) => {\n  const { children } = props\n  return <div css={leftAndRightCss}>{children}</div>\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/leftAndRight/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface LeftAndRightLayoutProps {\n  children?: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/leftAndRight/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const leftAndRightCss = css`\n  min-height: 40px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 0 16px;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/setterPadding/index.tsx",
    "content": "import { FC } from \"react\"\nimport { SetterPaddingLayout } from \"./interface\"\nimport { setterPaddingStyle } from \"./style\"\n\nexport const SetterPadding: FC<SetterPaddingLayout> = (props) => {\n  const { children } = props\n  return <div css={setterPaddingStyle}>{children}</div>\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/setterPadding/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface SetterPaddingLayout {\n  children: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/setterPadding/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const setterPaddingStyle = css`\n  padding: 8px 0px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/verticalLayout/index.tsx",
    "content": "import { FC } from \"react\"\nimport { VerticalLayoutProps } from \"./interface\"\nimport { verticalCss } from \"./style\"\n\nexport const VerticalLayout: FC<VerticalLayoutProps> = (props) => {\n  const { children } = props\n  return <div css={verticalCss}>{children}</div>\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/verticalLayout/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface VerticalLayoutProps {\n  children?: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Layout/verticalLayout/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const verticalCss = css`\n  min-height: 40px;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-between;\n  padding: 0 16px;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Basic/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { ComponentMapNode } from \"@illa-public/public-types\"\nimport { FC, useCallback, useEffect, useMemo, useRef } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Input, Switch } from \"@illa-design/react\"\nimport { PanelBar } from \"@/components/PanelBar\"\nimport { PageLabel } from \"@/page/App/components/PagePanel/Components/Label\"\nimport { ViewList } from \"@/page/App/components/PagePanel/Components/ViewsList\"\nimport { PanelDivider } from \"@/page/App/components/PagePanel/Layout/divider\"\nimport { LeftAndRightLayout } from \"@/page/App/components/PagePanel/Layout/leftAndRight\"\nimport { SetterPadding } from \"@/page/App/components/PagePanel/Layout/setterPadding\"\nimport { VerticalLayout } from \"@/page/App/components/PagePanel/Layout/verticalLayout\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { PageNodeProps } from \"@/redux/currentApp/components/componentsState\"\nimport { getRootNodeExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { placePaddingStyle } from \"./style\"\n\nexport const PageBasic: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const rootExecutionProps = useSelector(getRootNodeExecutionResult)\n  const homepageControlRef = useRef<HTMLButtonElement>(null)\n  const isReportFlag = useRef<boolean>(false)\n\n  const intersectionObserver = useRef<IntersectionObserver | null>(\n    new IntersectionObserver((entries) => {\n      entries.forEach((entry) => {\n        if (entry.isIntersecting) {\n          if (isReportFlag.current) return\n          trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n            element: \"homepage_switch\",\n          })\n          isReportFlag.current = true\n        }\n      })\n    }),\n  )\n  const { currentPageIndex, pageSortedKey, homepageDisplayName } =\n    rootExecutionProps\n\n  useEffect(() => {\n    const homepageControlValue = homepageControlRef.current\n    const intersectionObserverValue = intersectionObserver.current\n    if (!homepageControlValue) return\n    intersectionObserverValue?.observe(homepageControlValue)\n    return () => {\n      if (!homepageControlValue) return\n      intersectionObserverValue?.unobserve(homepageControlValue)\n      isReportFlag.current = false\n    }\n  }, [currentPageIndex])\n\n  const currentPageDisplayName = pageSortedKey[currentPageIndex]\n\n  const pageProps = useSelector<RootState>((state) => {\n    const components = getComponentMap(state)\n    return (\n      searchComponentFromMap(components, currentPageDisplayName)?.props || {}\n    )\n  }) as PageNodeProps\n\n  const sectionNodes = useSelector<RootState, ComponentMapNode[] | null>(\n    (state) => {\n      const components = getComponentMap(state)\n      const currentPageNode = searchComponentFromMap(\n        components,\n        currentPageDisplayName,\n      )\n      if (!currentPageNode) return null\n      return currentPageNode.childrenNode.map(\n        (displayName) => components[displayName],\n      )\n    },\n  )\n\n  const { hasLeft, hasRight, hasFooter, hasHeader } = pageProps\n  const isHomepage = useMemo(() => {\n    return homepageDisplayName\n      ? homepageDisplayName === currentPageDisplayName\n      : currentPageDisplayName === \"page1\"\n  }, [currentPageDisplayName, homepageDisplayName])\n\n  const handleChangeIsHomePage = useCallback(() => {\n    if (currentPageDisplayName !== homepageDisplayName) {\n      dispatch(\n        componentsActions.updateRootNodePropsReducer({\n          homepageDisplayName: currentPageDisplayName,\n          currentPageIndex: currentPageIndex,\n        }),\n      )\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n        element: \"homepage_switch\",\n      })\n    }\n  }, [currentPageDisplayName, currentPageIndex, dispatch, homepageDisplayName])\n\n  const targetDefaultViewValue = useCallback(\n    (showName: string) => {\n      if (!Array.isArray(sectionNodes)) return \"\"\n      const targetSectionNodeDisplayName = sectionNodes.find((node) => {\n        return node.showName === showName\n      })\n      if (!targetSectionNodeDisplayName) return \"\"\n      return targetSectionNodeDisplayName.props!.defaultViewKey\n    },\n    [sectionNodes],\n  )\n\n  const handleChangeDefaultView = useCallback(\n    (value: string, showName: string) => {\n      if (!Array.isArray(sectionNodes)) return\n      const targetSectionNode = sectionNodes.find((node) => {\n        return node.showName === showName\n      })\n      if (!targetSectionNode) return\n      dispatch(\n        componentsActions.updateSectionViewPropsReducer({\n          parentNodeName: targetSectionNode.displayName,\n          newProps: {\n            defaultViewKey: value,\n          },\n        }),\n      )\n    },\n    [dispatch, sectionNodes],\n  )\n\n  return (\n    <PanelBar title={t(\"editor.page.panel_bar_title.basic\")}>\n      <LeftAndRightLayout>\n        <PageLabel\n          labelName={t(\"editor.page.label_name.set_as_homepage\")}\n          size=\"big\"\n        />\n        <SetterPadding>\n          <Switch\n            checked={isHomepage}\n            onChange={handleChangeIsHomePage}\n            colorScheme=\"techPurple\"\n            ref={homepageControlRef}\n          />\n        </SetterPadding>\n      </LeftAndRightLayout>\n      <LeftAndRightLayout>\n        <SetterPadding>\n          <div css={placePaddingStyle}>\n            <PageLabel\n              labelName={t(\"editor.page.label_name.body\")}\n              size=\"big\"\n            />\n          </div>\n          <ViewList sectionName=\"bodySection\" />\n        </SetterPadding>\n      </LeftAndRightLayout>\n      <SetterPadding>\n        <VerticalLayout>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.default_view\")}\n            size=\"small\"\n          />\n          <Input\n            value={targetDefaultViewValue(\"bodySection\")}\n            onChange={(value) => {\n              handleChangeDefaultView(value, \"bodySection\")\n            }}\n            colorScheme=\"techPurple\"\n          />\n        </VerticalLayout>\n      </SetterPadding>\n\n      {hasLeft && (\n        <>\n          <PanelDivider />\n          <LeftAndRightLayout>\n            <SetterPadding>\n              <div css={placePaddingStyle}>\n                <PageLabel\n                  labelName={t(\"editor.page.label_name.left_panel\")}\n                  size=\"big\"\n                />\n              </div>\n              <ViewList sectionName=\"leftSection\" />\n            </SetterPadding>\n          </LeftAndRightLayout>\n          <SetterPadding>\n            <VerticalLayout>\n              <PageLabel\n                labelName={t(\"editor.page.label_name.default_view\")}\n                size=\"small\"\n              />\n              <Input\n                value={targetDefaultViewValue(\"leftSection\")}\n                onChange={(value) => {\n                  handleChangeDefaultView(value, \"leftSection\")\n                }}\n                colorScheme=\"techPurple\"\n              />\n            </VerticalLayout>\n          </SetterPadding>\n        </>\n      )}\n      {hasRight && (\n        <>\n          <PanelDivider />\n          <LeftAndRightLayout>\n            <SetterPadding>\n              <div css={placePaddingStyle}>\n                <PageLabel\n                  labelName={t(\"editor.page.label_name.right_panel\")}\n                  size=\"big\"\n                />\n              </div>\n              <ViewList sectionName=\"rightSection\" />\n            </SetterPadding>\n          </LeftAndRightLayout>\n          <SetterPadding>\n            <VerticalLayout>\n              <PageLabel\n                labelName={t(\"editor.page.label_name.default_view\")}\n                size=\"small\"\n              />\n              <Input\n                value={targetDefaultViewValue(\"rightSection\")}\n                onChange={(value) => {\n                  handleChangeDefaultView(value, \"rightSection\")\n                }}\n                colorScheme=\"techPurple\"\n              />\n            </VerticalLayout>\n          </SetterPadding>\n        </>\n      )}\n      {hasHeader && (\n        <>\n          <PanelDivider />\n          <LeftAndRightLayout>\n            <SetterPadding>\n              <div css={placePaddingStyle}>\n                <PageLabel\n                  labelName={t(\"editor.page.label_name.header\")}\n                  size=\"big\"\n                />\n              </div>\n              <ViewList sectionName=\"headerSection\" />\n            </SetterPadding>\n          </LeftAndRightLayout>\n          <SetterPadding>\n            <VerticalLayout>\n              <PageLabel\n                labelName={t(\"editor.page.label_name.default_view\")}\n                size=\"small\"\n              />\n              <Input\n                value={targetDefaultViewValue(\"headerSection\")}\n                onChange={(value) => {\n                  handleChangeDefaultView(value, \"headerSection\")\n                }}\n                colorScheme=\"techPurple\"\n              />\n            </VerticalLayout>\n          </SetterPadding>\n        </>\n      )}\n      {hasFooter && (\n        <>\n          <PanelDivider />\n          <LeftAndRightLayout>\n            <SetterPadding>\n              <div css={placePaddingStyle}>\n                <PageLabel\n                  labelName={t(\"editor.page.label_name.footer\")}\n                  size=\"big\"\n                />\n              </div>\n              <ViewList sectionName=\"footerSection\" />\n            </SetterPadding>\n          </LeftAndRightLayout>\n          <SetterPadding>\n            <VerticalLayout>\n              <PageLabel\n                labelName={t(\"editor.page.label_name.default_view\")}\n                size=\"small\"\n              />\n              <Input\n                value={targetDefaultViewValue(\"footerSection\")}\n                onChange={(value) => {\n                  handleChangeDefaultView(value, \"footerSection\")\n                }}\n                colorScheme=\"techPurple\"\n              />\n            </VerticalLayout>\n          </SetterPadding>\n        </>\n      )}\n    </PanelBar>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Basic/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const placePaddingStyle = css`\n  padding-bottom: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Frame/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport {\n  FC,\n  FocusEvent,\n  useCallback,\n  useEffect,\n  useMemo,\n  useState,\n} from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  InputNumber,\n  RadioGroup,\n  Switch,\n  useMessage,\n  useModal,\n} from \"@illa-design/react\"\nimport FrameFixedIcon from \"@/assets/rightPagePanel/frame-fixed.svg?react\"\nimport FrameResponsiveIcon from \"@/assets/rightPagePanel/frame-responsive.svg?react\"\nimport { PanelBar } from \"@/components/PanelBar\"\nimport i18n from \"@/i18n/config\"\nimport {\n  BODY_MIN_HEIGHT,\n  BODY_MIN_WIDTH,\n  DEFAULT_PERCENT_WIDTH,\n  DEFAULT_PX_WIDTH,\n  FOOTER_MIN_HEIGHT,\n  HEADER_MIN_HEIGHT,\n  LEFT_MIN_WIDTH,\n  RIGHT_MIN_WIDTH,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { PageLabel } from \"@/page/App/components/PagePanel/Components/Label\"\nimport { LayoutSelect } from \"@/page/App/components/PagePanel/Components/LayoutSelect\"\nimport { PanelActionBar } from \"@/page/App/components/PagePanel/Components/PanelActionBar\"\nimport { PanelDivider } from \"@/page/App/components/PagePanel/Layout/divider\"\nimport { LeftAndRightLayout } from \"@/page/App/components/PagePanel/Layout/leftAndRight\"\nimport { SetterPadding } from \"@/page/App/components/PagePanel/Layout/setterPadding\"\nimport { optionListWrapperStyle } from \"@/page/App/components/PagePanel/style\"\nimport { getCanvasShape } from \"@/redux/config/configSelector\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { PageNodeProps } from \"@/redux/currentApp/components/componentsState\"\nimport { getRootNodeExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { RootState } from \"@/store\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { groupWrapperStyle } from \"./style\"\n\nconst getRealCanvasWidth = (canvasWidth: unknown) => {\n  if (typeof canvasWidth !== \"number\") return 100\n  return canvasWidth\n}\n\nconst canvasSizeOptions = [\n  {\n    label: (\n      <div css={optionListWrapperStyle}>\n        <FrameResponsiveIcon />\n        <span>{i18n.t(\"page.size.model.auto\")}</span>\n      </div>\n    ),\n    value: \"auto\",\n  },\n  {\n    label: (\n      <div css={optionListWrapperStyle}>\n        <FrameFixedIcon />\n        <span>{i18n.t(\"page.size.model.fixed\")}</span>\n      </div>\n    ),\n    value: \"fixed\",\n  },\n]\n\nexport const PageFrame: FC = () => {\n  const { t } = useTranslation()\n  const rootNodeProps = useSelector(getRootNodeExecutionResult)\n  const { currentPageIndex, pageSortedKey } = rootNodeProps\n  const currentPageDisplayName = pageSortedKey[currentPageIndex]\n  const pageProps = useSelector<RootState>((state) => {\n    const components = getComponentMap(state)\n    return (\n      searchComponentFromMap(components, currentPageDisplayName)?.props || {}\n    )\n  }) as PageNodeProps\n  const message = useMessage()\n\n  const canvasShape = useSelector(getCanvasShape)\n  const dispatch = useDispatch()\n  const {\n    canvasSize,\n    canvasWidth,\n    layout,\n    leftWidth,\n    rightWidth,\n    isLeftFixed,\n    isRightFixed,\n    isFooterFixed,\n    isHeaderFixed,\n    hasLeft,\n    hasRight,\n    hasFooter,\n    hasHeader,\n    showLeftFoldIcon,\n    showRightFoldIcon,\n  } = pageProps\n  const [finalLeftWidth, setFinalLeftWidth] = useState(hasLeft ? leftWidth : 0)\n  const [finalRightWidth, setFinalRightWidth] = useState(\n    hasRight ? rightWidth : 0,\n  )\n\n  useEffect(() => {\n    setFinalLeftWidth(leftWidth)\n  }, [leftWidth])\n\n  useEffect(() => {\n    setFinalRightWidth(rightWidth)\n  }, [rightWidth])\n\n  const bodyWidth = useMemo(() => {\n    if (canvasSize === \"fixed\")\n      return (\n        canvasWidth - (hasLeft ? leftWidth : 0) - (hasRight ? rightWidth : 0)\n      )\n    return 100 - (hasLeft ? leftWidth : 0) - (hasRight ? rightWidth : 0)\n  }, [canvasSize, canvasWidth, hasLeft, hasRight, leftWidth, rightWidth])\n\n  const [finalBodyWidth, setFinalBodyWidth] = useState(bodyWidth)\n\n  useEffect(() => {\n    setFinalBodyWidth(bodyWidth)\n  }, [bodyWidth])\n\n  const [finalCanvasWidth, setFinalCanvasWidth] = useState(\n    getRealCanvasWidth(canvasWidth),\n  )\n\n  useEffect(() => {\n    setFinalCanvasWidth(getRealCanvasWidth(canvasWidth))\n  }, [canvasWidth])\n\n  const finalCanvasSize = canvasSize === \"fixed\" ? \"fixed\" : \"auto\"\n\n  const widthI18n = useMemo(() => {\n    return canvasSize === \"fixed\"\n      ? `${t(\"editor.page.label_name.width\")}(px)`\n      : `${t(\"editor.page.label_name.width\")}(%)`\n  }, [canvasSize, t])\n\n  const modal = useModal()\n\n  const handleDeleteSection = useCallback(\n    (\n      deleteSectionName:\n        | \"leftSection\"\n        | \"rightSection\"\n        | \"headerSection\"\n        | \"footerSection\",\n    ) => {\n      if (!currentPageDisplayName) return\n      modal.show({\n        w: \"496px\",\n        children: t(\"editor.page.model_tips.delete_section_message\"),\n        cancelText: t(\"editor.page.model_tips.cancel_button\"),\n        okText: t(\"editor.page.model_tips.ok_button\"),\n        okButtonProps: {\n          colorScheme: \"red\",\n        },\n        closable: false,\n        onOk: () => {\n          dispatch(\n            componentsActions.deleteTargetPageSectionReducer({\n              pageName: currentPageDisplayName,\n              deleteSectionName,\n            }),\n          )\n        },\n      })\n    },\n    [currentPageDisplayName, dispatch, modal, t],\n  )\n\n  const handleAddSection = useCallback(\n    (\n      addedSectionName:\n        | \"leftSection\"\n        | \"rightSection\"\n        | \"headerSection\"\n        | \"footerSection\",\n    ) => {\n      if (!currentPageDisplayName) return\n      dispatch(\n        componentsActions.addTargetPageSectionReducer({\n          pageName: currentPageDisplayName,\n          addedSectionName,\n        }),\n      )\n    },\n    [currentPageDisplayName, dispatch],\n  )\n\n  const handleUpdateBodyPanelWidth = useCallback(\n    (value?: number) => {\n      if (!currentPageDisplayName || !value) return\n      setFinalBodyWidth(value)\n    },\n    [currentPageDisplayName],\n  )\n\n  const handleBlurUpdateBodyPanelWidth = useCallback(() => {\n    let finalValue = finalBodyWidth\n    let finalLeftValue = leftWidth\n    let finalRightValue = rightWidth\n    if (canvasSize === \"fixed\") {\n      let currentRightValue = finalRightValue\n      let currentLeftValue = finalLeftValue\n      if (finalValue < BODY_MIN_WIDTH) {\n        finalValue = BODY_MIN_WIDTH\n        currentRightValue =\n          canvasShape.canvasWidth - finalValue - finalLeftValue\n      } else {\n        currentRightValue =\n          canvasShape.canvasWidth - finalValue - finalLeftValue\n      }\n      if (currentRightValue < RIGHT_MIN_WIDTH) {\n        finalRightValue = RIGHT_MIN_WIDTH\n        currentLeftValue =\n          canvasShape.canvasWidth - finalValue - finalRightValue\n      }\n      if (currentLeftValue < LEFT_MIN_WIDTH) {\n        finalLeftValue = LEFT_MIN_WIDTH\n        currentRightValue =\n          canvasShape.canvasWidth - finalValue - finalLeftValue\n      }\n      if (\n        currentLeftValue < LEFT_MIN_WIDTH &&\n        currentRightValue < RIGHT_MIN_WIDTH\n      ) {\n        finalLeftValue = LEFT_MIN_WIDTH\n        finalRightValue = RIGHT_MIN_WIDTH\n      }\n      setFinalBodyWidth(\n        canvasShape.canvasWidth - finalLeftValue - finalRightValue,\n      )\n    } else {\n      let finalLeftValuePX = (finalLeftValue / 100) * canvasShape.canvasWidth\n      let finalRightValuePX = (finalRightValue / 100) * canvasShape.canvasWidth\n      let finalValuePX = (finalValue / 100) * canvasShape.canvasWidth\n      if (finalValuePX <= BODY_MIN_HEIGHT) {\n        const restWidth = canvasShape.canvasWidth - BODY_MIN_HEIGHT\n        finalLeftValuePX =\n          (finalLeftValuePX / (finalLeftValuePX + finalRightValuePX)) *\n          restWidth\n        finalRightValuePX = restWidth - finalLeftValuePX\n        finalLeftValue = (finalLeftValuePX / canvasShape.canvasWidth) * 100\n        finalRightValue = (finalRightValuePX / canvasShape.canvasWidth) * 100\n      } else {\n        let restWidth = canvasShape.canvasWidth - finalValuePX\n        finalLeftValuePX =\n          (finalLeftValuePX / (finalLeftValuePX + finalRightValuePX)) *\n          restWidth\n        if (finalLeftValuePX < LEFT_MIN_WIDTH) {\n          finalLeftValuePX = LEFT_MIN_WIDTH\n        }\n        finalRightValuePX = restWidth - finalLeftValuePX\n        if (finalRightValuePX < RIGHT_MIN_WIDTH) {\n          finalRightValuePX = LEFT_MIN_WIDTH\n        }\n        finalLeftValue = (finalLeftValuePX / canvasShape.canvasWidth) * 100\n        finalRightValue = (RIGHT_MIN_WIDTH / canvasShape.canvasWidth) * 100\n      }\n      setFinalBodyWidth((1 - finalLeftValue - finalRightValue) * 100)\n    }\n\n    dispatch(\n      componentsActions.updateTargetPagePropsReducer({\n        pageName: currentPageDisplayName,\n        newProps: {\n          leftWidth: finalLeftValue,\n          rightWidth: finalRightValue,\n        },\n      }),\n    )\n  }, [\n    canvasShape.canvasWidth,\n    canvasSize,\n    currentPageDisplayName,\n    dispatch,\n    finalBodyWidth,\n    leftWidth,\n    rightWidth,\n  ])\n\n  const handleUpdateLeftPanelWidth = (value?: number) => {\n    if (!value) return\n    setFinalLeftWidth(value)\n  }\n\n  const handleBlurUpdateLeftPanelWidth = useCallback(\n    (e: FocusEvent<HTMLInputElement, Element>) => {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n        element: \"panel_width\",\n        parameter2: \"left\",\n        parameter3: e.target.value,\n      })\n\n      let finalValue = finalLeftWidth\n      if (canvasSize === \"fixed\") {\n        if (\n          canvasShape.canvasWidth - finalValue - finalRightWidth <\n          BODY_MIN_WIDTH\n        ) {\n          finalValue =\n            canvasShape.canvasWidth - BODY_MIN_WIDTH - finalRightWidth\n        }\n        if (finalValue < LEFT_MIN_WIDTH) {\n          finalValue = LEFT_MIN_WIDTH\n        }\n      } else {\n        const leftWidthPX = (finalLeftWidth / 100) * canvasShape.canvasWidth\n        const currentRightWidthPX =\n          (finalRightWidth / 100) * canvasShape.canvasWidth\n        if (\n          canvasShape.canvasWidth - leftWidthPX - currentRightWidthPX <\n          BODY_MIN_WIDTH\n        ) {\n          finalValue =\n            ((canvasShape.canvasWidth - currentRightWidthPX - BODY_MIN_WIDTH) /\n              canvasShape.canvasWidth) *\n            100\n        }\n        if ((finalValue / 100) * canvasShape.canvasWidth < LEFT_MIN_WIDTH) {\n          finalValue = (LEFT_MIN_WIDTH / canvasShape.canvasWidth) * 100\n        }\n      }\n\n      dispatch(\n        componentsActions.updateTargetPagePropsReducer({\n          pageName: currentPageDisplayName,\n          newProps: {\n            leftWidth: finalValue,\n          },\n        }),\n      )\n      setFinalLeftWidth(finalValue)\n    },\n    [\n      canvasShape.canvasWidth,\n      canvasSize,\n      currentPageDisplayName,\n      dispatch,\n      finalLeftWidth,\n      finalRightWidth,\n    ],\n  )\n\n  const handleUpdateRightPanelWidth = (value?: number) => {\n    if (!value) return\n    setFinalRightWidth(value)\n  }\n\n  const handleBlurUpdateRightPanelWidth = useCallback(\n    (e: FocusEvent<HTMLInputElement, Element>) => {\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n        element: \"panel_width\",\n        parameter2: \"left\",\n        parameter3: e.target.value,\n      })\n\n      let finalValue = finalLeftWidth\n      if (canvasSize === \"fixed\") {\n        if (\n          canvasShape.canvasWidth - finalValue - finalLeftWidth <\n          BODY_MIN_WIDTH\n        ) {\n          finalValue = canvasShape.canvasWidth - BODY_MIN_WIDTH - finalLeftWidth\n        }\n        if (finalValue < RIGHT_MIN_WIDTH) {\n          finalValue = RIGHT_MIN_WIDTH\n        }\n      } else {\n        const rightWidthPX = (finalLeftWidth / 100) * canvasShape.canvasWidth\n        const currentLeftWidthPX = (leftWidth / 100) * canvasShape.canvasWidth\n        if (\n          canvasShape.canvasWidth - rightWidthPX - currentLeftWidthPX <\n          BODY_MIN_WIDTH\n        ) {\n          finalValue =\n            ((canvasShape.canvasWidth - currentLeftWidthPX - BODY_MIN_WIDTH) /\n              canvasShape.canvasWidth) *\n            100\n        }\n        if ((finalValue / 100) * canvasShape.canvasWidth < RIGHT_MIN_WIDTH) {\n          finalValue = (RIGHT_MIN_WIDTH / canvasShape.canvasWidth) * 100\n        }\n      }\n\n      dispatch(\n        componentsActions.updateTargetPagePropsReducer({\n          pageName: currentPageDisplayName,\n          newProps: {\n            rightWidth: finalValue,\n          },\n        }),\n      )\n    },\n    [\n      canvasShape.canvasWidth,\n      canvasSize,\n      currentPageDisplayName,\n      dispatch,\n      finalLeftWidth,\n      leftWidth,\n    ],\n  )\n\n  const handleUpdateShowFoldIcon = useCallback(\n    (value: boolean, sectionName: string) => {\n      if (!currentPageDisplayName) return\n      const newProps =\n        sectionName === \"leftSection\"\n          ? {\n              showLeftFoldIcon: value,\n            }\n          : { showRightFoldIcon: value }\n      dispatch(\n        componentsActions.updateTargetPagePropsReducer({\n          pageName: currentPageDisplayName,\n          newProps,\n        }),\n      )\n    },\n    [currentPageDisplayName, dispatch],\n  )\n\n  const handleUpdateFrameSize = useCallback(\n    (value: \"auto\" | \"fixed\") => {\n      if (canvasSize === value || !currentPageDisplayName) return\n      const newProps: Partial<PageNodeProps> = {\n        canvasSize: value,\n        canvasWidth:\n          value === \"fixed\"\n            ? DEFAULT_PX_WIDTH.CANVAS\n            : DEFAULT_PERCENT_WIDTH.CANVAS,\n        leftWidth: 0,\n        rightWidth: 0,\n      }\n      if (value === \"fixed\") {\n        if (hasLeft) newProps.leftWidth = DEFAULT_PX_WIDTH.LEFT\n        if (hasRight) newProps.rightWidth = DEFAULT_PX_WIDTH.RIGHT\n      } else {\n        if (hasLeft) newProps.leftWidth = DEFAULT_PERCENT_WIDTH.LEFT\n        if (hasRight) newProps.rightWidth = DEFAULT_PERCENT_WIDTH.RIGHT\n      }\n      dispatch(\n        componentsActions.updateTargetPagePropsReducer({\n          pageName: currentPageDisplayName,\n          newProps,\n        }),\n      )\n    },\n    [canvasSize, currentPageDisplayName, dispatch, hasLeft, hasRight],\n  )\n\n  const handleChangeCanvasWidth = useCallback(\n    (value?: number) => {\n      if (!currentPageDisplayName || value == undefined) return\n      setFinalCanvasWidth(value)\n    },\n    [currentPageDisplayName],\n  )\n\n  const handleBlurCanvasWidth = useCallback(() => {\n    if (canvasSize === \"fixed\") {\n      if (\n        finalCanvasWidth <\n        BODY_MIN_WIDTH + LEFT_MIN_WIDTH + RIGHT_MIN_WIDTH\n      ) {\n        message.error({\n          content: t(\"frame_size.invalid_tips\", {\n            size: BODY_MIN_HEIGHT + HEADER_MIN_HEIGHT + FOOTER_MIN_HEIGHT,\n          }),\n        })\n        dispatch(\n          componentsActions.updateTargetPagePropsReducer({\n            pageName: currentPageDisplayName,\n            newProps: {\n              canvasWidth: BODY_MIN_WIDTH + LEFT_MIN_WIDTH + RIGHT_MIN_WIDTH,\n              leftWidth: LEFT_MIN_WIDTH,\n              rightWidth: RIGHT_MIN_WIDTH,\n            },\n          }),\n        )\n        setFinalCanvasWidth(BODY_MIN_WIDTH + LEFT_MIN_WIDTH + RIGHT_MIN_WIDTH)\n      } else {\n        dispatch(\n          componentsActions.updateTargetPagePropsReducer({\n            pageName: currentPageDisplayName,\n            newProps: {\n              canvasWidth: finalCanvasWidth,\n            },\n          }),\n        )\n      }\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n        element: \"page_width\",\n        parameter2: \"fixed\",\n        parameter3: canvasWidth,\n      })\n    } else {\n      const originalWidth = canvasShape.canvasWidth / (canvasWidth / 100)\n      const currentWidth = originalWidth * (finalCanvasWidth / 100)\n      if (currentWidth < BODY_MIN_WIDTH + LEFT_MIN_WIDTH + RIGHT_MIN_WIDTH) {\n        const minWidth =\n          (BODY_MIN_WIDTH + LEFT_MIN_WIDTH + RIGHT_MIN_WIDTH) /\n          (originalWidth / 100)\n        message.error({\n          content: t(\"frame_size.invalid_tips\", {\n            size: minWidth.toFixed(0),\n          }),\n        })\n        dispatch(\n          componentsActions.updateTargetPagePropsReducer({\n            pageName: currentPageDisplayName,\n            newProps: {\n              canvasWidth: minWidth,\n            },\n          }),\n        )\n        setFinalCanvasWidth(minWidth)\n      } else {\n        dispatch(\n          componentsActions.updateTargetPagePropsReducer({\n            pageName: currentPageDisplayName,\n            newProps: {\n              canvasWidth: finalCanvasWidth,\n            },\n          }),\n        )\n      }\n      trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.BLUR, {\n        element: \"page_width\",\n        parameter2: \"auto\",\n        parameter3: canvasWidth,\n      })\n    }\n  }, [\n    canvasShape.canvasWidth,\n    canvasSize,\n    canvasWidth,\n    currentPageDisplayName,\n    dispatch,\n    finalCanvasWidth,\n    message,\n    t,\n  ])\n\n  return (\n    <PanelBar title={t(\"editor.page.panel_bar_title.frame\")}>\n      <LeftAndRightLayout>\n        <RadioGroup\n          type=\"button\"\n          options={canvasSizeOptions}\n          value={finalCanvasSize}\n          w=\"100%\"\n          forceEqualWidth={true}\n          colorScheme=\"grayBlue\"\n          onChange={handleUpdateFrameSize}\n        />\n      </LeftAndRightLayout>\n      <LeftAndRightLayout>\n        <PageLabel\n          labelName={widthI18n}\n          size=\"big\"\n          tooltip={\n            finalCanvasSize !== \"fixed\"\n              ? t(\"editor.page.tooltips.auto_canvas_width\")\n              : undefined\n          }\n        />\n        <SetterPadding>\n          <InputNumber\n            w=\"96px\"\n            precision={0}\n            step={1}\n            value={Number(finalCanvasWidth.toFixed(0))}\n            colorScheme=\"techPurple\"\n            onChange={handleChangeCanvasWidth}\n            onBlur={handleBlurCanvasWidth}\n          />\n        </SetterPadding>\n      </LeftAndRightLayout>\n      <PanelDivider />\n      <div css={groupWrapperStyle}>\n        <LeftAndRightLayout>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.preset\")}\n            size=\"big\"\n          />\n          <SetterPadding>\n            <LayoutSelect\n              value={layout}\n              currentPageName={currentPageDisplayName}\n            />\n          </SetterPadding>\n        </LeftAndRightLayout>\n      </div>\n      <PanelDivider hasMargin={false} />\n      <div css={groupWrapperStyle}>\n        <LeftAndRightLayout>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.left_panel\")}\n            size=\"big\"\n          />\n          <PanelActionBar\n            isFixed={isLeftFixed}\n            hasPanel={hasLeft}\n            deletePanelAction={() => {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"panel_show\",\n                parameter2: \"left\",\n                parameter3: \"hidden\",\n              })\n              handleDeleteSection(\"leftSection\")\n            }}\n            addPanelAction={() => {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"panel_show\",\n                parameter2: \"left\",\n                parameter3: \"show\",\n              })\n              handleAddSection(\"leftSection\")\n            }}\n          />\n        </LeftAndRightLayout>\n        {hasLeft && (\n          <>\n            <LeftAndRightLayout>\n              <PageLabel labelName={widthI18n} size=\"small\" />\n              <SetterPadding>\n                <InputNumber\n                  w=\"96px\"\n                  value={Number(finalLeftWidth.toFixed(0))}\n                  precision={0}\n                  colorScheme=\"techPurple\"\n                  onChange={handleUpdateLeftPanelWidth}\n                  step={1}\n                  onBlur={handleBlurUpdateLeftPanelWidth}\n                />\n              </SetterPadding>\n            </LeftAndRightLayout>\n            <LeftAndRightLayout>\n              <PageLabel\n                labelName={t(\"editor.page.label_name.show_fold_icon\")}\n                size=\"small\"\n                tooltip={t(\"editor.page.tooltips.show_fold_icon\")}\n              />\n              <SetterPadding>\n                <Switch\n                  checked={showLeftFoldIcon}\n                  onChange={(value) => {\n                    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                      element: \"panel_fold\",\n                      parameter2: \"left\",\n                      parameter3: value ? \"show\" : \"hidden\",\n                    })\n                    handleUpdateShowFoldIcon(value, \"leftSection\")\n                  }}\n                  colorScheme=\"techPurple\"\n                />\n              </SetterPadding>\n            </LeftAndRightLayout>\n          </>\n        )}\n      </div>\n      <PanelDivider hasMargin={false} />\n      <div css={groupWrapperStyle}>\n        <LeftAndRightLayout>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.right_panel\")}\n            size=\"big\"\n          />\n          <PanelActionBar\n            isFixed={isRightFixed}\n            hasPanel={hasRight}\n            deletePanelAction={() => {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"panel_show\",\n                parameter2: \"right\",\n                parameter3: \"hidden\",\n              })\n              handleDeleteSection(\"rightSection\")\n            }}\n            addPanelAction={() => {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"panel_show\",\n                parameter2: \"right\",\n                parameter3: \"show\",\n              })\n              handleAddSection(\"rightSection\")\n            }}\n          />\n        </LeftAndRightLayout>\n        {hasRight && (\n          <>\n            <LeftAndRightLayout>\n              <PageLabel labelName={widthI18n} size=\"small\" />\n              <SetterPadding>\n                <InputNumber\n                  w=\"96px\"\n                  precision={0}\n                  value={Number(finalRightWidth.toFixed(0))}\n                  colorScheme=\"techPurple\"\n                  onChange={handleUpdateRightPanelWidth}\n                  step={1}\n                  onBlur={handleBlurUpdateRightPanelWidth}\n                />\n              </SetterPadding>\n            </LeftAndRightLayout>\n            <LeftAndRightLayout>\n              <PageLabel\n                labelName={t(\"editor.page.label_name.show_fold_icon\")}\n                size=\"small\"\n                tooltip={t(\"editor.page.tooltips.show_fold_icon\")}\n              />\n              <SetterPadding>\n                <Switch\n                  checked={showRightFoldIcon}\n                  onChange={(value) => {\n                    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                      element: \"panel_fold\",\n                      parameter2: \"right\",\n                      parameter3: value ? \"show\" : \"hidden\",\n                    })\n                    handleUpdateShowFoldIcon(value, \"rightSection\")\n                  }}\n                  colorScheme=\"techPurple\"\n                />\n              </SetterPadding>\n            </LeftAndRightLayout>\n          </>\n        )}\n      </div>\n\n      <PanelDivider hasMargin={false} />\n      <div css={groupWrapperStyle}>\n        <LeftAndRightLayout>\n          <PageLabel labelName={t(\"editor.page.label_name.body\")} size=\"big\" />\n        </LeftAndRightLayout>\n        <LeftAndRightLayout>\n          <PageLabel labelName={widthI18n} size=\"small\" />\n          <SetterPadding>\n            <InputNumber\n              w=\"96px\"\n              precision={0}\n              colorScheme=\"techPurple\"\n              value={Number(finalBodyWidth.toFixed(0))}\n              onChange={handleUpdateBodyPanelWidth}\n              onBlur={handleBlurUpdateBodyPanelWidth}\n              step={1}\n              disabled={!hasLeft && !hasRight}\n            />\n          </SetterPadding>\n        </LeftAndRightLayout>\n      </div>\n      <PanelDivider hasMargin={false} />\n      <div css={groupWrapperStyle}>\n        <LeftAndRightLayout>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.header\")}\n            size=\"big\"\n          />\n          <PanelActionBar\n            isFixed={isHeaderFixed}\n            hasPanel={hasHeader}\n            deletePanelAction={() => {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"panel_show\",\n                parameter2: \"header\",\n                parameter3: \"hidden\",\n              })\n              handleDeleteSection(\"headerSection\")\n            }}\n            addPanelAction={() => {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"panel_show\",\n                parameter2: \"header\",\n                parameter3: \"show\",\n              })\n              handleAddSection(\"headerSection\")\n            }}\n          />\n        </LeftAndRightLayout>\n      </div>\n      <PanelDivider hasMargin={false} />\n      <div css={groupWrapperStyle}>\n        <LeftAndRightLayout>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.footer\")}\n            size=\"big\"\n          />\n          <PanelActionBar\n            isFixed={isFooterFixed}\n            hasPanel={hasFooter}\n            deletePanelAction={() => {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"panel_show\",\n                parameter2: \"footer\",\n                parameter3: \"hidden\",\n              })\n              handleDeleteSection(\"footerSection\")\n            }}\n            addPanelAction={() => {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"panel_show\",\n                parameter2: \"footer\",\n                parameter3: \"show\",\n              })\n              handleAddSection(\"footerSection\")\n            }}\n          />\n        </LeftAndRightLayout>\n      </div>\n    </PanelBar>\n  )\n}\n\nPageFrame.displayName = \"PageFrame\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Frame/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const groupWrapperStyle = css`\n  padding: 8px 0;\n`\n\nexport const basicPaddingStyle = css`\n  width: 100%;\n  padding: 0 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/AddSection/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport {\n  DropList,\n  DropListItem,\n  DropListProps,\n  Dropdown,\n  getColor,\n} from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport {\n  getCurrentPageExecutionResult,\n  getCurrentPageFooterSection,\n  getCurrentPageHeaderSection,\n  getCurrentPageLeftSection,\n  getCurrentPageRightSection,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { AddSectionProps } from \"./interface\"\n\nexport const AddSection: FC<AddSectionProps> = ({ children }) => {\n  const dispatch = useDispatch()\n\n  const currentPage = useSelector(getCurrentPageExecutionResult)\n  const { displayName, hasFooter, hasLeft, hasRight, hasHeader } = currentPage\n\n  const rightSection = useSelector(getCurrentPageRightSection)\n  const leftSection = useSelector(getCurrentPageLeftSection)\n  const headerSection = useSelector(getCurrentPageHeaderSection)\n  const footerSection = useSelector(getCurrentPageFooterSection)\n  const { style: rightStyle } = rightSection ?? {}\n  const { style: leftStyle } = leftSection ?? {}\n  const { style: headerStyle } = headerSection ?? {}\n  const { style: footerStyle } = footerSection ?? {}\n\n  const hasLeftDivider = !!leftStyle?.dividerColor\n  const hasRightDivider = !!rightStyle?.dividerColor\n  const hasHeaderDivider = !!headerStyle?.dividerColor\n  const hasFooterDivider = !!footerStyle?.dividerColor\n\n  const SECTION_OPTIONS = [\n    {\n      label: i18n.t(\"editor.page.label_name.left_panel\"),\n      value: \"leftSection\",\n      disabled: !hasLeft || hasLeftDivider,\n    },\n    {\n      label: i18n.t(\"editor.page.label_name.right_panel\"),\n      value: \"rightSection\",\n      disabled: !hasRight || hasRightDivider,\n    },\n    {\n      label: i18n.t(\"editor.page.label_name.header\"),\n      value: \"headerSection\",\n      disabled: !hasHeader || hasHeaderDivider,\n    },\n    {\n      label: i18n.t(\"editor.page.label_name.footer\"),\n      value: \"footerSection\",\n      disabled: !hasFooter || hasFooterDivider,\n    },\n  ]\n\n  const onClickItem: DropListProps[\"onClickItem\"] = (key) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          dividerColor: getColor(\"grayBlue\", \"08\"),\n        },\n        sectionName: key as\n          | \"leftSection\"\n          | \"rightSection\"\n          | \"headerSection\"\n          | \"footerSection\"\n          | \"bodySection\",\n      }),\n    )\n  }\n\n  return (\n    <Dropdown\n      position=\"bottom-start\"\n      trigger=\"click\"\n      dropList={\n        <DropList onClickItem={onClickItem}>\n          {SECTION_OPTIONS.map((option) => {\n            return (\n              <DropListItem\n                key={option.label}\n                value={option.value}\n                disabled={option.disabled}\n                colorScheme=\"techPurple\"\n                title={option.label}\n              />\n            )\n          })}\n        </DropList>\n      }\n    >\n      {children}\n    </Dropdown>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/AddSection/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface AddSectionProps {\n  children: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/BackgroundSetter/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport ColorPickerSetter from \"@/components/ColorSetter\"\nimport { PageLabel } from \"@/page/App/components/PagePanel/Components/Label\"\nimport {\n  labelContainerStyle,\n  sectionContainerStyle,\n  setterContainerStyle,\n} from \"@/page/App/components/PagePanel/Modules/Style/style\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport {\n  getCurrentPageBodySection,\n  getCurrentPageExecutionResult,\n  getCurrentPageFooterSection,\n  getCurrentPageHeaderSection,\n  getCurrentPageLeftSection,\n  getCurrentPageRightSection,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\n\nexport const BackgroundSetter: FC = () => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n\n  const currentPage = useSelector(getCurrentPageExecutionResult)\n  const { displayName, hasFooter, hasLeft, hasRight, hasHeader } = currentPage\n\n  const bodySection = useSelector(getCurrentPageBodySection)\n  const rightSection = useSelector(getCurrentPageRightSection)\n  const leftSection = useSelector(getCurrentPageLeftSection)\n  const headerSection = useSelector(getCurrentPageHeaderSection)\n  const footerSection = useSelector(getCurrentPageFooterSection)\n  const { style: bodyStyle } = bodySection ?? {}\n  const { style: rightStyle } = rightSection ?? {}\n  const { style: leftStyle } = leftSection ?? {}\n  const { style: headerStyle } = headerSection ?? {}\n  const { style: footerStyle } = footerSection ?? {}\n\n  const handleChangeLeftBackGroundColor = (value: string) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          background: value,\n        },\n        sectionName: \"leftSection\",\n      }),\n    )\n  }\n  const handleChangeRightBackGroundColor = (value: string) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          background: value,\n        },\n        sectionName: \"rightSection\",\n      }),\n    )\n  }\n  const handleChangeBodyBackGroundColor = (value: string) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          background: value,\n        },\n        sectionName: \"bodySection\",\n      }),\n    )\n  }\n  const handleChangeHeaderBackGroundColor = (value: string) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          background: value,\n        },\n        sectionName: \"headerSection\",\n      }),\n    )\n  }\n  const handleChangeFooterBackGroundColor = (value: string) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          background: value,\n        },\n        sectionName: \"footerSection\",\n      }),\n    )\n  }\n\n  return (\n    <section css={sectionContainerStyle}>\n      <div css={labelContainerStyle}>\n        <PageLabel\n          labelName={t(\"editor.inspect.setter_group.background\")}\n          size=\"big\"\n        />\n      </div>\n      <div css={setterContainerStyle}>\n        <PageLabel labelName={t(\"editor.page.label_name.body\")} size=\"small\" />\n        <ColorPickerSetter\n          value={bodyStyle?.background ?? \"white\"}\n          handleUpdateColor={handleChangeBodyBackGroundColor}\n        />\n      </div>\n      {hasHeader && (\n        <div css={setterContainerStyle}>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.header\")}\n            size=\"small\"\n          />\n          <ColorPickerSetter\n            value={headerStyle?.background ?? \"white\"}\n            handleUpdateColor={handleChangeHeaderBackGroundColor}\n          />\n        </div>\n      )}\n      {hasLeft && (\n        <div css={setterContainerStyle}>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.left_panel\")}\n            size=\"small\"\n          />\n          <ColorPickerSetter\n            value={leftStyle?.background ?? \"white\"}\n            handleUpdateColor={handleChangeLeftBackGroundColor}\n          />\n        </div>\n      )}\n      {hasRight && (\n        <div css={setterContainerStyle}>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.right_panel\")}\n            size=\"small\"\n          />\n          <ColorPickerSetter\n            value={rightStyle?.background ?? \"white\"}\n            handleUpdateColor={handleChangeRightBackGroundColor}\n          />\n        </div>\n      )}\n      {hasFooter && (\n        <div css={setterContainerStyle}>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.footer\")}\n            size=\"small\"\n          />\n          <ColorPickerSetter\n            value={footerStyle?.background ?? \"white\"}\n            handleUpdateColor={handleChangeFooterBackGroundColor}\n          />\n        </div>\n      )}\n    </section>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/DeleteActionContainer/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC } from \"react\"\nimport { MinusIcon } from \"@illa-design/react\"\nimport { PageLabel } from \"@/page/App/components/PagePanel/Components/Label\"\nimport { DeleteActionContainerProps } from \"./interface\"\nimport { deleteActionContainerStyle, deleteContainerStyle } from \"./style\"\n\nexport const DeleteActionContainer: FC<DeleteActionContainerProps> = (\n  props,\n) => {\n  const { children, onClickDelete, labelName } = props\n\n  return (\n    <div css={deleteActionContainerStyle}>\n      <PageLabel labelName={labelName} size=\"small\" />\n      <div css={deleteContainerStyle} className=\"deleteContainer\">\n        {children}\n        <IconHotSpot onClick={onClickDelete}>\n          <MinusIcon />\n        </IconHotSpot>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/DeleteActionContainer/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface DeleteActionContainerProps {\n  children: ReactNode\n  labelName: string\n  onClickDelete: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/DeleteActionContainer/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const deleteActionContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 8px 16px;\n  overflow: hidden;\n  :hover {\n    .deleteContainer {\n      transform: translateX(0);\n    }\n  }\n`\n\nexport const deleteContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  transform: translateX(32px);\n  transition: all 0.2s ease-in-out;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/DirectionPaddingSetter/index.tsx",
    "content": "import { FC, FocusEventHandler, useRef } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { Input } from \"@illa-design/react\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { DirectionPaddingSetterProps } from \"./interface\"\nimport { directionPaddingContainerStyle, prefixContainerStyle } from \"./style\"\n\nconst formatValue = (value: string) => {\n  const values = value\n    .split(\" \")\n    .filter((v) => v !== \"\")\n    .filter((v) => !isNaN(Number(v)))\n  if (values.length === 2) {\n    return `${values[0]} ${values[1]} 0 0`\n  }\n  if (values.length === 3) {\n    return `${values[0]} ${values[1]} ${values[2]} 0`\n  }\n  if (values.length > 4) {\n    return `${values[0]} ${values[1]} ${values[2]} ${values[3]}`\n  }\n  return values.join(\" \")\n}\n\nconst formatPartialValue = (value: string = \"\") => {\n  if (!/^[0-9]+$/.test(value)) {\n    return \"0\"\n  }\n  return value\n}\n\nexport const DirectionPaddingSetter: FC<DirectionPaddingSetterProps> = (\n  props,\n) => {\n  const { isAll, value, handleUpdateValue } = props\n  const values = value.split(\" \")\n\n  const allInputRef = useRef<HTMLInputElement>(null)\n  const dispatch = useDispatch()\n\n  const handleChangeAllValue = (value: string) => {\n    handleUpdateValue(value)\n  }\n\n  const handleBlurAllValue: FocusEventHandler<HTMLInputElement> = (e) => {\n    handleUpdateValue(formatValue(e.target.value ?? \"\"))\n    dispatch(configActions.updateShowDot(false))\n  }\n\n  const handleChangePartialValue = (index: number) => {\n    return (value: string) => {\n      values[index] = value\n      if (value !== \"\" && !/^[0-9]+$/.test(value)) return\n      handleUpdateValue(values.join(\" \"))\n    }\n  }\n\n  const handleOnFocus = () => {\n    dispatch(configActions.updateShowDot(true))\n  }\n\n  const handleOnBlurPartialValue = (index: number) => {\n    const fixFunc: FocusEventHandler<HTMLInputElement> = (e) => {\n      dispatch(configActions.updateShowDot(false))\n      const value = formatPartialValue(e.target.value)\n      values[index] = value\n      handleUpdateValue(values.join(\" \"))\n    }\n    return fixFunc\n  }\n\n  return (\n    <div css={directionPaddingContainerStyle}>\n      {isAll ? (\n        <Input\n          prefix={<span css={prefixContainerStyle}>All</span>}\n          colorScheme=\"techPurple\"\n          value={value}\n          ref={allInputRef}\n          onFocus={handleOnFocus}\n          onChange={handleChangeAllValue}\n          onBlur={handleBlurAllValue}\n        />\n      ) : (\n        <>\n          <Input\n            prefix={<span css={prefixContainerStyle}>T</span>}\n            colorScheme=\"techPurple\"\n            bdRadius=\"8px 0 0 8px\"\n            value={values[0]}\n            onFocus={handleOnFocus}\n            onBlur={handleOnBlurPartialValue(0)}\n            onChange={handleChangePartialValue(0)}\n          />\n          <Input\n            prefix={<span css={prefixContainerStyle}>R</span>}\n            colorScheme=\"techPurple\"\n            bdRadius=\"0\"\n            pos=\"relative\"\n            l=\"-1px\"\n            value={values[1]}\n            onFocus={handleOnFocus}\n            onBlur={handleOnBlurPartialValue(1)}\n            onChange={handleChangePartialValue(1)}\n          />\n          <Input\n            prefix={<span css={prefixContainerStyle}>B</span>}\n            colorScheme=\"techPurple\"\n            bdRadius=\"0\"\n            pos=\"relative\"\n            l=\"-2px\"\n            value={values[2]}\n            onFocus={handleOnFocus}\n            onBlur={handleOnBlurPartialValue(2)}\n            onChange={handleChangePartialValue(2)}\n          />\n          <Input\n            prefix={<span css={prefixContainerStyle}>L</span>}\n            colorScheme=\"techPurple\"\n            bdRadius=\"0 8px 8px 0\"\n            pos=\"relative\"\n            l=\"-3px\"\n            value={values[3]}\n            onFocus={handleOnFocus}\n            onBlur={handleOnBlurPartialValue(3)}\n            onChange={handleChangePartialValue(3)}\n          />\n        </>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/DirectionPaddingSetter/interface.ts",
    "content": "export interface DirectionPaddingSetterProps {\n  isAll: boolean\n  value: string\n  handleUpdateValue: (value: string) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/DirectionPaddingSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const directionPaddingContainerStyle = css`\n  display: flex;\n  padding: 8px 16px;\n`\n\nexport const prefixContainerStyle = css`\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 12px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/DividerSetter/index.tsx",
    "content": "import IconHotSpot from \"@illa-public/icon-hot-spot\"\nimport { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { PlusIcon, getColor } from \"@illa-design/react\"\nimport ColorPickerSetter from \"@/components/ColorSetter\"\nimport { PageLabel } from \"@/page/App/components/PagePanel/Components/Label\"\nimport {\n  labelContainerStyle,\n  sectionContainerStyle,\n} from \"@/page/App/components/PagePanel/Modules/Style/style\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport {\n  getCurrentPageExecutionResult,\n  getCurrentPageFooterSection,\n  getCurrentPageHeaderSection,\n  getCurrentPageLeftSection,\n  getCurrentPageRightSection,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { AddSection } from \"../AddSection\"\nimport { DeleteActionContainer } from \"../DeleteActionContainer\"\n\nexport const DividerSetter: FC = () => {\n  const { t } = useTranslation()\n\n  const dispatch = useDispatch()\n\n  const currentPage = useSelector(getCurrentPageExecutionResult)\n  const { displayName } = currentPage\n\n  const rightSection = useSelector(getCurrentPageRightSection)\n  const leftSection = useSelector(getCurrentPageLeftSection)\n  const headerSection = useSelector(getCurrentPageHeaderSection)\n  const footerSection = useSelector(getCurrentPageFooterSection)\n  const { style: rightStyle } = rightSection ?? {}\n  const { style: leftStyle } = leftSection ?? {}\n  const { style: headerStyle } = headerSection ?? {}\n  const { style: footerStyle } = footerSection ?? {}\n\n  const hasLeftDivider = !!leftStyle?.dividerColor\n  const hasRightDivider = !!rightStyle?.dividerColor\n  const hasHeaderDivider = !!headerStyle?.dividerColor\n  const hasFooterDivider = !!footerStyle?.dividerColor\n\n  const handleUpdateLeftDivider = useCallback(\n    (value: string) => {\n      dispatch(\n        componentsActions.updateCurrentPageStyleReducer({\n          pageName: displayName,\n          style: {\n            dividerColor: value,\n          },\n          sectionName: \"leftSection\",\n        }),\n      )\n    },\n    [dispatch, displayName],\n  )\n\n  const handleDeleteLeftDivider = useCallback(() => {\n    dispatch(\n      componentsActions.deleteCurrentPageStyleReducer({\n        pageName: displayName,\n        styleKey: \"dividerColor\",\n        sectionName: \"leftSection\",\n      }),\n    )\n  }, [dispatch, displayName])\n\n  const handleUpdateRightDivider = useCallback(\n    (value: string) => {\n      dispatch(\n        componentsActions.updateCurrentPageStyleReducer({\n          pageName: displayName,\n          style: {\n            dividerColor: value,\n          },\n          sectionName: \"rightSection\",\n        }),\n      )\n    },\n    [dispatch, displayName],\n  )\n\n  const handleDeleteRightDivider = useCallback(() => {\n    dispatch(\n      componentsActions.deleteCurrentPageStyleReducer({\n        pageName: displayName,\n        styleKey: \"dividerColor\",\n        sectionName: \"rightSection\",\n      }),\n    )\n  }, [dispatch, displayName])\n\n  const handleUpdateHeaderDivider = useCallback(\n    (value: string) => {\n      dispatch(\n        componentsActions.updateCurrentPageStyleReducer({\n          pageName: displayName,\n          style: {\n            dividerColor: value,\n          },\n          sectionName: \"headerSection\",\n        }),\n      )\n    },\n    [dispatch, displayName],\n  )\n\n  const handleDeleteHeaderDivider = useCallback(() => {\n    dispatch(\n      componentsActions.deleteCurrentPageStyleReducer({\n        pageName: displayName,\n        styleKey: \"dividerColor\",\n        sectionName: \"headerSection\",\n      }),\n    )\n  }, [dispatch, displayName])\n\n  const handleUpdateFooterDivider = useCallback(\n    (value: string) => {\n      dispatch(\n        componentsActions.updateCurrentPageStyleReducer({\n          pageName: displayName,\n          style: {\n            dividerColor: value,\n          },\n          sectionName: \"footerSection\",\n        }),\n      )\n    },\n    [dispatch, displayName],\n  )\n\n  const handleDeleteFooterDivider = useCallback(() => {\n    dispatch(\n      componentsActions.deleteCurrentPageStyleReducer({\n        pageName: displayName,\n        styleKey: \"dividerColor\",\n        sectionName: \"footerSection\",\n      }),\n    )\n  }, [dispatch, displayName])\n\n  return (\n    <section css={sectionContainerStyle}>\n      <div css={labelContainerStyle}>\n        <PageLabel\n          labelName={t(\"editor.inspect.setter_group.divider\")}\n          size=\"big\"\n        />\n        <AddSection>\n          <span>\n            <IconHotSpot>\n              <PlusIcon />\n            </IconHotSpot>\n          </span>\n        </AddSection>\n      </div>\n      {hasLeftDivider && (\n        <DeleteActionContainer\n          labelName={t(\"editor.page.label_name.left_panel\")}\n          onClickDelete={handleDeleteLeftDivider}\n        >\n          <ColorPickerSetter\n            value={leftStyle?.dividerColor ?? getColor(\"grayBlue\", \"08\")}\n            handleUpdateColor={handleUpdateLeftDivider}\n          />\n        </DeleteActionContainer>\n      )}\n      {hasRightDivider && (\n        <DeleteActionContainer\n          labelName={t(\"editor.page.label_name.right_panel\")}\n          onClickDelete={handleDeleteRightDivider}\n        >\n          <ColorPickerSetter\n            value={rightStyle?.dividerColor ?? getColor(\"grayBlue\", \"08\")}\n            handleUpdateColor={handleUpdateRightDivider}\n          />\n        </DeleteActionContainer>\n      )}\n      {hasHeaderDivider && (\n        <DeleteActionContainer\n          labelName={t(\"editor.page.label_name.header\")}\n          onClickDelete={handleDeleteHeaderDivider}\n        >\n          <ColorPickerSetter\n            value={headerStyle?.dividerColor ?? getColor(\"grayBlue\", \"08\")}\n            handleUpdateColor={handleUpdateHeaderDivider}\n          />\n        </DeleteActionContainer>\n      )}\n      {hasFooterDivider && (\n        <DeleteActionContainer\n          labelName={t(\"editor.page.label_name.footer\")}\n          onClickDelete={handleDeleteFooterDivider}\n        >\n          <ColorPickerSetter\n            value={footerStyle?.dividerColor ?? getColor(\"grayBlue\", \"08\")}\n            handleUpdateColor={handleUpdateFooterDivider}\n          />\n        </DeleteActionContainer>\n      )}\n    </section>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/PaddingSetter/index.tsx",
    "content": "import PartialIcon from \"@assets/rightPagePanel/partial.svg?react\"\nimport { PADDING_MODE } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { RadioGroup } from \"@illa-design/react\"\nimport AllIcon from \"@/assets/rightPagePanel/all.svg?react\"\nimport { BASIC_CANVAS_PADDING } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { PageLabel } from \"@/page/App/components/PagePanel/Components/Label\"\nimport {\n  labelContainerStyle,\n  sectionContainerStyle,\n  setterContainerStyle,\n} from \"@/page/App/components/PagePanel/Modules/Style/style\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport {\n  getCurrentPageBodySection,\n  getCurrentPageExecutionResult,\n  getCurrentPageFooterSection,\n  getCurrentPageHeaderSection,\n  getCurrentPageLeftSection,\n  getCurrentPageRightSection,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { DirectionPaddingSetter } from \"../DirectionPaddingSetter\"\nimport { optionsIconHotSpotStyle } from \"./style\"\n\nconst options = [\n  {\n    label: (\n      <div css={optionsIconHotSpotStyle}>\n        <AllIcon />\n      </div>\n    ),\n    value: PADDING_MODE.ALL,\n  },\n  {\n    label: (\n      <div css={optionsIconHotSpotStyle}>\n        <PartialIcon />\n      </div>\n    ),\n    value: PADDING_MODE.PARTIAL,\n  },\n]\n\nexport const PaddingSetter: FC = () => {\n  const { t } = useTranslation()\n\n  const currentPage = useSelector(getCurrentPageExecutionResult)\n  const { displayName, hasFooter, hasLeft, hasRight, hasHeader } = currentPage\n\n  const bodySection = useSelector(getCurrentPageBodySection)\n  const rightSection = useSelector(getCurrentPageRightSection)\n  const leftSection = useSelector(getCurrentPageLeftSection)\n  const headerSection = useSelector(getCurrentPageHeaderSection)\n  const footerSection = useSelector(getCurrentPageFooterSection)\n  const { style: bodyStyle } = bodySection ?? {}\n  const { style: rightStyle } = rightSection ?? {}\n  const { style: leftStyle } = leftSection ?? {}\n  const { style: headerStyle } = headerSection ?? {}\n  const { style: footerStyle } = footerSection ?? {}\n\n  const dispatch = useDispatch()\n\n  const { padding: bodyPadding = {} } = bodyStyle ?? {}\n  const { padding: headerPadding = {} } = headerStyle ?? {}\n  const { padding: leftPanelPadding = {} } = leftStyle ?? {}\n  const { padding: rightPanelPadding = {} } = rightStyle ?? {}\n  const { padding: footerPadding = {} } = footerStyle ?? {}\n\n  const bodyPaddingMode = bodyPadding.mode ?? PADDING_MODE.ALL\n  const headerPaddingMode = headerPadding.mode ?? PADDING_MODE.ALL\n  const leftPanelPaddingMode = leftPanelPadding.mode ?? PADDING_MODE.ALL\n  const rightPanelPaddingMode = rightPanelPadding.mode ?? PADDING_MODE.ALL\n  const footerPaddingMode = footerPadding.mode ?? PADDING_MODE.ALL\n\n  const bodyPaddingSize = bodyPadding.size ?? `${BASIC_CANVAS_PADDING}`\n  const headerPaddingSize = headerPadding.size ?? `${BASIC_CANVAS_PADDING}`\n  const leftPaddingSize = leftPanelPadding.size ?? `${BASIC_CANVAS_PADDING}`\n  const rightPaddingSize = rightPanelPadding.size ?? `${BASIC_CANVAS_PADDING}`\n  const footerPaddingSize = footerPadding.size ?? `${BASIC_CANVAS_PADDING}`\n\n  const changeLeftPaddingMode = (value: PADDING_MODE) => {\n    if (leftPanelPaddingMode === value) return\n    switch (value) {\n      case PADDING_MODE.ALL: {\n        let result = leftPaddingSize\n        const partialSize = Array.from(new Set(leftPaddingSize.split(\" \")))\n        if (partialSize.length === 1) {\n          result = partialSize[0]\n        }\n\n        dispatch(\n          componentsActions.updateCurrentPageStyleReducer({\n            pageName: displayName,\n            style: {\n              padding: {\n                mode: value,\n                size: result,\n              },\n            },\n            sectionName: \"leftSection\",\n          }),\n        )\n        break\n      }\n      case PADDING_MODE.PARTIAL: {\n        const partialSize = leftPaddingSize.split(\" \")\n        let result = leftPaddingSize\n        if (partialSize.length === 1) {\n          result = `${partialSize[0]} ${partialSize[0]} ${partialSize[0]} ${partialSize[0]}`\n        }\n        if (partialSize.length === 4) {\n          result = `${partialSize[0]} ${partialSize[1]} ${partialSize[2]} ${partialSize[3]}`\n        }\n\n        dispatch(\n          componentsActions.updateCurrentPageStyleReducer({\n            pageName: displayName,\n            style: {\n              padding: {\n                mode: value,\n                size: result,\n              },\n            },\n            sectionName: \"leftSection\",\n          }),\n        )\n        break\n      }\n    }\n  }\n\n  const changeRightPaddingMode = (value: PADDING_MODE) => {\n    if (rightPanelPaddingMode === value) return\n    switch (value) {\n      case PADDING_MODE.ALL: {\n        let result = rightPaddingSize\n        const partialSize = Array.from(new Set(rightPaddingSize.split(\" \")))\n        if (partialSize.length === 1) {\n          result = partialSize[0]\n        }\n\n        dispatch(\n          componentsActions.updateCurrentPageStyleReducer({\n            pageName: displayName,\n            style: {\n              padding: {\n                mode: value,\n                size: result,\n              },\n            },\n            sectionName: \"rightSection\",\n          }),\n        )\n        break\n      }\n      case PADDING_MODE.PARTIAL: {\n        const partialSize = rightPaddingSize.split(\" \")\n        let result = rightPaddingSize\n        if (partialSize.length === 1) {\n          result = `${partialSize[0]} ${partialSize[0]} ${partialSize[0]} ${partialSize[0]}`\n        }\n        if (partialSize.length === 4) {\n          result = `${partialSize[0]} ${partialSize[1]} ${partialSize[2]} ${partialSize[3]}`\n        }\n\n        dispatch(\n          componentsActions.updateCurrentPageStyleReducer({\n            pageName: displayName,\n            style: {\n              padding: {\n                mode: value,\n                size: result,\n              },\n            },\n            sectionName: \"rightSection\",\n          }),\n        )\n        break\n      }\n    }\n  }\n\n  const changeHeaderPaddingMode = (value: PADDING_MODE) => {\n    if (headerPaddingMode === value) return\n    switch (value) {\n      case PADDING_MODE.ALL: {\n        let result = headerPaddingSize\n        const partialSize = Array.from(new Set(headerPaddingSize.split(\" \")))\n        if (partialSize.length === 1) {\n          result = partialSize[0]\n        }\n\n        dispatch(\n          componentsActions.updateCurrentPageStyleReducer({\n            pageName: displayName,\n            style: {\n              padding: {\n                mode: value,\n                size: result,\n              },\n            },\n            sectionName: \"headerSection\",\n          }),\n        )\n        break\n      }\n      case PADDING_MODE.PARTIAL: {\n        const partialSize = headerPaddingSize.split(\" \")\n        let result = headerPaddingSize\n        if (partialSize.length === 1) {\n          result = `${partialSize[0]} ${partialSize[0]} ${partialSize[0]} ${partialSize[0]}`\n        }\n        if (partialSize.length === 4) {\n          result = `${partialSize[0]} ${partialSize[1]} ${partialSize[2]} ${partialSize[3]}`\n        }\n\n        dispatch(\n          componentsActions.updateCurrentPageStyleReducer({\n            pageName: displayName,\n            style: {\n              padding: {\n                mode: value,\n                size: result,\n              },\n            },\n            sectionName: \"headerSection\",\n          }),\n        )\n        break\n      }\n    }\n  }\n\n  const changeFooterPaddingMode = (value: PADDING_MODE) => {\n    if (footerPaddingMode === value) return\n    switch (value) {\n      case PADDING_MODE.ALL: {\n        let result = footerPaddingSize\n        const partialSize = Array.from(new Set(footerPaddingSize.split(\" \")))\n        if (partialSize.length === 1) {\n          result = partialSize[0]\n        }\n\n        dispatch(\n          componentsActions.updateCurrentPageStyleReducer({\n            pageName: displayName,\n            style: {\n              padding: {\n                mode: value,\n                size: result,\n              },\n            },\n            sectionName: \"footerSection\",\n          }),\n        )\n        break\n      }\n      case PADDING_MODE.PARTIAL: {\n        const partialSize = footerPaddingSize.split(\" \")\n        let result = footerPaddingSize\n        if (partialSize.length === 1) {\n          result = `${partialSize[0]} ${partialSize[0]} ${partialSize[0]} ${partialSize[0]}`\n        }\n        if (partialSize.length === 4) {\n          result = `${partialSize[0]} ${partialSize[1]} ${partialSize[2]} ${partialSize[3]}`\n        }\n\n        dispatch(\n          componentsActions.updateCurrentPageStyleReducer({\n            pageName: displayName,\n            style: {\n              padding: {\n                mode: value,\n                size: result,\n              },\n            },\n            sectionName: \"footerSection\",\n          }),\n        )\n        break\n      }\n    }\n  }\n\n  const changeBodyPaddingMode = (value: PADDING_MODE) => {\n    if (bodyPaddingMode === value) return\n    switch (value) {\n      case PADDING_MODE.ALL: {\n        let result = bodyPaddingSize\n        const partialSize = Array.from(new Set(bodyPaddingSize.split(\" \")))\n        if (partialSize.length === 1) {\n          result = partialSize[0]\n        }\n\n        dispatch(\n          componentsActions.updateCurrentPageStyleReducer({\n            pageName: displayName,\n            style: {\n              padding: {\n                mode: value,\n                size: result,\n              },\n            },\n            sectionName: \"bodySection\",\n          }),\n        )\n        break\n      }\n      case PADDING_MODE.PARTIAL: {\n        const partialSize = bodyPaddingSize.split(\" \")\n        let result = bodyPaddingSize\n        if (partialSize.length === 1) {\n          result = `${partialSize[0]} ${partialSize[0]} ${partialSize[0]} ${partialSize[0]}`\n        }\n        if (partialSize.length === 4) {\n          result = `${partialSize[0]} ${partialSize[1]} ${partialSize[2]} ${partialSize[3]}`\n        }\n\n        dispatch(\n          componentsActions.updateCurrentPageStyleReducer({\n            pageName: displayName,\n            style: {\n              padding: {\n                mode: value,\n                size: result,\n              },\n            },\n            sectionName: \"bodySection\",\n          }),\n        )\n        break\n      }\n    }\n  }\n\n  const handleChangeLeftPaddingSize = (value: string) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          padding: {\n            size: value,\n          },\n        },\n        sectionName: \"leftSection\",\n      }),\n    )\n  }\n\n  const handleChangeRightPaddingSize = (value: string) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          padding: {\n            size: value,\n          },\n        },\n        sectionName: \"rightSection\",\n      }),\n    )\n  }\n\n  const handleChangeHeaderPaddingSize = (value: string) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          padding: {\n            size: value,\n          },\n        },\n        sectionName: \"headerSection\",\n      }),\n    )\n  }\n\n  const handleChangeFooterPaddingSize = (value: string) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          padding: {\n            size: value,\n          },\n        },\n        sectionName: \"footerSection\",\n      }),\n    )\n  }\n\n  const handleChangeBodyPaddingSize = (value: string) => {\n    dispatch(\n      componentsActions.updateCurrentPageStyleReducer({\n        pageName: displayName,\n        style: {\n          padding: {\n            size: value,\n          },\n        },\n        sectionName: \"bodySection\",\n      }),\n    )\n  }\n\n  return (\n    <section css={sectionContainerStyle}>\n      <div css={labelContainerStyle}>\n        <PageLabel\n          labelName={t(\"editor.inspect.setter_group.padding\")}\n          size=\"big\"\n        />\n      </div>\n      <div css={setterContainerStyle}>\n        <PageLabel labelName={t(\"editor.page.label_name.body\")} size=\"small\" />\n        <RadioGroup\n          type=\"button\"\n          options={options}\n          value={bodyPaddingMode}\n          onChange={changeBodyPaddingMode}\n          size=\"small\"\n          w=\"105px\"\n          forceEqualWidth\n        />\n      </div>\n      <DirectionPaddingSetter\n        isAll={bodyPaddingMode === PADDING_MODE.ALL}\n        value={bodyPaddingSize}\n        handleUpdateValue={handleChangeBodyPaddingSize}\n      />\n      {hasHeader && (\n        <>\n          <div css={setterContainerStyle}>\n            <PageLabel\n              labelName={t(\"editor.page.label_name.header\")}\n              size=\"small\"\n            />\n            <RadioGroup\n              type=\"button\"\n              options={options}\n              value={headerPaddingMode}\n              onChange={changeHeaderPaddingMode}\n              size=\"small\"\n              w=\"105px\"\n              forceEqualWidth\n            />\n          </div>\n          <DirectionPaddingSetter\n            isAll={headerPaddingMode === PADDING_MODE.ALL}\n            value={headerPaddingSize}\n            handleUpdateValue={handleChangeHeaderPaddingSize}\n          />\n        </>\n      )}\n      {hasLeft && (\n        <>\n          <div css={setterContainerStyle}>\n            <PageLabel\n              labelName={t(\"editor.page.label_name.left_panel\")}\n              size=\"small\"\n            />\n            <RadioGroup\n              type=\"button\"\n              options={options}\n              value={leftPanelPaddingMode}\n              onChange={changeLeftPaddingMode}\n              size=\"small\"\n              w=\"105px\"\n              forceEqualWidth\n            />\n          </div>\n          <DirectionPaddingSetter\n            isAll={leftPanelPaddingMode === PADDING_MODE.ALL}\n            value={leftPaddingSize}\n            handleUpdateValue={handleChangeLeftPaddingSize}\n          />\n        </>\n      )}\n      {hasRight && (\n        <>\n          <div css={setterContainerStyle}>\n            <PageLabel\n              labelName={t(\"editor.page.label_name.right_panel\")}\n              size=\"small\"\n            />\n            <RadioGroup\n              type=\"button\"\n              options={options}\n              value={rightPanelPaddingMode}\n              onChange={changeRightPaddingMode}\n              size=\"small\"\n              w=\"105px\"\n              forceEqualWidth\n            />\n          </div>\n          <DirectionPaddingSetter\n            isAll={rightPanelPaddingMode === PADDING_MODE.ALL}\n            value={rightPaddingSize}\n            handleUpdateValue={handleChangeRightPaddingSize}\n          />\n        </>\n      )}\n      {hasFooter && (\n        <>\n          <div css={setterContainerStyle}>\n            <PageLabel\n              labelName={t(\"editor.page.label_name.footer\")}\n              size=\"small\"\n            />\n            <RadioGroup\n              type=\"button\"\n              options={options}\n              value={footerPaddingMode}\n              onChange={changeFooterPaddingMode}\n              size=\"small\"\n              w=\"105px\"\n              forceEqualWidth\n            />\n          </div>\n          <DirectionPaddingSetter\n            isAll={footerPaddingMode === PADDING_MODE.ALL}\n            value={footerPaddingSize}\n            handleUpdateValue={handleChangeFooterPaddingSize}\n          />\n        </>\n      )}\n    </section>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/PaddingSetter/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const optionsIconHotSpotStyle = css`\n  width: 16px;\n  height: 16px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/ShadowSelect/constants.ts",
    "content": "import i18n from \"@/i18n/config\"\n\nexport enum SHADOW_VALUE {\n  NONE = \"none\",\n  LARGE = \"large\",\n  MEDIUM = \"medium\",\n  SMALL = \"small\",\n}\n\nexport const SHADOW_OPTIONS = [\n  {\n    label: i18n.t(\"editor.inspect.setter_option.shadow.none\"),\n    value: SHADOW_VALUE.NONE,\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.shadow.large\"),\n    value: SHADOW_VALUE.LARGE,\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.shadow.medium\"),\n    value: SHADOW_VALUE.MEDIUM,\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.shadow.small\"),\n    value: SHADOW_VALUE.SMALL,\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/ShadowSelect/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { DropList, DropListItem, Dropdown } from \"@illa-design/react\"\nimport ShadowIcon from \"@/assets/shadow-icon.svg?react\"\nimport { SHADOW_OPTIONS } from \"./constants\"\nimport { ShadowSetterProps } from \"./interface\"\nimport {\n  shadowIconHotSpotStyle,\n  shadowSelectStyle,\n  shadowSelectWrapperStyle,\n} from \"./style\"\n\nconst ShadowSelect: FC<ShadowSetterProps> = (props) => {\n  const { value, onChange } = props\n\n  const { t } = useTranslation()\n\n  return (\n    <Dropdown\n      trigger=\"click\"\n      position=\"bottom-start\"\n      autoAlignPopupWidth\n      dropList={\n        <DropList>\n          {SHADOW_OPTIONS.map((option) => {\n            return (\n              <DropListItem\n                key={option.label}\n                value={option.value}\n                selected={value === option.value}\n                colorScheme=\"techPurple\"\n                title={option.label}\n                onClick={() => {\n                  onChange(option.value)\n                }}\n              />\n            )\n          })}\n        </DropList>\n      }\n    >\n      <div css={shadowSelectWrapperStyle}>\n        <div css={shadowSelectStyle}>\n          <div css={shadowIconHotSpotStyle}>\n            <ShadowIcon />\n          </div>\n\n          <div>\n            {t(`editor.inspect.setter_option.shadow.${value || \"small\"}`)}\n          </div>\n        </div>\n      </div>\n    </Dropdown>\n  )\n}\n\nShadowSelect.displayName = \"ShadowSelect\"\n\nexport default ShadowSelect\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/ShadowSelect/interface.ts",
    "content": "import { SHADOW_VALUE } from \"./constants\"\n\nexport interface ShadowSetterProps {\n  value: SHADOW_VALUE\n  onChange: (value: SHADOW_VALUE) => void\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/ShadowSelect/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const shadowSelectWrapperStyle = css`\n  width: 170px;\n  padding: 4px 12px 4px 8px;\n  border-radius: 8px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  display: flex;\n  align-items: center;\n  cursor: pointer;\n`\n\nexport const shadowSelectStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  width: 100%;\n`\n\nexport const shadowIconHotSpotStyle = css`\n  flex: none;\n  width: 24px;\n  height: 24px;\n  align-items: center;\n  justify-content: center;\n  font-size: 16px;\n  display: flex;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/Components/ShadowSetter/index.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { PageLabel } from \"@/page/App/components/PagePanel/Components/Label\"\nimport {\n  labelContainerStyle,\n  sectionContainerStyle,\n  setterContainerStyle,\n} from \"@/page/App/components/PagePanel/Modules/Style/style\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport {\n  getCurrentPageExecutionResult,\n  getCurrentPageFooterSection,\n  getCurrentPageHeaderSection,\n  getCurrentPageLeftSection,\n  getCurrentPageRightSection,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport ShadowSelect from \"../ShadowSelect\"\nimport { SHADOW_VALUE } from \"../ShadowSelect/constants\"\n\nexport const ShadowSetter: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n\n  const currentPage = useSelector(getCurrentPageExecutionResult)\n  const { displayName, hasFooter, hasLeft, hasRight, hasHeader } = currentPage\n\n  const rightSection = useSelector(getCurrentPageRightSection)\n  const leftSection = useSelector(getCurrentPageLeftSection)\n  const headerSection = useSelector(getCurrentPageHeaderSection)\n  const footerSection = useSelector(getCurrentPageFooterSection)\n  const { style: rightStyle } = rightSection ?? {}\n  const { style: leftStyle } = leftSection ?? {}\n  const { style: headerStyle } = headerSection ?? {}\n  const { style: footerStyle } = footerSection ?? {}\n\n  const handleUpdateLeftShadow = useCallback(\n    (value: SHADOW_VALUE) => {\n      dispatch(\n        componentsActions.updateCurrentPageStyleReducer({\n          pageName: displayName,\n          style: {\n            shadowSize: value,\n          },\n          sectionName: \"leftSection\",\n        }),\n      )\n    },\n    [dispatch, displayName],\n  )\n\n  const handleUpdateRightShadow = useCallback(\n    (value: SHADOW_VALUE) => {\n      dispatch(\n        componentsActions.updateCurrentPageStyleReducer({\n          pageName: displayName,\n          style: {\n            shadowSize: value,\n          },\n          sectionName: \"rightSection\",\n        }),\n      )\n    },\n    [dispatch, displayName],\n  )\n\n  const handleUpdateHeaderShadow = useCallback(\n    (value: SHADOW_VALUE) => {\n      dispatch(\n        componentsActions.updateCurrentPageStyleReducer({\n          pageName: displayName,\n          style: {\n            shadowSize: value,\n          },\n          sectionName: \"headerSection\",\n        }),\n      )\n    },\n    [dispatch, displayName],\n  )\n\n  const handleUpdateFooterShadow = useCallback(\n    (value: SHADOW_VALUE) => {\n      dispatch(\n        componentsActions.updateCurrentPageStyleReducer({\n          pageName: displayName,\n          style: {\n            shadowSize: value,\n          },\n          sectionName: \"footerSection\",\n        }),\n      )\n    },\n    [dispatch, displayName],\n  )\n\n  return (\n    <section css={sectionContainerStyle}>\n      <div css={labelContainerStyle}>\n        <PageLabel\n          labelName={t(\"editor.inspect.setter_group.shadow\")}\n          size=\"big\"\n        />\n      </div>\n      {hasLeft && (\n        <div css={setterContainerStyle}>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.left_panel\")}\n            size=\"small\"\n          />\n          <ShadowSelect\n            value={leftStyle?.shadowSize ?? SHADOW_VALUE.NONE}\n            onChange={handleUpdateLeftShadow}\n          />\n        </div>\n      )}\n      {hasRight && (\n        <div css={setterContainerStyle}>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.right_panel\")}\n            size=\"small\"\n          />\n          <ShadowSelect\n            value={rightStyle?.shadowSize ?? SHADOW_VALUE.NONE}\n            onChange={handleUpdateRightShadow}\n          />\n        </div>\n      )}\n      {hasHeader && (\n        <div css={setterContainerStyle}>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.header\")}\n            size=\"small\"\n          />\n          <ShadowSelect\n            value={headerStyle?.shadowSize ?? SHADOW_VALUE.NONE}\n            onChange={handleUpdateHeaderShadow}\n          />\n        </div>\n      )}\n      {hasFooter && (\n        <div css={setterContainerStyle}>\n          <PageLabel\n            labelName={t(\"editor.page.label_name.footer\")}\n            size=\"small\"\n          />\n          <ShadowSelect\n            value={footerStyle?.shadowSize ?? SHADOW_VALUE.NONE}\n            onChange={handleUpdateFooterShadow}\n          />\n        </div>\n      )}\n    </section>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Divider } from \"@illa-design/react\"\nimport { PanelBar } from \"@/components/PanelBar\"\nimport { BackgroundSetter } from \"./Components/BackgroundSetter\"\nimport { DividerSetter } from \"./Components/DividerSetter\"\nimport { PaddingSetter } from \"./Components/PaddingSetter\"\n\nexport const PageStyle: FC = () => {\n  const { t } = useTranslation()\n\n  return (\n    <PanelBar title={t(\"editor.inspect.setter_group.style\")}>\n      <DividerSetter />\n      <Divider />\n      {/* <ShadowSetter />\n      <Divider /> */}\n      <BackgroundSetter />\n      <Divider />\n      <PaddingSetter />\n    </PanelBar>\n  )\n}\n\nPageStyle.displayName = \"PageStyle\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/Modules/Style/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const iconHotSpotContainerStyle = css`\n  padding: 6px;\n  font-size: 12px;\n  cursor: pointer;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  :hover {\n    color: ${getColor(\"grayBlue\", \"02\")};\n  }\n`\n\nexport const labelContainerStyle = css`\n  display: flex;\n  justify-content: space-between;\n  padding: 8px 16px;\n  align-items: center;\n`\n\nexport const sectionContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  padding: 8px 0px;\n`\n\nexport const setterContainerStyle = css`\n  padding: 8px 16px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/index.tsx",
    "content": "import { FC } from \"react\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { PageBasic } from \"./Modules/Basic\"\nimport { PageFrame } from \"./Modules/Frame\"\nimport { PageStyle } from \"./Modules/Style\"\nimport { PagePanelWrapperStyle, PageScrollContainerWrapperStyle } from \"./style\"\n\nconst PagePanel: FC = () => {\n  return (\n    <div\n      css={PagePanelWrapperStyle}\n      onClick={() => {\n        FocusManager.switchFocus(\"page_config\")\n      }}\n    >\n      <div css={PageScrollContainerWrapperStyle}>\n        <PageFrame />\n        <PageBasic />\n        <PageStyle />\n      </div>\n    </div>\n  )\n}\n\nPagePanel.displayName = \"PagePanel\"\nexport default PagePanel\n"
  },
  {
    "path": "apps/builder/src/page/App/components/PagePanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const PagePanelWrapperStyle = css`\n  border-top: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  height: 100%;\n  width: 100%;\n  padding-bottom: 48px;\n  overflow: hidden;\n  display: flex;\n  flex-direction: column;\n`\n\nexport const PageScrollContainerWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  overflow-y: auto;\n`\n\nexport const headerWrapperStyle = css`\n  display: flex;\n  height: 48px;\n  align-items: center;\n  padding: 0 16px;\n`\n\nexport const optionListWrapperStyle = css`\n  display: flex;\n  width: 100%;\n  height: 100%;\n  align-items: center;\n  justify-content: center;\n  gap: 6px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/AutoHeightWithLimitedContainer/index.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { Resizable, ResizeCallback, ResizeStartCallback } from \"re-resizable\"\nimport { FC, useCallback, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { AutoHeightWithLimitedContainerProps } from \"@/page/App/components/ScaleSquare/components/AutoHeightWithLimitedContainer/interface\"\nimport {\n  applyResizeBarPointStyle,\n  containerBorderStyle,\n} from \"@/page/App/components/ScaleSquare/components/AutoHeightWithLimitedContainer/style\"\nimport { applyBarHandlerStyle } from \"@/page/App/components/ScaleSquare/style\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\n\nexport const DEFAULT_MAX_HEIGHT = 80\nexport const DEFAULT_MIN_GAP = 8\n\nconst resizeHandler = {\n  bottom: (\n    <div css={applyBarHandlerStyle(true, \"normal\", \"b\")}>\n      <div className=\"handler\" css={applyResizeBarPointStyle} />\n    </div>\n  ),\n}\n\nexport const AutoHeightWithLimitedContainer: FC<\n  AutoHeightWithLimitedContainerProps\n> = ({ containerHeight, displayName }) => {\n  const dispatch = useDispatch()\n  const [resizeMaxHeight, setResizeMaxHeight] = useState(false)\n  const [resizeMinHeight, setResizeMinHeight] = useState(false)\n  const executionResult = useSelector(getExecutionResult)\n  const layoutInfoResult = useSelector(getClientWidgetLayoutInfo)\n\n  const dynamicMinHeight = get(\n    executionResult,\n    `${displayName}.dynamicMinHeight`,\n    0,\n  )\n  const dynamicMaxHeight = get(\n    executionResult,\n    `${displayName}.dynamicMaxHeight`,\n    0,\n  )\n  const widgetH = get(\n    layoutInfoResult,\n    `${displayName}.layoutInfo.h`,\n    0,\n  ) as number\n\n  const isAutoLimitedMode =\n    get(executionResult, `${displayName}.dynamicHeight`, \"fixed\") === \"limited\"\n\n  const handleUpdateComponentHeight = useCallback(\n    (height: number) => {\n      const finalHeight = Math.ceil(height / UNIT_HEIGHT)\n\n      dispatch(\n        componentsActions.updateComponentNodeHeightReducer({\n          displayName: displayName,\n          height: finalHeight,\n          oldHeight: widgetH,\n        }),\n      )\n    },\n    [displayName, widgetH, dispatch],\n  )\n\n  const resizeStartCallback: ResizeStartCallback = useCallback(() => {\n    setResizeMinHeight(true)\n    dispatch(configActions.updateShowDot(true))\n    dispatch(\n      configActions.setResizingNodeIDsReducer([\n        `${displayName}-resize-minHeight`,\n      ]),\n    )\n  }, [dispatch, displayName])\n\n  const resizeMaxHeightStartCallback: ResizeStartCallback = useCallback(() => {\n    setResizeMaxHeight(true)\n    dispatch(configActions.updateShowDot(true))\n    dispatch(\n      configActions.setResizingNodeIDsReducer([\n        `${displayName}-resize-maxHeight`,\n      ]),\n    )\n  }, [dispatch, displayName])\n\n  const resizeMaxHeightCallback: ResizeCallback = useCallback(\n    (event, direction, elementRef, delta) => {\n      setResizeMaxHeight(false)\n      const deltaHeight = delta.height\n      const finalDynamicMaxHeight =\n        Math.round(\n          ((dynamicMaxHeight ?? containerHeight + DEFAULT_MAX_HEIGHT) +\n            deltaHeight) /\n            UNIT_HEIGHT,\n        ) * UNIT_HEIGHT\n      dispatch(\n        componentsActions.updateComponentPropsReducer({\n          displayName,\n          updateSlice: {\n            dynamicMaxHeight: finalDynamicMaxHeight,\n          },\n        }),\n      )\n      dispatch(configActions.updateShowDot(false))\n      window.setTimeout(() => {\n        dispatch(configActions.setResizingNodeIDsReducer([]))\n      }, 16)\n    },\n    [containerHeight, dispatch, displayName, dynamicMaxHeight],\n  )\n\n  const resizeMinHeightCallback: ResizeCallback = useCallback(\n    (event, direction, elementRef, delta) => {\n      setResizeMinHeight(false)\n      const deltaHeight = delta.height\n      const finalDynamicMinHeight =\n        Math.round(\n          ((dynamicMinHeight ?? containerHeight + 3) + deltaHeight) /\n            UNIT_HEIGHT,\n        ) * UNIT_HEIGHT\n      dispatch(\n        componentsActions.updateComponentPropsReducer({\n          displayName,\n          updateSlice: {\n            dynamicMinHeight: finalDynamicMinHeight,\n          },\n        }),\n      )\n      setTimeout(() => {\n        if (finalDynamicMinHeight > containerHeight) {\n          handleUpdateComponentHeight(finalDynamicMinHeight)\n        }\n      }, 30)\n      dispatch(configActions.updateShowDot(false))\n      window.setTimeout(() => {\n        dispatch(configActions.setResizingNodeIDsReducer([]))\n      }, 16)\n    },\n    [\n      containerHeight,\n      dispatch,\n      displayName,\n      dynamicMinHeight,\n      handleUpdateComponentHeight,\n    ],\n  )\n\n  return isAutoLimitedMode ? (\n    <>\n      <Resizable\n        size={{\n          width: \"100%\",\n          height: `${dynamicMaxHeight ?? containerHeight + DEFAULT_MAX_HEIGHT}`,\n        }}\n        style={{\n          position: \"absolute\",\n          top: \"0\",\n          pointerEvents: \"none\",\n          backgroundColor: resizeMaxHeight ? \"rgba(255, 88, 190, 0.1)\" : \"\",\n        }}\n        minHeight={dynamicMinHeight + DEFAULT_MIN_GAP}\n        handleComponent={resizeHandler}\n        enable={{\n          bottom: true,\n        }}\n        onResizeStart={resizeMaxHeightStartCallback}\n        onResizeStop={resizeMaxHeightCallback}\n        handleWrapperStyle={{\n          pointerEvents: \"all\",\n        }}\n      >\n        <div css={containerBorderStyle(\"b\")} />\n        <div css={containerBorderStyle(\"l\")} />\n        <div css={containerBorderStyle(\"r\")} />\n      </Resizable>\n      <Resizable\n        size={{\n          width: \"100%\",\n          height: `${dynamicMinHeight ?? containerHeight + 3}`,\n        }}\n        style={{\n          position: \"absolute\",\n          top: \"0\",\n          pointerEvents: \"none\",\n          backgroundColor: resizeMinHeight ? \"rgba(255, 88, 190, 0.1)\" : \"\",\n        }}\n        minHeight={27}\n        maxHeight={dynamicMaxHeight - DEFAULT_MIN_GAP}\n        handleComponent={resizeHandler}\n        enable={{\n          bottom: true,\n        }}\n        onResizeStart={resizeStartCallback}\n        onResizeStop={resizeMinHeightCallback}\n        handleWrapperStyle={{\n          pointerEvents: \"all\",\n        }}\n      >\n        <div css={containerBorderStyle(\"b\", 1)} />\n      </Resizable>\n    </>\n  ) : null\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/AutoHeightWithLimitedContainer/interface.ts",
    "content": "export interface AutoHeightWithLimitedContainerProps {\n  containerHeight: number\n  displayName: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/AutoHeightWithLimitedContainer/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { applyBarPointerShapeStyle } from \"@/page/App/components/ScaleSquare/style\"\n\nexport const containerStyle = css`\n  height: 100%;\n  width: 100%;\n  border: 1px dashed ${getColor(\"techPink\", \"03\")};\n  padding: 2px;\n  border-top: none;\n  pointer-events: none;\n`\n\nexport const containerBorderStyle = (\n  position: \"t\" | \"b\" | \"l\" | \"r\",\n  zIndex: number = -1,\n) => {\n  switch (position) {\n    case \"t\":\n      return css`\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 1px;\n        background: linear-gradient(\n          to right,\n          ${getColor(\"techPink\", \"03\")},\n          ${getColor(\"techPink\", \"03\")} 5px,\n          transparent 5px,\n          transparent\n        );\n        background-size: 10px 100%;\n        z-index: ${zIndex};\n      `\n    case \"b\":\n      return css`\n        position: absolute;\n        bottom: 0;\n        left: 0;\n        width: 100%;\n        height: 1px;\n        background: linear-gradient(\n          to right,\n          ${getColor(\"techPink\", \"03\")},\n          ${getColor(\"techPink\", \"03\")} 5px,\n          transparent 5px,\n          transparent\n        );\n        background-size: 10px 100%;\n      `\n    case \"l\":\n      return css`\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 1px;\n        height: 100%;\n        background: linear-gradient(\n          to bottom,\n          ${getColor(\"techPink\", \"03\")},\n          ${getColor(\"techPink\", \"03\")} 5px,\n          transparent 5px,\n          transparent\n        );\n        background-size: 100% 10px;\n        z-index: ${zIndex};\n      `\n    case \"r\":\n      return css`\n        position: absolute;\n        top: 0;\n        right: 0;\n        width: 1px;\n        height: 100%;\n        background: linear-gradient(\n          to bottom,\n          ${getColor(\"techPink\", \"03\")},\n          ${getColor(\"techPink\", \"03\")} 5px,\n          transparent 5px,\n          transparent\n        );\n        background-size: 100% 10px;\n        z-index: ${zIndex};\n      `\n  }\n}\n\nexport const applyResizeBarPointStyle = css`\n  ${applyBarPointerShapeStyle(\"b\")}\n  background-color: white;\n  border: 1px solid ${getColor(\"techPink\", \"03\")};\n  :hover {\n    background-color: ${getColor(\"techPink\", \"03\")};\n  }\n  :active {\n    background-color: ${getColor(\"techPink\", \"03\")};\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/CollaboratorsList/index.tsx",
    "content": "import { FC, useMemo, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport useMeasure from \"react-use-measure\"\nimport { MoreIcon, Trigger } from \"@illa-design/react\"\nimport { Avatar } from \"@/page/App/components/Avatar\"\nimport {\n  getComponentUsersListContainerStyle,\n  listContainerStyle,\n  listItemContentStyle,\n  listItemNicknameStyle,\n  listItemStyle,\n  moreIconStyle,\n} from \"@/page/App/components/ScaleSquare/components/CollaboratorsList/style\"\nimport {\n  MIN_THREE_AVATAR_MOVE_BAR_WIDTH,\n  MIN_THREE_AVATAR_WIDTH,\n} from \"@/redux/currentApp/collaborators/collaboratorsHandlers\"\nimport { CollaboratorsInfo } from \"@/redux/currentApp/collaborators/collaboratorsState\"\n\nexport const CollaboratorsList: FC<{\n  users: CollaboratorsInfo[]\n  disableMargin: boolean\n  currentState: string\n  containerWidth: number\n  nameChanging?: boolean\n}> = ({ users, disableMargin, currentState, containerWidth }) => {\n  const [listShow, setListShow] = useState(false)\n  const [listContainerRef, bounds] = useMeasure()\n  const { t } = useTranslation()\n  const length = users.length\n\n  const { showMoreIcon, displayDataList } = useMemo(() => {\n    let showMoreIcon = false\n    let displayDataList: CollaboratorsInfo[] = []\n\n    const listLength = users.length\n    if (listLength < 3) {\n      return {\n        showMoreIcon: false,\n        displayDataList: users,\n      }\n    }\n    if (currentState === \"right\") {\n      return containerWidth > MIN_THREE_AVATAR_MOVE_BAR_WIDTH\n        ? {\n            showMoreIcon: listLength !== 3,\n            displayDataList: listLength === 3 ? users : users.slice(0, 2),\n          }\n        : {\n            showMoreIcon: true,\n            displayDataList: users.slice(0, 1),\n          }\n    }\n    if (\n      (currentState === \"left\" && bounds.width <= MIN_THREE_AVATAR_WIDTH) ||\n      disableMargin\n    ) {\n      return {\n        showMoreIcon: true,\n        displayDataList: users.slice(0, 1),\n      }\n    }\n    return {\n      showMoreIcon,\n      displayDataList,\n    }\n  }, [bounds.width, containerWidth, currentState, disableMargin, users])\n\n  const renderListItem = useMemo(\n    () => (\n      <>\n        {displayDataList.map(({ avatar, id, nickname }, index) => (\n          <Avatar\n            userID={id}\n            nickname={nickname}\n            avatar={avatar}\n            showType=\"components\"\n            key={index}\n            showTooltips={true}\n          />\n        ))}\n        {showMoreIcon && (\n          <Trigger\n            trigger=\"hover\"\n            content={\n              <div css={listContainerStyle}>\n                <div css={listItemContentStyle}>\n                  {t(\"editor.component.editor_list\")}\n                </div>\n                {users.map(({ avatar, id, nickname }, index) => (\n                  <div key={index} css={listItemStyle}>\n                    <Avatar\n                      userID={id}\n                      nickname={nickname}\n                      avatar={avatar}\n                      showType=\"components\"\n                      type=\"list\"\n                      key={index}\n                    />\n                    <span css={listItemNicknameStyle}>{nickname || \"\"}</span>\n                  </div>\n                ))}\n              </div>\n            }\n            popupVisible={listShow}\n            onVisibleChange={setListShow}\n            position=\"bottom-start\"\n            showArrow={false}\n            withoutPadding\n            colorScheme=\"white\"\n          >\n            <div css={moreIconStyle}>\n              <MoreIcon />\n            </div>\n          </Trigger>\n        )}\n      </>\n    ),\n    [displayDataList, listShow, showMoreIcon, t, users],\n  )\n\n  if (!length) {\n    return null\n  }\n\n  return (\n    <div\n      css={getComponentUsersListContainerStyle(length, disableMargin)}\n      ref={listContainerRef}\n    >\n      {renderListItem}\n    </div>\n  )\n}\n\nCollaboratorsList.displayName = \"CollaboratorsList\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/CollaboratorsList/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport function applyUserAvatarStyle(\n  background: string,\n  type?: string,\n): SerializedStyles {\n  const basicStyle = css`\n    display: inline-block;\n    background: #${background};\n    color: ${globalColor(`--${illaPrefix}-white-01`)};\n    text-align: center;\n    border-radius: 50%;\n    flex-shrink: 0;\n  `\n  if (type === \"list\") {\n    return css`\n      ${basicStyle};\n      width: 24px;\n      height: 24px;\n      line-height: 24px;\n    `\n  }\n  return css`\n    ${basicStyle};\n    width: 14px;\n    height: 14px;\n    line-height: 14px;\n  `\n}\n\nexport const getComponentUsersListContainerStyle = (\n  length: number,\n  disableMargin: boolean,\n) => {\n  const minWidth = length >= 3 ? 32 : 14 * length + 4 * (length - 1)\n  let marginStyle = css`\n    margin-left: 8px;\n  `\n  if (disableMargin) {\n    marginStyle = css``\n  }\n  return css`\n    display: flex;\n    ${marginStyle};\n    gap: 4px;\n    height: 16px;\n    max-width: 50px;\n    flex-shrink: 0;\n    flex-grow: 1;\n    justify-content: flex-start;\n    align-self: center;\n    overflow: hidden;\n    align-items: center;\n    min-width: ${minWidth}px;\n  `\n}\n\nexport const moreIconStyle = css`\n  width: 14px;\n  height: 14px;\n  line-height: 14px;\n  text-align: center;\n  border-radius: 50%;\n  background-color: ${globalColor(`--${illaPrefix}-white-06`)};\n  color: ${globalColor(`--${illaPrefix}-white-01`)};\n  display: flex;\n  flex-grow: 0;\n  flex-shrink: 0;\n  align-items: center;\n  justify-content: center;\n  cursor: pointer;\n  & > svg {\n    width: 8px;\n    height: 8px;\n  }\n`\n\nexport const listContainerStyle = css`\n  width: 154px;\n  padding: 16px;\n  left: 14px;\n  top: -1px;\n  max-height: 234px;\n  overflow: scroll;\n  position: absolute;\n  border-radius: 8px;\n  box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.08);\n  background-color: ${globalColor(`--${illaPrefix}-white-01`)};\n`\n\nexport const listItemStyle = css`\n  height: 24px;\n  display: flex;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  align-items: center;\n  padding: 0;\n  font-weight: 500;\n  font-size: 12px;\n  gap: 8px;\n  flex: none;\n  width: 100%;\n  &:not(:last-child) {\n    margin-bottom: 12px;\n  }\n`\n\nexport const listItemContentStyle = css`\n  height: 22px;\n  line-height: 22px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  margin-bottom: 12px;\n  padding: 0;\n  font-weight: 500;\n  font-family: \"PingFang SC\";\n  font-style: normal;\n  font-size: 14px;\n  width: 100%;\n`\n\nexport const listItemNicknameStyle = css`\n  height: 20px;\n  line-height: 20px;\n  font-size: 12px;\n  font-family: \"Inter\";\n  font-style: normal;\n  flex-grow: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/DragContainer/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { FC } from \"react\"\nimport { useDrag } from \"react-dnd\"\nimport { useSelector } from \"react-redux\"\nimport { DropResultInfo } from \"@/page/App/components/DotPanel/components/Canvas/interface\"\nimport { illaSnapshot } from \"@/page/App/components/DotPanel/constant/snapshotNew\"\nimport {\n  sendMousePositionHandler,\n  sendShadowMessageHandler,\n} from \"@/page/App/components/DotPanel/utils/sendBinaryMessage\"\nimport {\n  getIsILLAEditMode,\n  getSelectedComponentDisplayNames,\n} from \"@/redux/config/configSelector\"\nimport { getIsResizing } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { WidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\nimport store from \"@/store\"\nimport { endDragMultiNodes, startDragMultiNodes } from \"@/utils/drag/drag\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { DRAG_EFFECT, DragContainerProps, DragInfo } from \"./interface\"\nimport { dragContainerStyle } from \"./style\"\n\nexport const DragContainer: FC<DragContainerProps> = (props) => {\n  const {\n    children,\n    displayName,\n    canDrag = true,\n    columnNumber,\n    unitWidth,\n    parentNodeDisplayName,\n  } = props\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const isResizingStateInGlobal = useSelector(getIsResizing)\n  const selectedComponents = useSelector(getSelectedComponentDisplayNames)\n\n  const [, dragRef] = useDrag<DragInfo, DropResultInfo>(\n    () => ({\n      type: \"components\",\n      canDrag: isEditMode && canDrag && !isResizingStateInGlobal,\n      end: (draggedItem, monitor) => {\n        const dropResult = monitor.getDropResult()\n        sendShadowMessageHandler(-1, \"\", [], 0, 0, 0, 0, 0, 0, 0, 0)\n        const { draggedComponents } = draggedItem\n        const widgetTypes = draggedComponents.map((node) => node.widgetType)\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.DRAG, {\n          element: \"component\",\n          parameter1: widgetTypes,\n        })\n        endDragMultiNodes(\n          draggedComponents,\n          !!dropResult?.isDropOnCanvas,\n          false,\n        )\n      },\n      item: () => {\n        const rootState = store.getState()\n        let allWidgetLayoutInfo = getClientWidgetLayoutInfo(rootState)\n        illaSnapshot.setSnapshot(allWidgetLayoutInfo)\n        let draggedSelectedComponents: WidgetLayoutInfo[] = []\n        let currentSelectedComponents = selectedComponents\n        if (!currentSelectedComponents.includes(displayName)) {\n          currentSelectedComponents = [displayName]\n        }\n        draggedSelectedComponents = Object.values(allWidgetLayoutInfo).filter(\n          (node) =>\n            currentSelectedComponents.includes(node.displayName) ||\n            node.displayName === displayName,\n        )\n        startDragMultiNodes(draggedSelectedComponents)\n        sendMousePositionHandler(parentNodeDisplayName, 0, 0, 0, 0, true)\n        return {\n          draggedComponents: draggedSelectedComponents,\n          dragEffect: DRAG_EFFECT.UPDATE,\n          draggedDisplayName: displayName,\n          columnNumberWhenDragged: columnNumber,\n          unitWWhenDragged: unitWidth,\n        }\n      },\n    }),\n    [\n      isEditMode,\n      isResizingStateInGlobal,\n      selectedComponents,\n      displayName,\n      unitWidth,\n      columnNumber,\n      canDrag,\n      parentNodeDisplayName,\n    ],\n  )\n\n  return (\n    <div css={dragContainerStyle} ref={dragRef}>\n      {children}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/DragContainer/interface.ts",
    "content": "import { ReactNode } from \"react\"\nimport { WidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\n\nexport interface DragContainerProps {\n  children: ReactNode\n  displayName: string\n  parentNodeDisplayName: string\n  canDrag: boolean\n  unitWidth: number\n  columnNumber: number\n}\n\nexport enum DRAG_EFFECT {\n  ADD = \"ADD\",\n  UPDATE = \"UPDATE\",\n}\n\nexport interface DragInfo {\n  draggedComponents: WidgetLayoutInfo[]\n  dragEffect: DRAG_EFFECT\n  draggedDisplayName: string\n  alignTop?: boolean\n  dropResult?: {\n    shape?: {\n      x: number\n      y: number\n      w: number\n      previewH: number\n    }\n    canDrop: boolean\n    columnNumberWhenDrag: number\n    columnNumberWhenDrop: number\n  }\n  columnNumberWhenDragged: number\n  unitWWhenDragged: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/DragContainer/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const dragContainerStyle = css`\n  width: 100%;\n  height: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/MoveBar/interface.ts",
    "content": "import { CollaboratorsInfo } from \"@/redux/currentApp/collaborators/collaboratorsState\"\n\nexport interface MoveBarProps {\n  displayName: string\n  isError: boolean\n  maxWidth: number\n  widgetTop: number\n  widgetType: string\n  userList: CollaboratorsInfo[]\n  columnNumber: number\n}\n\nexport type BarPosition = \"l\" | \"r\" | \"t\" | \"b\" | \"tl\" | \"tr\" | \"bl\" | \"br\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/MoveBar/moveBar.tsx",
    "content": "import { FC, useEffect, useRef, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport useMeasure from \"react-use-measure\"\nimport {\n  DragPointIcon,\n  Trigger,\n  WarningCircleIcon,\n  globalColor,\n  illaPrefix,\n} from \"@illa-design/react\"\nimport DocIcon from \"@/assets/doc.svg?react\"\nimport { SCROLL_CONTAINER_PADDING } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { CollaboratorsList } from \"@/page/App/components/ScaleSquare/components/CollaboratorsList\"\nimport {\n  MIN_MOVE_BAR_WIDTH,\n  MOVE_BAR_HEIGHT,\n  MOVE_BAR_SVG_WIDTH,\n} from \"@/page/App/components/ScaleSquare/constant/moveBar\"\nimport { useDisplayNameInMoveBarSelector } from \"@/page/App/components/ScaleSquare/utils/useGetDisplayNameInMoveBar\"\nimport { getIsLikeProductMode } from \"@/redux/config/configSelector\"\nimport {\n  AVATAR_GAP,\n  AVATAR_WIDTH,\n  MIN_DISABLE_MARGIN_WIDTH,\n} from \"@/redux/currentApp/collaborators/collaboratorsHandlers\"\nimport { MoveBarProps } from \"./interface\"\nimport {\n  applyMoveBarWrapperStyle,\n  displayNameContainerStyle,\n  docIconStyle,\n  docTipsWrapperStyle,\n  dragPointIconWrapperStyle,\n  moveBarDisplayNameStyle,\n  warningStyle,\n} from \"./style\"\n\ninterface WidgetDocProps {\n  widgetType: string\n}\n\nexport const WidgetDoc: FC<WidgetDocProps> = (props) => {\n  const { t } = useTranslation()\n  switch (props.widgetType) {\n    case \"LIST_WIDGET\":\n      return (\n        <Trigger\n          content={\n            <div css={docTipsWrapperStyle}>\n              <span>{t(\"widget.list.doc1\")}</span>\n              <span>{t(\"widget.list.doc2\")}</span>\n            </div>\n          }\n          trigger=\"hover\"\n          colorScheme=\"white\"\n          position=\"right-start\"\n        >\n          <span css={docIconStyle}>\n            <DocIcon />\n          </span>\n        </Trigger>\n      )\n\n    default:\n      return null\n  }\n}\n\nexport const MoveBar: FC<MoveBarProps> = (props) => {\n  const { displayName, isError, maxWidth, widgetTop, widgetType, userList } =\n    props\n\n  const [currentState, setCurrentState] = useState<string>(\"right\")\n  const [containerRef, bounds] = useMeasure()\n  const containerWidthRef = useRef(0)\n  const isLikeProductionMode = useSelector(getIsLikeProductMode)\n  const displayNameInMoveBar = useDisplayNameInMoveBarSelector(\n    displayName,\n    widgetType,\n  )\n\n  useEffect(() => {\n    if (bounds.width > containerWidthRef.current) {\n      currentState !== \"right\" && setCurrentState(\"right\")\n    }\n    if (bounds.width < containerWidthRef.current) {\n      currentState !== \"left\" && setCurrentState(\"left\")\n    }\n    containerWidthRef.current = bounds.width\n  }, [bounds.width, currentState])\n\n  const topPosition =\n    widgetTop + SCROLL_CONTAINER_PADDING >= MOVE_BAR_HEIGHT\n      ? -MOVE_BAR_HEIGHT\n      : 0\n\n  const minWidth =\n    userList.length >= 3\n      ? MIN_MOVE_BAR_WIDTH\n      : userList.length * AVATAR_WIDTH +\n          (userList.length || 1 - 1) * AVATAR_GAP +\n          MOVE_BAR_SVG_WIDTH || MOVE_BAR_SVG_WIDTH\n\n  const disableMargin =\n    bounds.width <=\n    (userList.length >= 2 ? MIN_MOVE_BAR_WIDTH : MIN_DISABLE_MARGIN_WIDTH)\n\n  return (\n    <div\n      css={applyMoveBarWrapperStyle(\n        maxWidth,\n        minWidth,\n        isError,\n        isLikeProductionMode,\n        topPosition,\n      )}\n      id=\"moveBar\"\n      ref={containerRef}\n    >\n      <>\n        <div css={displayNameContainerStyle}>\n          <DragPointIcon css={dragPointIconWrapperStyle} />\n          <span css={moveBarDisplayNameStyle}>{displayNameInMoveBar}</span>\n        </div>\n        <CollaboratorsList\n          users={userList}\n          disableMargin={disableMargin}\n          currentState={currentState}\n          containerWidth={bounds.width}\n        />\n      </>\n      {isError && (\n        <WarningCircleIcon\n          color={globalColor(`--${illaPrefix}-white-05`)}\n          css={warningStyle}\n        />\n      )}\n      <WidgetDoc widgetType={widgetType} />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/MoveBar/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\nimport { MOVE_BAR_HEIGHT } from \"@/page/App/components/ScaleSquare/constant/moveBar\"\n\nexport const warningStyle = css`\n  margin-left: 4px;\n`\n\nexport const applyMoveBarWrapperStyle = (\n  maxWidth: number,\n  minWidth: number,\n  isError: boolean,\n  isLikeProductionMode: boolean,\n  topPosition: number,\n) => {\n  let borderRadiusStyle = css`\n    border-radius: 4px 4px 0 0;\n  `\n\n  const backgroundColorStyle = isError\n    ? globalColor(`--${illaPrefix}-red-03`)\n    : globalColor(`--${illaPrefix}-techPurple-03`)\n  return css`\n    height: ${MOVE_BAR_HEIGHT}px;\n    padding: 1px 4px 1px 0;\n    background-color: ${backgroundColorStyle};\n    ${borderRadiusStyle};\n    display: flex;\n    position: absolute;\n    top: ${topPosition}px;\n    left: 0;\n    align-items: center;\n    font-size: 12px;\n    color: #fff;\n    max-width: ${maxWidth}px;\n    min-width: ${minWidth}px;\n    visibility: ${!isLikeProductionMode ? \"visible\" : \"hidden\"};\n    z-index: 100;\n    cursor: move;\n  `\n}\n\nexport const displayNameContainerStyle = css`\n  display: flex;\n  min-width: 12px;\n  flex-grow: 1;\n  align-items: center;\n`\n\nexport const dragPointIconWrapperStyle = css`\n  width: 12px;\n  height: 12px;\n  flex: none;\n`\n\nexport const moveBarDisplayNameStyle = css`\n  overflow: hidden;\n  text-overflow: ellipsis;\n  line-height: 16px;\n`\n\nexport const docIconStyle = css`\n  height: 100%;\n  margin-left: 4px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n\nexport const docTipsWrapperStyle = css`\n  width: 320px;\n  display: flex;\n  flex-direction: column;\n  gap: 10px;\n  font-size: 14px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  word-break: break-all;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/PositionContainer/index.tsx",
    "content": "import { FC, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getSelectedComponentDisplayNames } from \"@/redux/config/configSelector\"\nimport { getDraggingComponentIDs } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { PositionContainerProps } from \"./interface\"\nimport { positionContainerStyle } from \"./style\"\n\nexport const PositionContainer: FC<PositionContainerProps> = (props) => {\n  const { x, y, children, displayName } = props\n  const selectedComponents = useSelector(getSelectedComponentDisplayNames)\n\n  const draggingComponentNodes = useSelector(getDraggingComponentIDs)\n  const isDragging = draggingComponentNodes.includes(displayName)\n  const isSelected = useMemo(() => {\n    return selectedComponents.some((currentDisplayName) => {\n      return displayName === currentDisplayName\n    })\n  }, [displayName, selectedComponents])\n  return (\n    <div css={positionContainerStyle(x, y, isDragging, isSelected)}>\n      {children}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/PositionContainer/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface PositionContainerProps {\n  x: number\n  y: number\n  displayName: string\n  children: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/PositionContainer/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const positionContainerStyle = (\n  x: number,\n  y: number,\n  isDragging: boolean,\n  isSelected: boolean,\n) => css`\n  position: absolute;\n  top: 0;\n  left: 0;\n  transform: translate(${x}px, ${y}px);\n  pointer-events: ${isDragging ? \"none\" : \"auto\"};\n  display: ${isDragging ? \"none\" : \"block\"};\n  z-index: ${isSelected ? 5 : 0};\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/ResizingAndDragContainer/ResizeHandler/hooks.ts",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { throttle } from \"lodash-es\"\nimport { useCallback, useMemo, useRef } from \"react\"\nimport { XYCoord, useDrag, useDragLayer, useDrop } from \"react-dnd\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { illaSnapshot } from \"@/page/App/components/DotPanel/constant/snapshotNew\"\nimport {\n  NodeShape,\n  getNewPositionWithCrossing,\n} from \"@/page/App/components/DotPanel/utils/crossingHelper\"\nimport { sendShadowMessageHandler } from \"@/page/App/components/DotPanel/utils/sendBinaryMessage\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { layoutInfoActions } from \"@/redux/currentApp/layoutInfo/layoutInfoSlice\"\nimport {\n  BatchUpdateWidgetLayoutInfoPayload,\n  WidgetLayoutInfo,\n} from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\nimport store from \"@/store\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { BarPosition } from \"./interface\"\nimport { fixWidgetPosition } from \"./utils\"\n\nexport interface DragResizeHandlerInfo {\n  barPosition: BarPosition\n  displayName: string\n  dragResult?: NodeShape\n}\n\nexport const useResizeStart = (\n  barPosition: BarPosition,\n  displayName: string,\n) => {\n  const dispatch = useDispatch()\n  const useDragReturnValue = useDrag<DragResizeHandlerInfo>(\n    () => ({\n      type: \"resizeHandler\",\n      end: () => {\n        dispatch(configActions.updateShowDot(false))\n      },\n      item: () => {\n        const rootState = store.getState()\n        let allWidgetLayoutInfo = getClientWidgetLayoutInfo(rootState)\n        illaSnapshot.setSnapshot(allWidgetLayoutInfo)\n        dispatch(configActions.updateShowDot(true))\n        dispatch(configActions.setResizingNodeIDsReducer([displayName]))\n\n        return {\n          barPosition,\n          displayName,\n        }\n      },\n    }),\n    [barPosition, displayName],\n  )\n\n  return useDragReturnValue\n}\n\nexport const useResize = () => {\n  const isEditMode = useSelector(getIsILLAEditMode)\n\n  const dispatch = useDispatch()\n  const prevEffectedDisplayNamesRef = useRef<string[]>([])\n\n  const useDropReturnValue = useDrop<DragResizeHandlerInfo>(\n    () => ({\n      accept: [\"resizeHandler\"],\n      canDrop: () => {\n        return isEditMode\n      },\n      hover: (dragHandlerInfo) => {\n        const { displayName } = dragHandlerInfo\n\n        const snapShot = illaSnapshot.getSnapshot()\n        const currentWidgetSnapShot = snapShot[displayName]\n        const scrollContainerDOM = document.querySelector(\n          `[data-scroll-container=\"${currentWidgetSnapShot.parentNode}\"]`,\n        ) as HTMLElement\n        if (!scrollContainerDOM) return\n        scrollContainerDOM.dataset.isDraggingOver = \"true\"\n      },\n\n      drop: (dragHandlerInfo) => {\n        const { displayName, dragResult } = dragHandlerInfo\n        if (!dragResult) return\n\n        const snapShot = illaSnapshot.getSnapshot()\n        const currentWidgetSnapShot = snapShot[displayName]\n        dispatch(\n          componentsActions.updateComponentLayoutInfoReducer({\n            displayName: displayName,\n            layoutInfo: {\n              x: dragResult.x,\n              y: dragResult.y,\n              w: dragResult.w,\n              h:\n                dragResult.h === currentWidgetSnapShot.layoutInfo.h\n                  ? undefined\n                  : dragResult.h,\n            },\n            parentNode: currentWidgetSnapShot.parentNode,\n          }),\n        )\n        dispatch(configActions.setResizingNodeIDsReducer([]))\n\n        sendShadowMessageHandler(-1, \"\", [], 0, 0, 0, 0, 0, 0, 0, 0)\n        trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.DRAG, {\n          element: \"component\",\n          parameter1: currentWidgetSnapShot.widgetType,\n        })\n        prevEffectedDisplayNamesRef.current = []\n        const scrollContainerDOM = document.querySelector(\n          `[data-scroll-container=\"${currentWidgetSnapShot.parentNode}\"]`,\n        ) as HTMLElement\n        if (!scrollContainerDOM) return\n        scrollContainerDOM.dataset.isDraggingOver = \"false\"\n      },\n    }),\n    [isEditMode],\n  )\n\n  return useDropReturnValue\n}\n\ninterface ResizingCollectedProps {\n  isDragging: boolean\n  item: DragResizeHandlerInfo\n  clientOffset: XYCoord | null\n}\n\nexport const useResizingUpdateRealTime = (isActive: boolean) => {\n  const prevEffectedDisplayNamesRef = useRef<string[]>([])\n  const dispatch = useDispatch()\n\n  const collectedProps = useDragLayer<\n    ResizingCollectedProps,\n    DragResizeHandlerInfo\n  >((monitor) => {\n    return {\n      isDragging: monitor.isDragging(),\n      item: monitor.getItem(),\n      clientOffset: monitor.getClientOffset(),\n    }\n  })\n\n  const throttleUpdateComponentPositionByReflow = useMemo(() => {\n    return throttle((newItem: WidgetLayoutInfo) => {\n      const snapshotMap = illaSnapshot.getSnapshot()\n      const snapShotShape = snapshotMap[newItem.displayName]\n      const effectMap = getNewPositionWithCrossing(\n        {\n          x: newItem.layoutInfo.x,\n          y: newItem.layoutInfo.y,\n          w: newItem.layoutInfo.w,\n          h: newItem.layoutInfo.h,\n        },\n        newItem.parentNode,\n        [newItem.displayName],\n      )\n\n      const updateSlice: BatchUpdateWidgetLayoutInfoPayload[] = [\n        {\n          displayName: newItem.displayName,\n          layoutInfo:\n            newItem.layoutInfo.h === snapShotShape.layoutInfo.h\n              ? {\n                  x: newItem.layoutInfo.x,\n                  y: newItem.layoutInfo.y,\n                  w: newItem.layoutInfo.w,\n                }\n              : {\n                  x: newItem.layoutInfo.x,\n                  y: newItem.layoutInfo.y,\n                  w: newItem.layoutInfo.w,\n                  h: newItem.layoutInfo.h,\n                },\n        },\n      ]\n\n      for (let i = 0; i < prevEffectedDisplayNamesRef.current.length; i++) {\n        const effectName = prevEffectedDisplayNamesRef.current[i]\n        if (effectMap && effectMap.has(effectName)) {\n          continue\n        }\n        const layoutInfo = snapshotMap[effectName]\n        if (layoutInfo) {\n          updateSlice.push({\n            displayName: effectName,\n            layoutInfo: {\n              x: layoutInfo.layoutInfo.x,\n              y: layoutInfo.layoutInfo.y,\n              w: layoutInfo.layoutInfo.w,\n              h: layoutInfo.layoutInfo.h,\n            },\n          })\n        }\n      }\n      prevEffectedDisplayNamesRef.current = []\n\n      if (effectMap && effectMap.size > 0) {\n        effectMap.forEach((widgetLayoutInfo) => {\n          updateSlice.push({\n            displayName: widgetLayoutInfo.displayName,\n            layoutInfo: {\n              x: widgetLayoutInfo.layoutInfo.x,\n              y: widgetLayoutInfo.layoutInfo.y,\n              w: widgetLayoutInfo.layoutInfo.w,\n              h: widgetLayoutInfo.layoutInfo.h,\n            },\n          })\n          prevEffectedDisplayNamesRef.current = Array.from(\n            new Set([\n              ...prevEffectedDisplayNamesRef.current,\n              widgetLayoutInfo.displayName,\n            ]),\n          )\n        })\n      }\n      dispatch(\n        layoutInfoActions.batchUpdateWidgetLayoutInfoReducer(updateSlice),\n      )\n    }, 16)\n  }, [dispatch])\n\n  const updateComponentResizeInfo = useCallback(\n    (\n      mousePositionInViewport: XYCoord,\n      dragHandlerInfo: DragResizeHandlerInfo,\n    ) => {\n      const { barPosition, displayName } = dragHandlerInfo\n      const snapShot = illaSnapshot.getSnapshot()\n      const currentWidgetSnapShot = snapShot[displayName]\n      if (!mousePositionInViewport || !currentWidgetSnapShot) return\n      const parentNodeDisplayName = currentWidgetSnapShot.parentNode\n      if (!parentNodeDisplayName) return\n      const parentNodeDOM = document.querySelector(\n        `[data-canvas-container=\"${parentNodeDisplayName}\"]`,\n      ) as HTMLElement\n      const scrollContainerDOM = document.querySelector(\n        `[data-scroll-container=\"${parentNodeDisplayName}\"]`,\n      ) as HTMLElement\n      if (!parentNodeDOM || !scrollContainerDOM) return\n      scrollContainerDOM.dataset.isDraggingOver = \"true\"\n      const unitW = Number(parentNodeDOM.dataset.unitWidth)\n      if (isNaN(unitW)) return\n      const columnNumber = Number(parentNodeDOM.dataset.columnNumber)\n      if (isNaN(columnNumber)) return\n      const canvasRect = parentNodeDOM.getBoundingClientRect()\n      const canvasTop = canvasRect.top\n      const canvasLeft = canvasRect.left\n      const mouseRelativeY = Math.round(\n        (mousePositionInViewport.y - canvasTop) / UNIT_HEIGHT,\n      )\n      const mouseRelativeX = Math.round(\n        (mousePositionInViewport.x - canvasLeft) / unitW,\n      )\n\n      const currentLayoutInfo = currentWidgetSnapShot.layoutInfo\n\n      const deltaX =\n        mouseRelativeX -\n        (barPosition.includes(\"l\")\n          ? currentLayoutInfo.x\n          : currentLayoutInfo.x + currentLayoutInfo.w)\n      const deltaY =\n        mouseRelativeY -\n        (barPosition.includes(\"t\")\n          ? currentLayoutInfo.y\n          : currentLayoutInfo.y + currentLayoutInfo.h)\n\n      let widgetDeltaTop = 0\n      let widgetDeltaHeight = 0\n\n      if (barPosition.includes(\"t\")) {\n        widgetDeltaTop = deltaY\n        widgetDeltaHeight = -deltaY\n      }\n      if (!barPosition.includes(\"t\") && barPosition.includes(\"b\")) {\n        widgetDeltaHeight = deltaY\n      }\n\n      let widgetDeltaLeft = 0\n      let widgetDeltaWidth = 0\n      if (barPosition.includes(\"l\")) {\n        widgetDeltaLeft = deltaX\n        widgetDeltaWidth = -deltaX\n      }\n\n      if (!barPosition.includes(\"l\") && barPosition.includes(\"r\")) {\n        widgetDeltaWidth = deltaX\n      }\n\n      const resizeEffect = {\n        x: widgetDeltaLeft,\n        y: widgetDeltaTop,\n        w: widgetDeltaWidth,\n        h: widgetDeltaHeight,\n      }\n\n      const layoutInfoResult = {\n        ...currentLayoutInfo,\n        x: currentLayoutInfo.x + resizeEffect.x,\n        y: currentLayoutInfo.y + resizeEffect.y,\n        w: currentLayoutInfo.w + resizeEffect.w,\n        h: currentLayoutInfo.h + resizeEffect.h,\n      }\n\n      const fixedLayoutInfoResult = fixWidgetPosition(\n        layoutInfoResult,\n        layoutInfoResult.minH,\n        columnNumber,\n      )\n\n      const resizeDiff = {\n        x: fixedLayoutInfoResult.x - currentLayoutInfo.x,\n        y: fixedLayoutInfoResult.y - currentLayoutInfo.y,\n        w: fixedLayoutInfoResult.w - currentLayoutInfo.w,\n        h: fixedLayoutInfoResult.h - currentLayoutInfo.h,\n      }\n\n      if (resizeEffect.h && resizeEffect.h === -1 * resizeEffect.y) {\n        if (Math.abs(resizeDiff.y) < Math.abs(resizeDiff.h)) {\n          resizeDiff.h = -1 * resizeDiff.y\n        } else {\n          resizeDiff.y = -1 * resizeDiff.h\n        }\n      }\n\n      if (resizeEffect.w) {\n        if (resizeEffect.w === -1 * resizeEffect.x) {\n          if (Math.abs(resizeDiff.x) < Math.abs(resizeDiff.w)) {\n            resizeDiff.w = -1 * resizeDiff.x\n          } else {\n            resizeDiff.x = -1 * resizeDiff.w\n          }\n        } else {\n          if (!resizeEffect.x) {\n            resizeDiff.w += resizeDiff.x\n            resizeDiff.x = 0\n          }\n        }\n      }\n\n      const dragResult = {\n        x: currentLayoutInfo.x + resizeDiff.x,\n        y: currentLayoutInfo.y + resizeDiff.y,\n        w: currentLayoutInfo.w + resizeDiff.w,\n        h: currentLayoutInfo.h + resizeDiff.h,\n      }\n      const resizeResult = {\n        ...currentWidgetSnapShot,\n        layoutInfo: {\n          ...currentLayoutInfo,\n          ...dragResult,\n        },\n      }\n\n      dragHandlerInfo.dragResult = dragResult\n\n      sendShadowMessageHandler(\n        2,\n        parentNodeDisplayName,\n        [displayName],\n        0,\n        0,\n        0,\n        0,\n        dragResult.x,\n        dragResult.y,\n        dragResult.w,\n        dragResult.h,\n      )\n\n      throttleUpdateComponentPositionByReflow(resizeResult)\n    },\n    [throttleUpdateComponentPositionByReflow],\n  )\n\n  if (isActive && collectedProps.isDragging) {\n    updateComponentResizeInfo(\n      collectedProps.clientOffset ?? { x: 0, y: 0 },\n      collectedProps.item,\n    )\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/ResizingAndDragContainer/ResizeHandler/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { RESIZE_DIRECTION } from \"@/widgetLibrary/interface\"\nimport { useResizeStart } from \"./hooks\"\nimport { PartResizeHandlerProps, ResizeHandlerProps } from \"./interface\"\nimport {\n  applyBarHandlerStyle,\n  applyBarPointerStyle,\n  applySquarePointerStyle,\n} from \"./style\"\n\nconst TopLeftResizeHandler = memo<PartResizeHandlerProps>(\n  (props: PartResizeHandlerProps) => {\n    const { displayName } = props\n    const [, dragRef] = useResizeStart(\"tl\", displayName)\n    return <div css={applySquarePointerStyle(\"tl\")} ref={dragRef} />\n  },\n)\nTopLeftResizeHandler.displayName = \"TopLeftResizeHandler\"\n\nconst TopRightResizeHandler = memo<PartResizeHandlerProps>(\n  (props: PartResizeHandlerProps) => {\n    const { displayName } = props\n    const [, dragRef] = useResizeStart(\"tr\", displayName)\n\n    return <div css={applySquarePointerStyle(\"tr\")} ref={dragRef} />\n  },\n)\nTopRightResizeHandler.displayName = \"TopRightResizeHandler\"\n\nconst BottomLeftResizeHandler = memo<PartResizeHandlerProps>(\n  (props: PartResizeHandlerProps) => {\n    const { displayName } = props\n    const [, dragRef] = useResizeStart(\"bl\", displayName)\n\n    return <div css={applySquarePointerStyle(\"bl\")} ref={dragRef} />\n  },\n)\nBottomLeftResizeHandler.displayName = \"BottomLeftResizeHandler\"\n\nconst BottomRightResizeHandler = memo<PartResizeHandlerProps>(\n  (props: PartResizeHandlerProps) => {\n    const { displayName } = props\n    const [, dragRef] = useResizeStart(\"br\", displayName)\n\n    return <div css={applySquarePointerStyle(\"br\")} ref={dragRef} />\n  },\n)\nBottomRightResizeHandler.displayName = \"BottomRightResizeHandler\"\n\nconst TopResizeHandler = memo<PartResizeHandlerProps>(\n  (props: PartResizeHandlerProps) => {\n    const { displayName } = props\n    const [, dragRef] = useResizeStart(\"t\", displayName)\n\n    return (\n      <div css={applyBarHandlerStyle(\"t\")} ref={dragRef}>\n        <div className=\"handler\" css={applyBarPointerStyle(\"t\")} />\n      </div>\n    )\n  },\n)\nTopResizeHandler.displayName = \"TopResizeHandler\"\n\nconst BottomResizeHandler = memo<PartResizeHandlerProps>(\n  (props: PartResizeHandlerProps) => {\n    const { displayName } = props\n    const [, dragRef] = useResizeStart(\"b\", displayName)\n\n    return (\n      <div css={applyBarHandlerStyle(\"b\")} ref={dragRef}>\n        <div className=\"handler\" css={applyBarPointerStyle(\"b\")} />\n      </div>\n    )\n  },\n)\nBottomResizeHandler.displayName = \"BottomResizeHandler\"\n\nconst LeftResizeHandler = memo<PartResizeHandlerProps>(\n  (props: PartResizeHandlerProps) => {\n    const { displayName } = props\n    const [, dragRef] = useResizeStart(\"l\", displayName)\n\n    return (\n      <div css={applyBarHandlerStyle(\"l\")} ref={dragRef}>\n        <div className=\"handler\" css={applyBarPointerStyle(\"l\")} />\n      </div>\n    )\n  },\n)\nLeftResizeHandler.displayName = \"LeftResizeHandler\"\n\nconst RightResizeHandler = memo<PartResizeHandlerProps>(\n  (props: PartResizeHandlerProps) => {\n    const { displayName } = props\n    const [, dragRef] = useResizeStart(\"r\", displayName)\n\n    return (\n      <div css={applyBarHandlerStyle(\"r\")} ref={dragRef}>\n        <div className=\"handler\" css={applyBarPointerStyle(\"r\")} />\n      </div>\n    )\n  },\n)\nRightResizeHandler.displayName = \"RightResizeHandler\"\n\nconst ResizeHandler: FC<ResizeHandlerProps> = (props) => {\n  const { resizeDirection, displayName } = props\n\n  return (\n    <div className=\"resize-handler-container\">\n      {resizeDirection === RESIZE_DIRECTION.ALL && (\n        <TopLeftResizeHandler displayName={displayName} />\n      )}\n      {resizeDirection !== RESIZE_DIRECTION.HORIZONTAL && (\n        <TopResizeHandler displayName={displayName} />\n      )}\n      {resizeDirection === RESIZE_DIRECTION.ALL && (\n        <TopRightResizeHandler displayName={displayName} />\n      )}\n      {resizeDirection !== RESIZE_DIRECTION.VERTICAL && (\n        <LeftResizeHandler displayName={displayName} />\n      )}\n      {resizeDirection !== RESIZE_DIRECTION.VERTICAL && (\n        <RightResizeHandler displayName={displayName} />\n      )}\n      {resizeDirection === RESIZE_DIRECTION.ALL && (\n        <BottomLeftResizeHandler displayName={displayName} />\n      )}\n      {resizeDirection !== RESIZE_DIRECTION.HORIZONTAL && (\n        <BottomResizeHandler displayName={displayName} />\n      )}\n      {resizeDirection === RESIZE_DIRECTION.ALL && (\n        <BottomRightResizeHandler displayName={displayName} />\n      )}\n    </div>\n  )\n}\n\nResizeHandler.displayName = \"ResizeHandler\"\n\nexport default memo(ResizeHandler)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/ResizingAndDragContainer/ResizeHandler/interface.ts",
    "content": "import { RESIZE_DIRECTION } from \"@/widgetLibrary/interface\"\n\nexport type BarPosition = \"l\" | \"r\" | \"t\" | \"b\" | \"tl\" | \"tr\" | \"bl\" | \"br\"\n\nexport interface ResizeHandlerProps {\n  resizeDirection: RESIZE_DIRECTION\n  displayName: string\n}\n\nexport interface PartResizeHandlerProps {\n  displayName: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/ResizingAndDragContainer/ResizeHandler/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { BarPosition } from \"./interface\"\n\nexport const applyBarPointerShapeStyle = (barPosition: BarPosition) => {\n  let barPositionStyle: SerializedStyles\n\n  switch (barPosition) {\n    case \"t\":\n      barPositionStyle = css`\n        left: 0;\n        right: 0;\n        margin: auto;\n        height: 5px;\n        width: 24px;\n      `\n      break\n    case \"b\":\n      barPositionStyle = css`\n        left: 0;\n        right: 0;\n        margin: auto;\n        height: 5px;\n        width: 24px;\n      `\n      break\n    case \"l\":\n      barPositionStyle = css`\n        bottom: 0;\n        top: 0;\n        margin: auto;\n        width: 5px;\n        height: 24px;\n      `\n      break\n    case \"r\":\n      barPositionStyle = css`\n        bottom: 0;\n        top: 0;\n        margin: auto;\n        width: 5px;\n        height: 24px;\n      `\n      break\n    default:\n      barPositionStyle = css``\n  }\n  return css`\n    ${barPositionStyle};\n    box-sizing: border-box;\n    position: absolute;\n    border-radius: 2.5px;\n    background-color: ${getColor(\"white\", \"01\")};\n  `\n}\n\nexport function applyBarHandlerStyle(\n  barPosition: BarPosition,\n): SerializedStyles {\n  let barPositionStyle: SerializedStyles\n  switch (barPosition) {\n    case \"t\":\n      barPositionStyle = css`\n        top: -3px;\n        left: 0;\n        right: 0;\n        height: 5px;\n        cursor: row-resize;\n      `\n      break\n    case \"b\":\n      barPositionStyle = css`\n        bottom: -3px;\n        left: 0;\n        right: 0;\n        height: 5px;\n        cursor: row-resize;\n      `\n      break\n    case \"l\":\n      barPositionStyle = css`\n        bottom: 0;\n        left: -3px;\n        top: 0;\n        width: 5px;\n        cursor: col-resize;\n      `\n      break\n    case \"r\":\n      barPositionStyle = css`\n        bottom: 0;\n        right: -3px;\n        top: 0;\n        cursor: col-resize;\n        width: 5px;\n      `\n      break\n    default:\n      barPositionStyle = css``\n  }\n\n  return css`\n    ${barPositionStyle};\n    position: absolute;\n  `\n}\n\nexport function applyBarPointerStyle(\n  barPosition: BarPosition,\n  isLimitedMode: boolean = false,\n): SerializedStyles {\n  let barPositionStyle: SerializedStyles =\n    applyBarPointerShapeStyle(barPosition)\n\n  const baseColor = isLimitedMode\n    ? getColor(\"techPink\", \"03\")\n    : getColor(\"techPurple\", \"03\")\n  return css`\n    ${barPositionStyle};\n    border: 1px solid ${baseColor};\n    :hover {\n      background-color: ${isLimitedMode\n        ? getColor(\"techPink\", \"03\")\n        : getColor(\"techPurple\", \"03\")};\n    }\n    :active {\n      background-color: ${isLimitedMode\n        ? getColor(\"techPink\", \"03\")\n        : getColor(\"techPurple\", \"03\")};\n    }\n  `\n}\n\nexport function applySquarePointerStyle(\n  pointerPosition: BarPosition,\n): SerializedStyles {\n  let positionStyle: SerializedStyles\n  switch (pointerPosition) {\n    case \"tl\":\n      positionStyle = css`\n        top: -3px;\n        left: -3px;\n        cursor: nwse-resize;\n      `\n      break\n    case \"tr\":\n      positionStyle = css`\n        cursor: nesw-resize;\n        top: -3px;\n        right: -3px;\n      `\n      break\n    case \"bl\":\n      positionStyle = css`\n        cursor: nesw-resize;\n        bottom: -3px;\n        left: -3px;\n      `\n      break\n    case \"br\":\n      positionStyle = css`\n        cursor: nwse-resize;\n        bottom: -3px;\n        right: -3px;\n      `\n      break\n    default:\n      positionStyle = css``\n      break\n  }\n\n  return css`\n    ${positionStyle};\n    box-sizing: border-box;\n    border: 1px solid ${getColor(\"techPurple\", \"03\")};\n    height: 5px;\n    width: 5px;\n    position: absolute;\n    background: ${getColor(\"white\", \"01\")};\n    z-index: 150;\n    &:active {\n      background: ${getColor(\"techPurple\", \"03\")};\n    }\n\n    &:hover {\n      background: ${getColor(\"techPurple\", \"03\")};\n    }\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/ResizingAndDragContainer/ResizeHandler/utils.ts",
    "content": "import { clamp } from \"lodash-es\"\nimport { NodeShape } from \"@/page/App/components/DotPanel/utils/crossingHelper\"\nimport { DEFAULT_MIN_COLUMN } from \"@/page/App/components/ScaleSquare/constant/widget\"\n\nexport const fixWidgetPosition = (\n  nodeShape: NodeShape,\n  minH: number,\n  columnNumber: number,\n) => {\n  const y = clamp(nodeShape.y, 0, Infinity)\n  const h = clamp(nodeShape.h, minH, Infinity)\n  const w = clamp(nodeShape.w, DEFAULT_MIN_COLUMN, columnNumber)\n  const x = clamp(nodeShape.x, 0, columnNumber - w)\n  return {\n    x,\n    y,\n    w,\n    h,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/ResizingAndDragContainer/index.tsx",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { getCurrentUserId } from \"@illa-public/user-data\"\nimport { klona } from \"klona\"\nimport { get } from \"lodash-es\"\nimport { FC, MouseEvent, useCallback, useContext, useMemo } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { DropList, DropListItem, Dropdown } from \"@illa-design/react\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { AutoHeightWithLimitedContainer } from \"@/page/App/components/ScaleSquare/components/AutoHeightWithLimitedContainer\"\nimport { DEFAULT_MIN_COLUMN } from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport {\n  getHoveredComponents,\n  getIsILLAEditMode,\n  getIsLikeProductMode,\n  getSelectedComponentDisplayNames,\n  isShowDot,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport {\n  getComponentAttachUsers,\n  getTargetCurrentUsersExpendMe,\n} from \"@/redux/currentApp/collaborators/collaboratorsSelector\"\nimport { getComponentDisplayNameMapDepth } from \"@/redux/currentApp/components/componentsSelector\"\nimport { getFirstDragShadowInfo } from \"@/redux/currentApp/dragShadow/dragShadowSelector\"\nimport {\n  getExecutionError,\n  getExecutionResult,\n  getIsDragging,\n  getResizingComponentIDs,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport store from \"@/store\"\nimport { CopyManager } from \"@/utils/copyManager\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ShortCutContext } from \"@/utils/shortcut/shortcutProvider\"\nimport { isMAC } from \"@/utils/userAgent\"\nimport { RESIZE_DIRECTION } from \"@/widgetLibrary/interface\"\nimport { widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\nimport { useMouseHover } from \"../../utils/useMouseHover\"\nimport { DragContainer } from \"../DragContainer\"\nimport { MoveBar } from \"../MoveBar/moveBar\"\nimport { PositionContainer } from \"../PositionContainer\"\nimport ResizeHandler from \"./ResizeHandler\"\nimport { ResizingAndDragContainerProps } from \"./interface\"\nimport { resizingContainerStyle, resizingPlaceholderStyle } from \"./style\"\n\nexport const ResizingAndDragContainer: FC<ResizingAndDragContainerProps> = (\n  props,\n) => {\n  const {\n    unitW,\n    displayName,\n    children,\n    widgetHeight,\n    widgetTop,\n    widgetLeft,\n    widgetWidth,\n    widgetType,\n    columnNumber,\n    parentNodeDisplayName,\n  } = props\n\n  const { t } = useTranslation()\n  const shortcut = useContext(ShortCutContext)\n  const firstDragShadow = useSelector(getFirstDragShadowInfo)\n\n  const isResizingWithOthers = firstDragShadow.some((dragShadow) => {\n    return dragShadow?.displayNames?.includes(displayName)\n  })\n\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const selectedComponents = useSelector(getSelectedComponentDisplayNames)\n  const executionResult = useSelector(getExecutionResult)\n  const layoutInfoResult = useSelector(getClientWidgetLayoutInfo)\n  const currentWidgetLayoutInfo = layoutInfoResult[displayName]\n  const currentWidgetProps = get(executionResult, displayName, {})\n  const isShownDot = useSelector(isShowDot)\n  const isDraggingStateInGlobal = useSelector(getIsDragging)\n\n  const isAutoLimitedMode =\n    get(currentWidgetProps, `dynamicHeight`, \"fixed\") === \"limited\"\n\n  const isSelected = useMemo(() => {\n    return selectedComponents.some((currentDisplayName) => {\n      return displayName === currentDisplayName\n    })\n  }, [displayName, selectedComponents])\n\n  const { handleMouseEnter, handleMouseLeave } = useMouseHover()\n  const dispatch = useDispatch()\n  const currentUserID = useSelector(getCurrentUserId)\n  const errors = useSelector(getExecutionError)\n  const hasError = useMemo(() => {\n    const keys = Object.keys(errors)\n    return (\n      keys.length > 0 &&\n      keys.some((key) => {\n        return (\n          Array.isArray(errors[key]) &&\n          errors[key].length > 0 &&\n          key.startsWith(displayName)\n        )\n      })\n    )\n  }, [displayName, errors])\n  const resizingIDs = useSelector(getResizingComponentIDs)\n  const isResizingCurrent = resizingIDs.includes(displayName)\n  const isGlobalResizing = resizingIDs.length > 0\n  const canDrag = widgetType !== \"MODAL_WIDGET\"\n\n  const resizeDirection = useMemo(() => {\n    const direction =\n      currentWidgetProps.resizeDirection ??\n      widgetBuilder(currentWidgetProps.$widgetType)?.config?.resizeDirection\n    return direction || RESIZE_DIRECTION.ALL\n  }, [currentWidgetProps.$widgetType, currentWidgetProps.resizeDirection])\n\n  const hoveredComponents = useSelector(getHoveredComponents)\n  const isMouseOver =\n    hoveredComponents[hoveredComponents.length - 1] === displayName\n\n  const isLikeProductionMode = useSelector(getIsLikeProductMode)\n  const attachedUsers = useSelector(getComponentAttachUsers)\n\n  const componentsAttachedUsers = useMemo(() => {\n    return getTargetCurrentUsersExpendMe(\n      attachedUsers,\n      displayName,\n      currentUserID,\n    )\n  }, [attachedUsers, currentUserID, displayName])\n\n  const handleOnSelection = (e: MouseEvent<HTMLDivElement>) => {\n    const rootState = store.getState()\n    const isEditMode = getIsILLAEditMode(rootState)\n    if (isGlobalResizing || !isEditMode) return\n    const displayNameMapDepth = getComponentDisplayNameMapDepth(rootState)\n    const widgetExecutionLayoutInfo = getClientWidgetLayoutInfo(rootState)\n    FocusManager.switchFocus(\"canvas\", {\n      displayName: displayName,\n      type: \"component\",\n      clickPosition: [],\n    })\n\n    e.stopPropagation()\n\n    trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SELECT, {\n      element: \"component\",\n      parameter1: \"click\",\n    })\n\n    if ((isMAC() && e.metaKey) || e.shiftKey || (!isMAC() && e.ctrlKey)) {\n      let currentSelectedDisplayName = klona(selectedComponents)\n      const index = currentSelectedDisplayName.findIndex(\n        (currentDisplayName) => displayName === currentDisplayName,\n      )\n      if (index !== -1) {\n        currentSelectedDisplayName.splice(index, 1)\n      } else {\n        currentSelectedDisplayName.push(displayName)\n      }\n\n      const depths = currentSelectedDisplayName.map((displayName) => {\n        return displayNameMapDepth[displayName]\n      })\n      let isEqual = depths.every((depth) => depth === depths[0])\n      if (!isEqual) {\n        return\n      }\n      if (currentSelectedDisplayName.length > 1) {\n        const firstParentNode =\n          widgetExecutionLayoutInfo[currentSelectedDisplayName[0]].parentNode\n        const isSameParentNode = currentSelectedDisplayName.every(\n          (displayName) => {\n            const parentNode = widgetExecutionLayoutInfo[displayName].parentNode\n            return parentNode === firstParentNode\n          },\n        )\n        if (!isSameParentNode) {\n          const lastParentNode =\n            widgetExecutionLayoutInfo[\n              currentSelectedDisplayName[currentSelectedDisplayName.length - 1]\n            ].parentNode\n          currentSelectedDisplayName = currentSelectedDisplayName.filter(\n            (displayName) => {\n              const currentParentNode =\n                widgetExecutionLayoutInfo[displayName].parentNode\n              return lastParentNode === currentParentNode\n            },\n          )\n        }\n      }\n      currentSelectedDisplayName = Array.from(\n        new Set(currentSelectedDisplayName),\n      )\n      dispatch(\n        configActions.updateSelectedComponent(currentSelectedDisplayName),\n      )\n      return\n    }\n\n    dispatch(configActions.updateSelectedComponent([displayName]))\n  }\n\n  const handleContextMenu = useCallback(\n    (e: MouseEvent<HTMLDivElement>) => {\n      FocusManager.switchFocus(\"canvas\", {\n        displayName: displayName,\n        type: \"component\",\n        clickPosition: [],\n      })\n      e.stopPropagation()\n      dispatch(configActions.updateSelectedComponent([displayName]))\n    },\n    [displayName, dispatch],\n  )\n\n  return !isResizingWithOthers ? (\n    <>\n      <PositionContainer x={widgetLeft} y={widgetTop} displayName={displayName}>\n        <Dropdown\n          disabled={!isEditMode}\n          position=\"right-start\"\n          trigger=\"contextmenu\"\n          dropList={\n            <DropList w=\"184px\">\n              <DropListItem\n                value=\"duplicate\"\n                title={t(\"editor.context_menu.duplicate\")}\n                onClick={() => {\n                  CopyManager.copyComponentNodeByDisplayName([displayName])\n                  CopyManager.paste(\"duplicate\")\n                }}\n              />\n              <DropListItem\n                deleted\n                value=\"delete\"\n                title={t(\"editor.context_menu.delete\")}\n                onClick={() => {\n                  shortcut.showDeleteDialog([displayName], \"widget\", {\n                    source: \"manage_delete\",\n                  })\n                }}\n              />\n            </DropList>\n          }\n          onVisibleChange={(visible) => {\n            if (visible) {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n                element: \"component_management_canvas\",\n                parameter1: widgetType,\n              })\n            }\n          }}\n        >\n          <div\n            data-displayname={displayName}\n            data-parentnode={parentNodeDisplayName}\n            onMouseEnter={handleMouseEnter}\n            onMouseLeave={handleMouseLeave}\n            onClick={handleOnSelection}\n            onContextMenu={handleContextMenu}\n            css={resizingContainerStyle(\n              {\n                width: widgetWidth,\n                height: widgetHeight,\n                minWidth: DEFAULT_MIN_COLUMN * unitW,\n                minHeight:\n                  (currentWidgetLayoutInfo?.layoutInfo.minH ?? 3) * UNIT_HEIGHT,\n              },\n              {\n                isLikeProductionMode,\n                isSelected,\n                hasEditors: componentsAttachedUsers.length > 0,\n                isHover: isMouseOver,\n                isDragging: false,\n                shownDot: isShownDot,\n              },\n            )}\n          >\n            <DragContainer\n              displayName={displayName}\n              parentNodeDisplayName={parentNodeDisplayName}\n              canDrag={canDrag}\n              unitWidth={unitW}\n              columnNumber={columnNumber}\n            >\n              {!isLikeProductionMode &&\n                (isSelected ||\n                  isMouseOver ||\n                  componentsAttachedUsers.length > 0 ||\n                  isShownDot) && (\n                  <MoveBar\n                    isError={hasError}\n                    displayName={displayName}\n                    maxWidth={widgetWidth}\n                    widgetTop={widgetTop}\n                    widgetType={widgetType}\n                    userList={componentsAttachedUsers}\n                    columnNumber={columnNumber}\n                  />\n                )}\n              {isResizingCurrent ? (\n                <div css={resizingPlaceholderStyle} />\n              ) : (\n                <>\n                  {children}\n                  {isEditMode &&\n                    isSelected &&\n                    !isDraggingStateInGlobal &&\n                    isAutoLimitedMode && (\n                      <AutoHeightWithLimitedContainer\n                        containerHeight={widgetHeight}\n                        displayName={displayName}\n                      />\n                    )}\n                </>\n              )}\n            </DragContainer>\n            {isSelected && !isLikeProductionMode && (\n              <ResizeHandler\n                resizeDirection={resizeDirection}\n                displayName={displayName}\n              />\n            )}\n          </div>\n        </Dropdown>\n      </PositionContainer>\n    </>\n  ) : null\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/ResizingAndDragContainer/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface ResizingAndDragContainerProps {\n  unitW: number\n  displayName: string\n  children: ReactNode\n  parentNodeDisplayName: string\n  widgetHeight: number\n  widgetWidth: number\n  widgetLeft: number\n  widgetTop: number\n  widgetType: string\n  columnNumber: number\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/ResizingAndDragContainer/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getWrapperBorder } from \"../../style\"\n\nexport const resizingContainerStyle = (\n  shapeInfo: {\n    width: number\n    height: number\n    minWidth: number\n    minHeight: number\n  },\n  borderInfo: {\n    isLikeProductionMode: boolean\n    isSelected: boolean\n    hasEditors: boolean\n    isHover: boolean\n    isDragging: boolean\n    shownDot: boolean\n  },\n) => {\n  const { width, height, minHeight, minWidth } = shapeInfo\n  const {\n    isLikeProductionMode: isLikProductionMode,\n    isSelected,\n    hasEditors,\n    isHover,\n    isDragging,\n    shownDot,\n  } = borderInfo\n  return css`\n    width: ${width}px;\n    height: ${height}px;\n    min-width: ${minWidth}px;\n    min-height: ${minHeight}px;\n    position: relative;\n    ${getWrapperBorder(\n      isLikProductionMode,\n      isSelected,\n      hasEditors,\n      isHover,\n      isDragging,\n      shownDot,\n    )}\n  `\n}\n\nexport const resizingPlaceholderStyle = css`\n  background-color: rgba(101, 74, 236, 0.1);\n  width: 100%;\n  height: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/ResizingAndDragContainer/utils.tsx",
    "content": "import { ScaleSquareType } from \"@/page/App/components/ScaleSquare/interface\"\nimport {\n  applyBarHandlerStyle,\n  applyBarPointerStyle,\n  applySquarePointerStyle,\n} from \"@/page/App/components/ScaleSquare/style\"\nimport { RESIZE_DIRECTION } from \"@/widgetLibrary/interface\"\n\nexport const getScaleSquareState = (hasError: boolean, isEditMode: boolean) => {\n  if (isEditMode) {\n    return hasError ? \"error\" : \"normal\"\n  }\n  return \"production\"\n}\n\nexport const getResizeHandler = (\n  resizeDirection: RESIZE_DIRECTION,\n  isSelected: boolean,\n  scaleSquareState: ScaleSquareType,\n) => {\n  switch (resizeDirection) {\n    case RESIZE_DIRECTION.HORIZONTAL: {\n      return {\n        right: (\n          <div css={applyBarHandlerStyle(isSelected, scaleSquareState, \"r\")}>\n            <div\n              className=\"handler\"\n              css={applyBarPointerStyle(isSelected, scaleSquareState, \"r\")}\n            />\n          </div>\n        ),\n        left: (\n          <div css={applyBarHandlerStyle(isSelected, scaleSquareState, \"l\")}>\n            <div\n              className=\"handler\"\n              css={applyBarPointerStyle(isSelected, scaleSquareState, \"l\")}\n            />\n          </div>\n        ),\n      }\n    }\n    case RESIZE_DIRECTION.VERTICAL: {\n      return {\n        top: (\n          <div css={applyBarHandlerStyle(isSelected, scaleSquareState, \"t\")}>\n            <div\n              className=\"handler\"\n              css={applyBarPointerStyle(isSelected, scaleSquareState, \"t\")}\n            />\n          </div>\n        ),\n        bottom: (\n          <div css={applyBarHandlerStyle(isSelected, scaleSquareState, \"b\")}>\n            <div\n              className=\"handler\"\n              css={applyBarPointerStyle(isSelected, scaleSquareState, \"b\")}\n            />\n          </div>\n        ),\n      }\n    }\n    case RESIZE_DIRECTION.ALL:\n    default: {\n      return {\n        topLeft: (\n          <div\n            css={applySquarePointerStyle(isSelected, scaleSquareState, \"tl\")}\n          />\n        ),\n        top: (\n          <div css={applyBarHandlerStyle(isSelected, scaleSquareState, \"t\")}>\n            <div\n              className=\"handler\"\n              css={applyBarPointerStyle(isSelected, scaleSquareState, \"t\")}\n            />\n          </div>\n        ),\n        topRight: (\n          <div\n            css={applySquarePointerStyle(isSelected, scaleSquareState, \"tr\")}\n          />\n        ),\n        right: (\n          <div css={applyBarHandlerStyle(isSelected, scaleSquareState, \"r\")}>\n            <div\n              className=\"handler\"\n              css={applyBarPointerStyle(isSelected, scaleSquareState, \"r\")}\n            />\n          </div>\n        ),\n        bottomRight: (\n          <div\n            css={applySquarePointerStyle(isSelected, scaleSquareState, \"br\")}\n          />\n        ),\n        bottom: (\n          <div css={applyBarHandlerStyle(isSelected, scaleSquareState, \"b\")}>\n            <div\n              className=\"handler\"\n              css={applyBarPointerStyle(isSelected, scaleSquareState, \"b\")}\n            />\n          </div>\n        ),\n        bottomLeft: (\n          <div\n            css={applySquarePointerStyle(isSelected, scaleSquareState, \"bl\")}\n          />\n        ),\n        left: (\n          <div css={applyBarHandlerStyle(isSelected, scaleSquareState, \"l\")}>\n            <div\n              className=\"handler\"\n              css={applyBarPointerStyle(isSelected, scaleSquareState, \"l\")}\n            />\n          </div>\n        ),\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/WrapperContainer/index.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, memo, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport {\n  getIsILLAEditMode,\n  getSelectedComponentDisplayNames,\n} from \"@/redux/config/configSelector\"\nimport {\n  getExecutionError,\n  getExecutionResult,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { WrapperContainerProps } from \"./interface\"\nimport { applyWrapperPendingStyle, hoverHotSpotStyle } from \"./style\"\n\nconst WrapperContainer: FC<WrapperContainerProps> = (props) => {\n  const { displayName, widgetHeight, children } = props\n  const executionResult = useSelector(getExecutionResult)\n\n  const selectedComponents = useSelector(getSelectedComponentDisplayNames)\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const errors = useSelector(getExecutionError)\n\n  const isSelected = useMemo(() => {\n    return selectedComponents.some((currentDisplayName) => {\n      return displayName === currentDisplayName\n    })\n  }, [displayName, selectedComponents])\n\n  const realProps: Record<string, any> = get(executionResult, displayName, {})\n  const hasError = useMemo(() => {\n    const keys = Object.keys(errors)\n    return (\n      keys.length > 0 &&\n      keys.some((key) => {\n        return (\n          Array.isArray(errors[key]) &&\n          errors[key].length > 0 &&\n          key.startsWith(displayName)\n        )\n      })\n    )\n  }, [displayName, errors])\n\n  const isAutoLimitedMode = realProps?.dynamicHeight === \"limited\"\n  const isOverLap =\n    isAutoLimitedMode &&\n    (realProps?.dynamicMaxHeight === widgetHeight ||\n      realProps?.dynamicMinHeight === widgetHeight)\n\n  return (\n    <div css={hoverHotSpotStyle}>\n      <div\n        css={applyWrapperPendingStyle({\n          hasError,\n          isSelected,\n          isEditor: isEditMode,\n          isLimitedModeAndOverLap: isOverLap,\n        })}\n      >\n        {children}\n      </div>\n    </div>\n  )\n}\n\nWrapperContainer.displayName = \"WrapperContainer\"\n\nexport default memo(WrapperContainer)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/WrapperContainer/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface WrapperContainerProps {\n  displayName: string\n  widgetHeight: number\n  children: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/components/WrapperContainer/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { WIDGET_PADDING } from \"@/page/App/components/ScaleSquare/constant/widget\"\n\nexport const hoverHotSpotStyle = css`\n  width: 100%;\n  height: 100%;\n`\n\nexport const applyWrapperPendingStyle = ({\n  isSelected,\n  hasError,\n  isEditor,\n  isLimitedModeAndOverLap = false,\n}: {\n  isSelected: boolean\n  hasError: boolean\n  isEditor: boolean\n  isLimitedModeAndOverLap: boolean\n}) => css`\n  width: 100%;\n  height: 100%;\n  padding: ${WIDGET_PADDING}px;\n  background-color: ${isEditor && hasError && !isSelected\n    ? getColor(\"red\", \"08\")\n    : \"transparent\"};\n  ${isLimitedModeAndOverLap && isSelected\n    ? `border-bottom:unset !important`\n    : \"\"}\n  ${isEditor && \"cursor: move\"}\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/constant/moveBar.ts",
    "content": "export const MOVE_BAR_HEIGHT = 18\nexport const MIN_MOVE_BAR_WIDTH = 48\nexport const MOVE_BAR_SVG_WIDTH = 12\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/constant/widget.ts",
    "content": "export const WIDGET_PADDING = 3 // need to modify\nexport const WIDGET_SCALE_SQUARE_BORDER_WIDTH = 1\nexport const CONTAINER_PADDING = 4\nexport const DEFAULT_MIN_COLUMN = 1\nexport const LIKE_CONTAINER_WIDGET_PADDING = 4\nexport const LIST_ITEM_MARGIN_TOP = 16\nexport const LABEL_TOP_UNIT_HEIGHT = 32\nexport const VALIDATE_MESSAGE_HEIGHT = 33\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/index.tsx",
    "content": "import { FC, memo, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport {\n  getIsILLAEditMode,\n  getSelectedComponentDisplayNames,\n} from \"@/redux/config/configSelector\"\nimport { TransformWidgetWrapper } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper\"\nimport { AutoHeightWithLimitedContainer } from \"./components/AutoHeightWithLimitedContainer\"\nimport { ResizingAndDragContainer } from \"./components/ResizingAndDragContainer\"\nimport WrapperContainer from \"./components/WrapperContainer\"\nimport { ScaleSquareProps } from \"./interface\"\nimport { useGetRealShapeAndPosition } from \"./utils/getRealShapeAndPosition\"\n\nconst ScaleSquare: FC<ScaleSquareProps> = (props) => {\n  const {\n    unitW,\n    displayName,\n    parentNodeDisplayName,\n    widgetType,\n    columnNumber,\n  } = props\n  const { width, height, left, top } = useGetRealShapeAndPosition(\n    displayName,\n    unitW,\n  )\n\n  const canDrag = widgetType !== \"MODAL_WIDGET\"\n\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const selectedComponents = useSelector(getSelectedComponentDisplayNames)\n  const isSelected = useMemo(() => {\n    return selectedComponents.some((currentDisplayName) => {\n      return displayName === currentDisplayName\n    })\n  }, [displayName, selectedComponents])\n\n  return (\n    <ResizingAndDragContainer\n      displayName={displayName}\n      unitW={unitW}\n      widgetHeight={height}\n      widgetWidth={width}\n      widgetTop={canDrag ? top : 0}\n      widgetLeft={canDrag ? left : 0}\n      parentNodeDisplayName={parentNodeDisplayName}\n      widgetType={widgetType}\n      columnNumber={columnNumber}\n    >\n      <WrapperContainer displayName={displayName} widgetHeight={height}>\n        <TransformWidgetWrapper\n          displayName={displayName}\n          widgetType={widgetType}\n          parentNodeDisplayName={parentNodeDisplayName}\n          columnNumber={columnNumber}\n        />\n      </WrapperContainer>\n      {isEditMode && selectedComponents?.length === 1 && isSelected && (\n        <AutoHeightWithLimitedContainer\n          containerHeight={width}\n          displayName={displayName}\n        />\n      )}\n    </ResizingAndDragContainer>\n  )\n}\n\nexport default memo(ScaleSquare)\n\nScaleSquare.displayName = \"NewScaleSquare\"\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/interface.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\n\nexport type ScaleSquareType = \"error\" | \"normal\" | \"production\"\n\nexport interface ScaleSquareProps {\n  displayName: string\n  unitW: number\n  parentNodeDisplayName: string\n  widgetType: string\n  columnNumber: number\n}\n\nexport interface ScaleSquarePropsWithJSON {\n  componentNode: ComponentTreeNode\n  unitW: number\n  columnNumber: number\n  displayNamePrefix?: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/modalScaleSquare.tsx",
    "content": "import { Resizable, ResizeCallback, ResizeStartCallback } from \"re-resizable\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport {\n  getIsILLAEditMode,\n  getSelectedComponentDisplayNames,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { TransformWidgetWrapper } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper\"\nimport { RESIZE_DIRECTION } from \"@/widgetLibrary/interface\"\nimport { AutoHeightWithLimitedContainer } from \"./components/AutoHeightWithLimitedContainer\"\nimport { DragContainer } from \"./components/DragContainer\"\nimport { getResizeHandler } from \"./components/ResizingAndDragContainer/utils\"\nimport WrapperContainer from \"./components/WrapperContainer\"\nimport { DEFAULT_MIN_COLUMN } from \"./constant/widget\"\nimport { ScaleSquareProps } from \"./interface\"\nimport { modalstopPropagationContainerStyle } from \"./style\"\nimport { useGetRealShapeAndPosition } from \"./utils/getRealShapeAndPosition\"\nimport { useScaleStateSelector } from \"./utils/useScaleStateSelector\"\n\nexport const ModalScaleSquare: FC<ScaleSquareProps> = (props) => {\n  const {\n    unitW,\n    displayName,\n    parentNodeDisplayName,\n    widgetType,\n    columnNumber,\n  } = props\n  const { width, height } = useGetRealShapeAndPosition(displayName, unitW)\n\n  const dispatch = useDispatch()\n\n  const layoutInfoResult = useSelector(getClientWidgetLayoutInfo)\n  const currentWidgetLayoutInfo = layoutInfoResult[displayName]\n\n  const layoutInfo = currentWidgetLayoutInfo?.layoutInfo ?? {}\n\n  const canDrag = widgetType !== \"MODAL_WIDGET\"\n\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const selectedComponents = useSelector(getSelectedComponentDisplayNames)\n  const isSelected = useMemo(() => {\n    return selectedComponents.some((currentDisplayName) => {\n      return displayName === currentDisplayName\n    })\n  }, [displayName, selectedComponents])\n\n  const scaleState = useScaleStateSelector(displayName)\n\n  const handleOnResizeStop: ResizeCallback = useCallback(\n    (e, dir, ref, delta) => {\n      let finalWidth = Math.round((width + delta.width) / unitW)\n      let finalHeight = Math.round((height + delta.height) / UNIT_HEIGHT)\n      finalWidth =\n        finalWidth < DEFAULT_MIN_COLUMN ? DEFAULT_MIN_COLUMN : finalWidth\n      finalHeight =\n        finalHeight < layoutInfo.minH ? layoutInfo.minH : finalHeight\n\n      dispatch(\n        componentsActions.updateComponentLayoutInfoReducer({\n          displayName,\n          layoutInfo: {\n            x: 0,\n            y: 0,\n            w: finalWidth,\n            h: finalHeight,\n          },\n          parentNode: parentNodeDisplayName,\n        }),\n      )\n      dispatch(configActions.setDraggingNodeIDsReducer([]))\n\n      dispatch(configActions.updateShowDot(false))\n    },\n    [\n      dispatch,\n      displayName,\n      height,\n      layoutInfo.minH,\n      parentNodeDisplayName,\n      unitW,\n      width,\n    ],\n  )\n\n  const handleResizeStart: ResizeStartCallback = useCallback(\n    (e) => {\n      e.preventDefault()\n      e.stopPropagation()\n      dispatch(configActions.setDraggingNodeIDsReducer([displayName]))\n\n      dispatch(configActions.updateShowDot(true))\n    },\n    [dispatch, displayName],\n  )\n\n  return (\n    <Resizable\n      bounds=\"parent\"\n      size={{\n        width,\n        height,\n      }}\n      minWidth={DEFAULT_MIN_COLUMN * unitW}\n      minHeight={currentWidgetLayoutInfo.layoutInfo.minH * UNIT_HEIGHT}\n      handleComponent={getResizeHandler(\n        RESIZE_DIRECTION.ALL,\n        isSelected,\n        scaleState,\n      )}\n      onResizeStart={handleResizeStart}\n      onResizeStop={handleOnResizeStop}\n    >\n      <div\n        css={modalstopPropagationContainerStyle}\n        onClick={(e) => e.stopPropagation()}\n      >\n        <DragContainer\n          displayName={displayName}\n          parentNodeDisplayName={parentNodeDisplayName}\n          canDrag={canDrag}\n          columnNumber={columnNumber}\n          unitWidth={unitW}\n        >\n          <WrapperContainer displayName={displayName} widgetHeight={height}>\n            <TransformWidgetWrapper\n              displayName={displayName}\n              widgetType={widgetType}\n              parentNodeDisplayName={parentNodeDisplayName}\n            />\n          </WrapperContainer>\n        </DragContainer>\n        {isEditMode && selectedComponents?.length === 1 && isSelected && (\n          <AutoHeightWithLimitedContainer\n            containerHeight={width}\n            displayName={displayName}\n          />\n        )}\n      </div>\n    </Resizable>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/scaleSquareWithJSON.tsx",
    "content": "import { memo } from \"react\"\nimport { Rnd } from \"react-rnd\"\nimport { TransformWidgetWrapperWithJson } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/renderWithJSON\"\nimport { UNIT_HEIGHT } from \"../DotPanel/constant/canvas\"\nimport { DEFAULT_MIN_COLUMN } from \"./constant/widget\"\nimport { ScaleSquarePropsWithJSON } from \"./interface\"\nimport { jsonWrapperPendingStyle } from \"./style\"\nimport { getRealShapeAndPosition } from \"./utils/getRealShapeAndPosition\"\n\nconst ScaleSquareWithJSON = (props: ScaleSquarePropsWithJSON) => {\n  const { componentNode, unitW, displayNamePrefix } = props\n  const { x, y, w, h } = getRealShapeAndPosition(\n    componentNode,\n    unitW,\n    displayNamePrefix,\n  )\n\n  return (\n    <Rnd\n      bounds=\"parent\"\n      size={{\n        width: w,\n        height: h,\n      }}\n      position={{\n        x: x,\n        y: y,\n      }}\n      enableResizing={false}\n      disableDragging\n      minWidth={DEFAULT_MIN_COLUMN * unitW}\n      minHeight={componentNode.minH * UNIT_HEIGHT}\n    >\n      <div className=\"wrapperPending\" css={jsonWrapperPendingStyle}>\n        <TransformWidgetWrapperWithJson\n          componentNode={componentNode}\n          unitW={unitW}\n        />\n      </div>\n    </Rnd>\n  )\n}\n\nScaleSquareWithJSON.displayName = \"ScaleSquareWithJSON\"\nexport default memo(ScaleSquareWithJSON)\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\nimport { ScaleSquareType } from \"@/page/App/components/ScaleSquare/interface\"\n\nexport type BarPosition = \"l\" | \"r\" | \"t\" | \"b\" | \"tl\" | \"tr\" | \"bl\" | \"br\"\n\nexport function getSelectedColor(selected: boolean): string {\n  return selected ? globalColor(`--${illaPrefix}-techPurple-03`) : \"transparent\"\n}\n\nexport function applySquarePointerStyle(\n  selected: boolean,\n  scaleSquareType: ScaleSquareType,\n  pointerPosition: BarPosition,\n): SerializedStyles {\n  if (scaleSquareType === \"production\") {\n    return css`\n      visibility: hidden;\n    `\n  }\n  let positionStyle: SerializedStyles\n  switch (pointerPosition) {\n    case \"tl\":\n      positionStyle = css`\n        top: 8px;\n        left: 8px;\n        cursor: ${selected ? \"nwse-resize\" : \"default\"};\n      `\n      break\n    case \"tr\":\n      positionStyle = css`\n        cursor: ${selected ? \"nesw-resize\" : \"default\"};\n        top: 8px;\n        right: 8px;\n      `\n      break\n    case \"bl\":\n      positionStyle = css`\n        cursor: ${selected ? \"nesw-resize\" : \"default\"};\n        bottom: 8px;\n        left: 8px;\n      `\n      break\n    case \"br\":\n      positionStyle = css`\n        cursor: ${selected ? \"nwse-resize\" : \"default\"};\n        bottom: 8px;\n        right: 8px;\n      `\n      break\n    default:\n      positionStyle = css``\n      break\n  }\n\n  const baseColor = getSelectedColor(selected)\n\n  return css`\n    ${positionStyle};\n    box-sizing: border-box;\n    border: 1px solid ${baseColor};\n    height: 5px;\n    width: 5px;\n    position: absolute;\n    background: ${selected\n      ? globalColor(`--${illaPrefix}-white-01`)\n      : \"transparent\"};\n    z-index: 150;\n    &:active {\n      background: ${baseColor};\n    }\n\n    &:hover {\n      background: ${baseColor};\n    }\n  `\n}\n\nexport const applyBarPointerShapeStyle = (barPosition: BarPosition) => {\n  let barPositionStyle: SerializedStyles\n\n  switch (barPosition) {\n    case \"t\":\n      barPositionStyle = css`\n        left: 0;\n        right: 0;\n        margin: auto;\n        height: 5px;\n        width: 24px;\n      `\n      break\n    case \"b\":\n      barPositionStyle = css`\n        left: 0;\n        right: 0;\n        margin: auto;\n        height: 5px;\n        width: 24px;\n      `\n      break\n    case \"l\":\n      barPositionStyle = css`\n        bottom: 0;\n        top: 0;\n        margin: auto;\n        width: 5px;\n        height: 24px;\n      `\n      break\n    case \"r\":\n      barPositionStyle = css`\n        bottom: 0;\n        top: 0;\n        margin: auto;\n        width: 5px;\n        height: 24px;\n      `\n      break\n    default:\n      barPositionStyle = css``\n  }\n  return css`\n    ${barPositionStyle};\n    box-sizing: border-box;\n    position: absolute;\n    border-radius: 2.5px;\n    background-color: ${globalColor(`--${illaPrefix}-white-01`)};\n  `\n}\n\nexport function applyBarPointerStyle(\n  selected: boolean,\n  scaleSquareType: ScaleSquareType,\n  barPosition: BarPosition,\n  isLimitedMode: boolean = false,\n): SerializedStyles {\n  if (scaleSquareType === \"production\") {\n    return css`\n      visibility: hidden;\n    `\n  }\n\n  let barPositionStyle: SerializedStyles =\n    applyBarPointerShapeStyle(barPosition)\n\n  const baseColor =\n    isLimitedMode && selected\n      ? getColor(\"techPink\", \"03\")\n      : getSelectedColor(selected)\n  return css`\n    ${barPositionStyle};\n    border: 1px solid ${baseColor};\n    :hover {\n      background-color: ${isLimitedMode\n        ? getColor(\"techPink\", \"03\")\n        : getColor(\"techPurple\", \"03\")};\n    }\n    :active {\n      background-color: ${isLimitedMode\n        ? getColor(\"techPink\", \"03\")\n        : getColor(\"techPurple\", \"03\")};\n    }\n  `\n}\n\nexport function applyBarHandlerStyle(\n  selected: boolean,\n  scaleSquareType: ScaleSquareType,\n  barPosition: BarPosition,\n): SerializedStyles {\n  if (scaleSquareType === \"production\") {\n    return css`\n      visibility: hidden;\n    `\n  }\n  let barPositionStyle: SerializedStyles\n  switch (barPosition) {\n    case \"t\":\n      barPositionStyle = css`\n        top: 3px;\n        left: 0;\n        right: 0;\n        height: 5px;\n        cursor: ${selected ? \"row-resize\" : \"default\"};\n      `\n      break\n    case \"b\":\n      barPositionStyle = css`\n        bottom: 3px;\n        left: 0;\n        right: 0;\n        height: 5px;\n        cursor: ${selected ? \"row-resize\" : \"default\"};\n      `\n      break\n    case \"l\":\n      barPositionStyle = css`\n        bottom: 0;\n        left: 3px;\n        top: 0;\n        width: 5px;\n        cursor: ${selected ? \"col-resize\" : \"default\"};\n      `\n      break\n    case \"r\":\n      barPositionStyle = css`\n        bottom: 0;\n        right: 3px;\n        top: 0;\n        cursor: ${selected ? \"col-resize\" : \"default\"};\n        width: 5px;\n      `\n      break\n    default:\n      barPositionStyle = css``\n  }\n\n  return css`\n    ${barPositionStyle};\n    position: absolute;\n  `\n}\n\nconst getWrapperBorderColor = (\n  isSelected: boolean,\n  hasEditors: boolean,\n  isHover: boolean,\n  shownDot: boolean,\n) => {\n  if (isSelected || hasEditors || isHover || shownDot) {\n    return getColor(\"techPurple\", \"03\")\n  }\n  return \"transparent\"\n}\n\nconst getWrapperBorderStyle = (\n  hasEditors: boolean,\n  isSelected: boolean,\n  isDragging: boolean,\n  isHover: boolean,\n  shownDot: boolean,\n) => {\n  if (shownDot || (hasEditors && !isSelected && !isDragging && !isHover)) {\n    return \"dashed\"\n  }\n  return \"solid\"\n}\n\nexport const getWrapperBorder = (\n  isLikProductionMode: boolean,\n  isSelected: boolean,\n  hasEditors: boolean,\n  isHover: boolean,\n  isDragging: boolean,\n  shownDot: boolean,\n) => {\n  if (isLikProductionMode) {\n    return css`\n      border: none;\n    `\n  }\n  return css`\n    border-width: 1px;\n    border-style: ${getWrapperBorderStyle(\n      hasEditors,\n      isSelected,\n      isDragging,\n      isHover,\n      shownDot,\n    )};\n    border-color: ${getWrapperBorderColor(\n      isSelected,\n      hasEditors,\n      isHover,\n      shownDot,\n    )};\n  `\n}\n\nexport const jsonWrapperPendingStyle = css`\n  width: 100%;\n  height: 100%;\n  padding: 2px;\n  background-color: transparent;\n`\n\nexport const applyDashedLineStyle = (\n  isSelected: boolean,\n  isShowCanvasDot: boolean,\n  isDragging: boolean,\n  maxHeight?: number,\n) => css`\n  width: 100%;\n  height: 100%;\n  position: absolute;\n  top: 0;\n  left: 0;\n  max-height: ${maxHeight ? `${maxHeight}px` : \"unset\"};\n  pointer-events: none;\n  border: ${isShowCanvasDot && !isSelected && !isDragging\n    ? `1px dashed ${globalColor(`--${illaPrefix}-techPurple-03`)}`\n    : \"none\"};\n`\n\nexport const applyXDirectionDashedLineStyle = (\n  isSelected: boolean,\n  isShowCanvasDot: boolean,\n  isDragging: boolean,\n  maxHeight?: number,\n) => css`\n  width: 100%;\n  height: 100%;\n  position: absolute;\n  top: 0;\n  left: 0;\n  max-height: ${maxHeight ? `${maxHeight}px` : \"unset\"};\n  pointer-events: none;\n  border-left: ${isShowCanvasDot && !isSelected && !isDragging\n    ? `1px dashed ${globalColor(`--${illaPrefix}-techPurple-03`)}`\n    : \"none\"};\n  border-right: ${isShowCanvasDot && !isSelected && !isDragging\n    ? `1px dashed ${globalColor(`--${illaPrefix}-techPurple-03`)}`\n    : \"none\"};\n`\n\nexport const modalstopPropagationContainerStyle = css`\n  width: 100%;\n  height: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/utils/getRealShapeAndPosition.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { get } from \"lodash-es\"\nimport { useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport store from \"@/store\"\n\nexport const getRealShapeAndPosition = (\n  componentNode: ComponentTreeNode,\n  unitW: number,\n  displayNamePrefix?: string,\n) => {\n  const rootState = store.getState()\n  const executionResult = getClientWidgetLayoutInfo(rootState)\n  let realDisplayName = componentNode.displayName\n  if (displayNamePrefix) {\n    realDisplayName = realDisplayName.replace(displayNamePrefix, \"\")\n  }\n  const widgetLayoutInfo = get(executionResult, realDisplayName, undefined)\n  if (!widgetLayoutInfo) {\n    return {\n      x: -1,\n      y: -1,\n      w: -1,\n      h: -1,\n    }\n  }\n  const layoutInfo = widgetLayoutInfo.layoutInfo\n  const {\n    x: propsPositionX,\n    y: propsPositionY,\n    w: sharpeW,\n    h: sharpeH,\n  } = layoutInfo\n  const x = (propsPositionX || componentNode.x) * unitW\n  const y = (propsPositionY || componentNode.y) * UNIT_HEIGHT\n  const w = (sharpeW || componentNode.w) * unitW\n  const h = (sharpeH || componentNode.h) * UNIT_HEIGHT\n  return {\n    x,\n    y,\n    w,\n    h,\n  }\n}\n\nexport const useGetRealShapeAndPosition = (\n  displayName: string,\n  unitW: number,\n  displayNamePrefix?: string,\n) => {\n  const layoutInfos = useSelector(getClientWidgetLayoutInfo)\n\n  const result = useMemo(() => {\n    let realDisplayName = displayName\n    if (displayNamePrefix) {\n      realDisplayName = realDisplayName.replace(displayNamePrefix, \"\")\n    }\n    const widgetLayoutInfo = get(layoutInfos, realDisplayName, undefined)\n    if (!widgetLayoutInfo) {\n      return {\n        left: -1,\n        top: -1,\n        width: -1,\n        height: -1,\n      }\n    }\n    const layoutInfo = widgetLayoutInfo.layoutInfo\n    const {\n      x: propsPositionX,\n      y: propsPositionY,\n      w: sharpeW,\n      h: sharpeH,\n    } = layoutInfo\n    return {\n      left: propsPositionX * unitW,\n      top: propsPositionY * UNIT_HEIGHT,\n      width: sharpeW * unitW,\n      height: sharpeH * UNIT_HEIGHT,\n    }\n  }, [displayName, displayNamePrefix, layoutInfos, unitW])\n\n  return result\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/utils/useGetDisplayNameInMoveBar.ts",
    "content": "import { get } from \"lodash-es\"\nimport { useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\n\nexport const useDisplayNameInMoveBarSelector = (\n  displayName: string,\n  widgetType: string,\n) => {\n  const executionResult = useSelector(\n    getExecutionResult,\n    (prev, next) => prev === next,\n  )\n  const realProps: Record<string, any> = get(executionResult, displayName, {})\n\n  const displayNameInMoveBar = useMemo(() => {\n    if (\n      widgetType === \"CONTAINER_WIDGET\" &&\n      realProps.hasOwnProperty(\"currentIndex\") &&\n      realProps.hasOwnProperty(\"viewList\")\n    ) {\n      const { currentIndex, viewList } = realProps\n      if (!Array.isArray(viewList) || currentIndex >= viewList.length)\n        return displayName + \" / \" + \"View 1\"\n      const labelName = viewList[currentIndex]\n        ? viewList[currentIndex].label\n        : currentIndex\n      return displayName + \" / \" + labelName\n    }\n    return displayName\n  }, [displayName, realProps, widgetType])\n\n  return displayNameInMoveBar\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/utils/useMouseHover.ts",
    "content": "import { MouseEvent, useCallback, useContext, useEffect } from \"react\"\nimport { useDragDropManager } from \"react-dnd\"\nimport { useDispatch } from \"react-redux\"\nimport { MouseHoverContext } from \"@/page/App/components/DotPanel/context/mouseHoverContext\"\nimport { configActions } from \"@/redux/config/configSlice\"\n\nexport const useMouseHover = () => {\n  const dragDropManager = useDragDropManager()\n  const isDragging = dragDropManager.getMonitor().isDragging()\n  const dispatch = useDispatch()\n  const hoverContext = useContext(MouseHoverContext)\n\n  useEffect(() => {\n    if (isDragging) {\n      hoverContext.hoveredWidgets.length > 0 &&\n        dispatch(configActions.updateHoveredComponent([]))\n    }\n  }, [dispatch, hoverContext.hoveredWidgets.length, isDragging])\n\n  const handleMouseEnter = useCallback(\n    (e: MouseEvent<HTMLDivElement>) => {\n      if (isDragging) return\n      const currentDisplayName =\n        e.currentTarget.getAttribute(\"data-displayname\")\n      if (!currentDisplayName) return\n      hoverContext.addHoverWidget(currentDisplayName)\n    },\n    [hoverContext, isDragging],\n  )\n\n  const handleMouseLeave = useCallback(\n    (e: MouseEvent<HTMLDivElement>) => {\n      const currentDisplayName =\n        e.currentTarget.getAttribute(\"data-displayname\")\n      if (!currentDisplayName) return\n      hoverContext.deleteHoverWidget(currentDisplayName)\n    },\n    [hoverContext],\n  )\n\n  return {\n    handleMouseEnter,\n    handleMouseLeave,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/components/ScaleSquare/utils/useScaleStateSelector.ts",
    "content": "import { useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport { getExecutionError } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { getScaleSquareState } from \"../components/ResizingAndDragContainer/utils\"\n\nexport const useScaleStateSelector = (displayName: string) => {\n  const errors = useSelector(getExecutionError)\n  const hasError = useMemo(() => {\n    const keys = Object.keys(errors)\n    return (\n      keys.length > 0 &&\n      keys.some((key) => {\n        return (\n          Array.isArray(errors[key]) &&\n          errors[key].length > 0 &&\n          key.startsWith(displayName)\n        )\n      })\n    )\n  }, [displayName, errors])\n\n  const isEditMode = useSelector(getIsILLAEditMode)\n\n  return getScaleSquareState(hasError, isEditMode)\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n} from \"@illa-public/mixpanel-utils\"\nimport {\n  getCurrentTeamInfo,\n  getCurrentUser,\n  getPlanUtils,\n} from \"@illa-public/user-data\"\nimport { canManage } from \"@illa-public/user-role-utils\"\nimport { ACTION_MANAGE, ATTRIBUTE_GROUP } from \"@illa-public/user-role-utils\"\nimport { Unsubscribe } from \"@reduxjs/toolkit\"\nimport { motion, useAnimation } from \"framer-motion\"\nimport { FC, MouseEvent, useCallback, useEffect } from \"react\"\nimport { Helmet } from \"react-helmet-async\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useBeforeUnload, useParams } from \"react-router-dom\"\nimport { TriggerProvider, WarningCircleIcon } from \"@illa-design/react\"\nimport { Connection, fixedWsURL } from \"@/api/ws\"\nimport {\n  ILLA_WEBSOCKET_CONTEXT,\n  ILLA_WEBSOCKET_STATUS,\n} from \"@/api/ws/interface\"\nimport { useInitBuilderApp } from \"@/hooks/useInitApp\"\nimport { ActionEditor } from \"@/page/App/Module/ActionEditor\"\nimport { CanvasPanel } from \"@/page/App/Module/CanvasPanel\"\nimport { ComponentsManager } from \"@/page/App/Module/ComponentManager\"\nimport { AppLoading } from \"@/page/App/components/AppLoading\"\nimport { Debugger } from \"@/page/App/components/Debugger\"\nimport { setupConfigListeners } from \"@/redux/config/configListener\"\nimport {\n  getAppWSStatus,\n  getIsOnline,\n  isOpenBottomPanel,\n  isOpenDebugger,\n  isOpenRightPanel,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { setupActionListeners } from \"@/redux/currentApp/action/actionListener\"\nimport { getAppInfo } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { collaboratorsActions } from \"@/redux/currentApp/collaborators/collaboratorsSlice\"\nimport { setupComponentsListeners } from \"@/redux/currentApp/components/componentsListener\"\nimport { setupExecutionListeners } from \"@/redux/currentApp/executionTree/executionListener\"\nimport { setupLayoutInfoListeners } from \"@/redux/currentApp/layoutInfo/layoutInfoListener\"\nimport { fetchAppBinaryWsUrl, fetchAppTextWsUrl } from \"@/services/public\"\nimport { startAppListening } from \"@/store\"\nimport { MediaSourceLoadProvider } from \"@/utils/mediaSourceLoad\"\nimport {\n  track,\n  trackPageDurationEnd,\n  trackPageDurationStart,\n} from \"@/utils/mixpanelHelper\"\nimport { Shortcut } from \"@/utils/shortcut\"\nimport LeftPanel from \"./Module/LeftPanel\"\nimport { PageNavBar } from \"./Module/PageNavBar\"\nimport { useResize } from \"./components/ScaleSquare/components/ResizingAndDragContainer/ResizeHandler/hooks\"\nimport {\n  bottomPanelStyle,\n  centerPanelStyle,\n  contentStyle,\n  editorContainerStyle,\n  messageWrapperStyle,\n  middlePanelStyle,\n  modalStyle,\n  navbarStyle,\n  waringIconStyle,\n} from \"./style\"\n\nexport const Editor: FC = () => {\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n  const { appId } = useParams()\n  const controls = useAnimation()\n\n  const currentUser = useSelector(getCurrentUser)\n  const teamInfo = useSelector(getCurrentTeamInfo)\n  const wsStatus = useSelector(getAppWSStatus)\n\n  const currentUserRole = teamInfo?.myRole\n\n  const handleLeaveRoom = useCallback(() => {\n    Connection.leaveRoom(\"app\", appId ?? \"\")\n  }, [appId])\n\n  // check if user can manage the app\n  if (currentUserRole) {\n    const canEditApp = canManage(\n      currentUserRole,\n      ATTRIBUTE_GROUP.APP,\n      getPlanUtils(teamInfo),\n      ACTION_MANAGE.EDIT_APP,\n    )\n    if (!canEditApp) {\n      throw new Error(\"You don't have permission to edit this app\")\n    }\n  }\n  useEffect(() => {\n    const abortController = new AbortController()\n    if (currentUser != null && currentUser.userID != \"\" && appId) {\n      Promise.all([\n        fetchAppTextWsUrl(appId, abortController.signal),\n        fetchAppBinaryWsUrl(appId, abortController.signal),\n      ])\n        .then((res) => {\n          Connection.enterAppRoom(\n            fixedWsURL(res[0].data.wsURL),\n            fixedWsURL(res[1].data.wsURL),\n            appId as string,\n          )\n        })\n        .catch(() => {})\n      window.addEventListener(\"beforeunload\", handleLeaveRoom)\n    }\n    return () => {\n      abortController.abort()\n      handleLeaveRoom()\n      dispatch(\n        collaboratorsActions.setInRoomUsers({\n          inRoomUsers: [],\n        }),\n      )\n      dispatch(\n        configActions.updateWSStatusReducer({\n          context: ILLA_WEBSOCKET_CONTEXT.APP,\n          wsStatus: ILLA_WEBSOCKET_STATUS.CLOSED,\n        }),\n      )\n      window.removeEventListener(\"beforeunload\", handleLeaveRoom)\n    }\n  }, [currentUser, appId, handleLeaveRoom, dispatch])\n\n  useEffect(() => {\n    const subscriptions: Unsubscribe[] = [\n      setupExecutionListeners(startAppListening),\n      setupLayoutInfoListeners(startAppListening),\n      setupComponentsListeners(startAppListening),\n      setupActionListeners(startAppListening),\n      setupConfigListeners(startAppListening),\n    ]\n    return () => subscriptions.forEach((unsubscribe) => unsubscribe())\n  }, [])\n\n  const showRightPanel = useSelector(isOpenRightPanel)\n  const showBottomPanel = useSelector(isOpenBottomPanel)\n  const showDebugger = useSelector(isOpenDebugger)\n  const isOnline = useSelector(getIsOnline)\n\n  // init app\n  const { loadingState } = useInitBuilderApp(\"edit\")\n\n  const handleMouseDownOnModal = useCallback(\n    (e: MouseEvent<HTMLDivElement>) => {\n      e.stopPropagation()\n      controls\n        .start({\n          scale: 1.05,\n          transition: {\n            duration: 0.2,\n          },\n        })\n        .then(() => {\n          controls.start({\n            scale: 1,\n            transition: {\n              duration: 0.2,\n            },\n          })\n        })\n    },\n    [controls],\n  )\n\n  useEffect(() => {\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.VISIT,\n      ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR,\n    )\n    trackPageDurationStart()\n    return () => {\n      trackPageDurationEnd(ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR)\n    }\n  }, [])\n\n  useBeforeUnload(() => {\n    trackPageDurationEnd(ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR)\n  })\n\n  const [, resizeDropRef] = useResize()\n\n  const appInfo = useSelector(getAppInfo)\n\n  const combineLoadingState =\n    loadingState ||\n    wsStatus === ILLA_WEBSOCKET_STATUS.INIT ||\n    wsStatus === ILLA_WEBSOCKET_STATUS.CONNECTING\n\n  return (\n    <>\n      <Helmet>\n        <title>{appInfo.appName}</title>\n      </Helmet>\n      <div css={editorContainerStyle} ref={resizeDropRef}>\n        {combineLoadingState && <AppLoading />}\n        {!combineLoadingState && (\n          <Shortcut>\n            <MediaSourceLoadProvider>\n              <TriggerProvider renderInBody zIndex={10}>\n                <PageNavBar css={navbarStyle} />\n              </TriggerProvider>\n              <div css={contentStyle}>\n                <LeftPanel />\n                <div css={middlePanelStyle}>\n                  <TriggerProvider renderInBody zIndex={10}>\n                    <CanvasPanel css={centerPanelStyle} />\n                  </TriggerProvider>\n                  <TriggerProvider renderInBody zIndex={10}>\n                    {showBottomPanel && !showDebugger ? <ActionEditor /> : null}\n                  </TriggerProvider>\n                  {showDebugger && <Debugger css={bottomPanelStyle} />}\n                </div>\n                {showRightPanel && (\n                  <TriggerProvider renderInBody zIndex={10}>\n                    <ComponentsManager />\n                  </TriggerProvider>\n                )}\n              </div>\n              {!isOnline && (\n                <div css={modalStyle} onMouseDown={handleMouseDownOnModal}>\n                  <motion.div css={messageWrapperStyle} animate={controls}>\n                    <WarningCircleIcon css={waringIconStyle} />\n                    {wsStatus === ILLA_WEBSOCKET_STATUS.LOCKING\n                      ? t(\"editor.history.message.version_change\")\n                      : t(\"not_online_tips\")}\n                  </motion.div>\n                </div>\n              )}\n            </MediaSourceLoadProvider>\n          </Shortcut>\n        )}\n      </div>\n    </>\n  )\n}\n\nexport default Editor\n\nEditor.displayName = \"Editor\"\n"
  },
  {
    "path": "apps/builder/src/page/App/resp/currentAppResp.ts",
    "content": "import {\n  ActionContent,\n  AppInfoShape,\n  ComponentTreeNode,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { DependenciesState } from \"@/redux/currentApp/executionTree/executionState\"\n\nexport interface CurrentAppResp {\n  appInfo: AppInfoShape\n  components: ComponentTreeNode\n  actions: ActionItem<ActionContent>[]\n  dependenciesState: DependenciesState\n  executionState: Record<string, any>\n}\n"
  },
  {
    "path": "apps/builder/src/page/App/style.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\nimport { LEFT_PANEL_WIDTH, NAVBAR_HEIGHT, RIGHT_PANEL_WIDTH } from \"@/style\"\n\nexport const editorContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  height: 100vh;\n  width: 100vw;\n  position: relative;\n`\n\nexport const contentStyle = css`\n  box-sizing: border-box;\n  display: flex;\n  flex-direction: row;\n  background: #fafafb;\n  flex-grow: 1;\n  width: 100%;\n  overflow: auto;\n`\n\nexport const loadingStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n\nexport const navbarStyle = css`\n  box-sizing: border-box;\n  width: 100%;\n  height: ${NAVBAR_HEIGHT}px;\n  flex: none;\n`\n\nexport const leftPanelStyle = css`\n  width: ${LEFT_PANEL_WIDTH}px;\n  height: 100%;\n  min-width: ${LEFT_PANEL_WIDTH}px;\n  overflow: hidden;\n  box-sizing: border-box;\n  border-right: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  background: ${globalColor(`--${illaPrefix}-white-01`)};\n  padding-bottom: 48px;\n`\n\nexport const centerPanelStyle = css`\n  height: 100%;\n  width: 100%;\n`\n\nexport const bottomPanelStyle = css`\n  box-sizing: border-box;\n  width: 100%;\n`\n\nexport const rightPanelStyle = css`\n  box-sizing: border-box;\n  width: ${RIGHT_PANEL_WIDTH}px;\n  min-width: ${RIGHT_PANEL_WIDTH}px;\n  height: 100%;\n  border-left: 1px solid ${globalColor(`--${illaPrefix}-grayBlue-08`)};\n  background: ${globalColor(`--${illaPrefix}-white-01`)};\n`\n\nexport const middlePanelStyle = css`\n  flex-grow: 1;\n  min-width: ${RIGHT_PANEL_WIDTH}px;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n  background: ${globalColor(`--${illaPrefix}-white-01`)};\n`\n\nexport const modalStyle = css`\n  position: absolute;\n  top: 47px;\n  width: 100vw;\n  height: calc(100vh - 47px);\n  z-index: 100;\n  display: flex;\n  justify-content: center;\n  user-select: none;\n`\n\nexport const messageWrapperStyle = css`\n  position: absolute;\n  top: 17px;\n  height: 40px;\n  background-color: ${getColor(\"white\", \"01\")};\n  padding: 9px 16px;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n  border-radius: 2px;\n  font-size: 14px;\n  display: flex;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const waringIconStyle = css`\n  color: ${getColor(\"orange\", \"03\")};\n  font-size: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/Deploy/Watermark/index.tsx",
    "content": "import { UpgradeIcon } from \"@illa-public/icon\"\nimport { USER_ROLE } from \"@illa-public/public-types\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { getCurrentTeamInfo, getPlanUtils } from \"@illa-public/user-data\"\nimport {\n  ACTION_MANAGE,\n  ATTRIBUTE_GROUP,\n  canManage,\n  canUseUpgradeFeature,\n} from \"@illa-public/user-role-utils\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { FC, useCallback, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { Button, DownIcon, Switch, Trigger } from \"@illa-design/react\"\nimport Logo from \"@/assets/illa-logo.svg?react\"\nimport { getCurrentAppWaterMarkConfig } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { appInfoActions } from \"@/redux/currentApp/appInfo/appInfoSlice\"\nimport { updateWaterMarkConfig } from \"@/services/apps\"\nimport {\n  applyPopupStateStyle,\n  deployLogoStyle,\n  logoStyle,\n  upgradeConfigStyle,\n  upgradePopContainerStyle,\n  upgradeTitleStyle,\n} from \"./style\"\n\nexport const WaterMark: FC = () => {\n  const [popupVisible, setPopupVisible] = useState<boolean>(false)\n  const dispatch = useDispatch()\n\n  const upgradeModal = useUpgradeModal()\n  const { t } = useTranslation()\n  const teamInfo = useSelector(getCurrentTeamInfo)\n  const waterMark = useSelector(getCurrentAppWaterMarkConfig)\n  const { appId } = useParams()\n\n  const currentUserRole = teamInfo?.myRole ?? USER_ROLE.VIEWER\n  const canUseBillingFeature = canUseUpgradeFeature(\n    currentUserRole,\n    getPlanUtils(teamInfo),\n    teamInfo?.totalTeamLicense?.teamLicensePurchased,\n    teamInfo?.totalTeamLicense?.teamLicenseAllPaid,\n  )\n\n  const canUpdateAppWaterMark = canManage(\n    currentUserRole,\n    ATTRIBUTE_GROUP.APP,\n    getPlanUtils(teamInfo),\n    ACTION_MANAGE.EDIT_APP,\n  )\n\n  const handleUpgradeModal = () => {\n    if (!canUseBillingFeature) {\n      upgradeModal({\n        modalType: \"upgrade\",\n        from: \"deploy_watermark\",\n      })\n    }\n  }\n\n  const handleWaterMarkChange = useCallback(\n    async (value: boolean, event: React.MouseEvent<Element, MouseEvent>) => {\n      if (appId) {\n        event.stopPropagation()\n        const res = await updateWaterMarkConfig(!value, appId)\n        dispatch(appInfoActions.updateAppInfoReducer(res.data))\n      }\n    },\n    [appId, dispatch],\n  )\n\n  return (\n    <>\n      {waterMark && (\n        <Trigger\n          trigger=\"click\"\n          colorScheme=\"white\"\n          position=\"top-end\"\n          mb={\"12px\"}\n          popupVisible={popupVisible}\n          onVisibleChange={setPopupVisible}\n          disabled={!isCloudVersion || !canUpdateAppWaterMark}\n          content={\n            canUseBillingFeature ? (\n              <div css={upgradeConfigStyle}>\n                {t(\"billing.advanced.feature\")}\n                <Switch checked={!waterMark} onChange={handleWaterMarkChange} />\n              </div>\n            ) : (\n              <div css={upgradePopContainerStyle}>\n                <div css={upgradeTitleStyle}>\n                  {t(\"billing.modal.upgrade_now_admin.upgrade_to_plus\")}\n                </div>\n                <div>{t(\"billing.advanced.feature\")}</div>\n                <Button\n                  mt=\"8px\"\n                  colorScheme=\"techPurple\"\n                  onClick={() => {\n                    handleUpgradeModal()\n                  }}\n                  leftIcon={<UpgradeIcon />}\n                >\n                  {t(\"billing.homepage.upgrade\")}\n                </Button>\n              </div>\n            )\n          }\n        >\n          <div\n            css={deployLogoStyle}\n            onClick={() => {\n              if (!isCloudVersion || !canUpdateAppWaterMark) {\n                window.open(\"https://illacloud.com\", \"_blank\")\n              }\n            }}\n          >\n            <span>Powered by</span>\n            <Logo css={logoStyle} />\n            {isCloudVersion && canUpdateAppWaterMark && (\n              <DownIcon css={applyPopupStateStyle(popupVisible)} />\n            )}\n          </div>\n        </Trigger>\n      )}\n    </>\n  )\n}\n\nWaterMark.displayName = \"WaterMark\"\n"
  },
  {
    "path": "apps/builder/src/page/Deploy/Watermark/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const deployLogoStyle = css`\n  position: absolute;\n  bottom: 16px;\n  right: 16px;\n  box-shadow: 0 0 8px 0 ${getColor(\"blackAlpha\", \"07\")};\n  border: solid 1px ${getColor(\"grayBlue\", \"09\")};\n  border-radius: 8px;\n  font-size: 12px;\n  padding: 0 12px;\n  height: 40px;\n  display: flex;\n  align-items: center;\n  font-weight: 500;\n  cursor: pointer;\n  background-color: ${getColor(\"white\", \"01\")};\n  gap: 8px;\n`\nexport const logoStyle = css`\n  width: 25px;\n  height: 12px;\n`\n\nexport function applyPopupStateStyle(openState: boolean) {\n  const transform = openState\n    ? css`\n        transform: rotate(180deg);\n      `\n    : css`\n        transform: rotate(0deg);\n      `\n\n  return css`\n    margin-left: 8px;\n    transition: transform 0.2s ease;\n    ${transform};\n  `\n}\n\nexport const upgradeBgStyle = css`\n  padding: 5px 4px;\n`\n\nexport const upgradePopContainerStyle = css`\n  text-align: center;\n  font-size: 12px;\n  line-height: 20px;\n  color: ${getColor(\"grayBlue\", \"03\")};\n  ${upgradeBgStyle};\n`\n\nexport const upgradeTitleStyle = css`\n  font-weight: 500;\n  font-size: 14px;\n  line-height: 22px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const upgradeConfigStyle = css`\n  display: flex;\n  flex-direction: row;\n  justify-content: center;\n  gap: 8px;\n  ${upgradeBgStyle};\n`\n"
  },
  {
    "path": "apps/builder/src/page/Deploy/content.tsx",
    "content": "import {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n} from \"@illa-public/mixpanel-utils\"\nimport { Unsubscribe } from \"@reduxjs/toolkit\"\nimport { AxiosResponse } from \"axios\"\nimport { FC, useEffect } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { useAsyncValue, useBeforeUnload, useParams } from \"react-router-dom\"\nimport { TriggerProvider } from \"@illa-design/react\"\nimport { useDestroyApp } from \"@/hooks/useDestoryExecutionTree\"\nimport { fixedActionToNewAction } from \"@/hooks/utils/fixedAction\"\nimport { fixedComponentsToNewComponents } from \"@/hooks/utils/fixedComponents\"\nimport { WaterMark } from \"@/page/Deploy/Watermark\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { appInfoActions } from \"@/redux/currentApp/appInfo/appInfoSlice\"\nimport { setupComponentsListeners } from \"@/redux/currentApp/components/componentsListener\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { setupExecutionListeners } from \"@/redux/currentApp/executionTree/executionListener\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { setupLayoutInfoListeners } from \"@/redux/currentApp/layoutInfo/layoutInfoListener\"\nimport { startAppListening } from \"@/store\"\nimport { flatTreeToMap } from \"@/utils/componentNode/flatTree\"\nimport {\n  track,\n  trackPageDurationEnd,\n  trackPageDurationStart,\n} from \"@/utils/mixpanelHelper\"\nimport { CanvasPanel } from \"../App/Module/CanvasPanel\"\nimport { CurrentAppResp } from \"../App/resp/currentAppResp\"\n\ninterface IDeployContentAsyncValue {\n  isPublic: boolean\n  appInfo: Promise<AxiosResponse<CurrentAppResp>>\n}\n\nexport const DeployContent: FC = () => {\n  const asyncValue = useAsyncValue() as IDeployContentAsyncValue\n  const dispatch = useDispatch()\n\n  let { pageName } = useParams()\n\n  useEffect(() => {\n    const subscriptions: Unsubscribe[] = [\n      setupComponentsListeners(startAppListening),\n      setupExecutionListeners(startAppListening),\n      setupLayoutInfoListeners(startAppListening),\n    ]\n    return () => subscriptions.forEach((unsubscribe) => unsubscribe())\n  }, [])\n\n  useEffect(() => {\n    const initApp = async () => {\n      const appInfo = await asyncValue.appInfo\n      document.title = appInfo.data.appInfo.appName\n      dispatch(configActions.updateIllaMode(\"production\"))\n      dispatch(appInfoActions.updateAppInfoReducer(appInfo.data.appInfo))\n      const canvasTree = appInfo.data.components\n      let needFixedCanvasTree = canvasTree\n      if (canvasTree.props) {\n        const { homepageDisplayName, pageSortedKey, currentPageIndex } =\n          canvasTree.props\n        let defaultPageIndex: number | undefined\n        const pageIndex = pageSortedKey?.findIndex(\n          (name: string) => name === pageName,\n        )\n        if (pageIndex != undefined && pageIndex !== -1) {\n          defaultPageIndex = pageIndex\n        }\n\n        const homePageIndex = pageSortedKey?.findIndex(\n          (name: string) => name === homepageDisplayName,\n        )\n        if (\n          defaultPageIndex == undefined &&\n          homePageIndex != undefined &&\n          homePageIndex !== -1\n        ) {\n          defaultPageIndex = homePageIndex\n        }\n\n        if (defaultPageIndex == undefined && currentPageIndex != undefined) {\n          defaultPageIndex = currentPageIndex\n        }\n        if (defaultPageIndex == undefined) {\n          defaultPageIndex = 0\n        }\n\n        needFixedCanvasTree = {\n          ...canvasTree,\n          props: {\n            ...canvasTree.props,\n            currentPageIndex: defaultPageIndex,\n          },\n        }\n      }\n      const fixedComponents =\n        fixedComponentsToNewComponents(needFixedCanvasTree)\n      dispatch(\n        componentsActions.initComponentReducer(flatTreeToMap(fixedComponents)),\n      )\n      const fixedActions = fixedActionToNewAction(appInfo.data.actions)\n      dispatch(actionActions.initActionListReducer(fixedActions))\n      dispatch(executionActions.startExecutionReducer())\n    }\n    initApp()\n  }, [asyncValue, dispatch, pageName])\n\n  useDestroyApp()\n\n  useEffect(() => {\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.VISIT,\n      ILLA_MIXPANEL_BUILDER_PAGE_NAME.DEPLOY,\n    )\n    trackPageDurationStart()\n    return () => {\n      trackPageDurationEnd(ILLA_MIXPANEL_BUILDER_PAGE_NAME.DEPLOY)\n    }\n  }, [])\n\n  useBeforeUnload(() => {\n    trackPageDurationEnd(ILLA_MIXPANEL_BUILDER_PAGE_NAME.DEPLOY)\n  })\n\n  return (\n    <TriggerProvider renderInBody zIndex={10}>\n      {<CanvasPanel />}\n      {<WaterMark />}\n    </TriggerProvider>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/Deploy/index.tsx",
    "content": "import { FC, Suspense } from \"react\"\nimport { Helmet } from \"react-helmet-async\"\nimport { useSelector } from \"react-redux\"\nimport { Await, useLoaderData } from \"react-router-dom\"\nimport { FullPageLoading } from \"@/components/FullPageLoading\"\nimport { deployContainerStyle } from \"@/page/Deploy/style\"\nimport Page404 from \"@/page/Status/404\"\nimport { getAppInfo } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { MediaSourceLoadProvider } from \"@/utils/mediaSourceLoad\"\nimport { DeployContent } from \"./content\"\n\nexport const Deploy: FC = () => {\n  const data = useLoaderData()\n\n  const appInfo = useSelector(getAppInfo)\n\n  return (\n    <>\n      <Helmet>\n        <title>{appInfo.appName}</title>\n      </Helmet>\n      <div css={deployContainerStyle}>\n        <Suspense fallback={<FullPageLoading />}>\n          <Await resolve={data} errorElement={<Page404 />}>\n            <MediaSourceLoadProvider>\n              <DeployContent />\n            </MediaSourceLoadProvider>\n          </Await>\n        </Suspense>\n      </div>\n    </>\n  )\n}\n\nexport default Deploy\n\nDeploy.displayName = \"Deploy\"\n"
  },
  {
    "path": "apps/builder/src/page/Deploy/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const deployContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  position: relative;\n`\n\nexport const loadingStyle = css`\n  width: 100%;\n  height: 100vh;\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  justify-content: center;\n  position: absolute;\n`\n\nexport function applyPopupStateStyle(openState?: boolean): SerializedStyles {\n  const transform = openState\n    ? css`\n        transform: rotate(180deg);\n      `\n    : css`\n        transform: rotate(0deg);\n      `\n\n  return css`\n    margin-left: 8px;\n    transition: transform 0.2s ease;\n    ${transform};\n  `\n}\n\nexport const upgradeBgStyle = css`\n  padding: 5px 4px;\n`\n\nexport const upgradePopContainerStyle = css`\n  text-align: center;\n  font-size: 12px;\n  line-height: 20px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-03`)};\n  ${upgradeBgStyle};\n`\n\nexport const upgradeTitleStyle = css`\n  font-weight: 500;\n  font-size: 14px;\n  line-height: 22px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n`\n\nexport const upgradeConfigStyle = css`\n  display: flex;\n  flex-direction: row;\n  justify-content: center;\n  gap: 8px;\n  ${upgradeBgStyle};\n`\n"
  },
  {
    "path": "apps/builder/src/page/History/components/ActionArea/index.tsx",
    "content": "import { FC, useCallback, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { Loading } from \"@illa-design/react\"\nimport {\n  actionTextStyle,\n  actionWrapperStyle,\n} from \"@/page/History/components/ActionArea/style\"\nimport { getSnapshotListCurrentPage } from \"@/redux/currentAppHistory/currentAppHistorySelector\"\nimport { currentAppHistoryActions } from \"@/redux/currentAppHistory/currentAppHistorySlice\"\nimport { fetchSnapShotList } from \"@/services/history\"\n\nexport const ActionArea: FC = () => {\n  const { appId } = useParams()\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const currentPage = useSelector(getSnapshotListCurrentPage)\n  const [loading, setLoading] = useState(false)\n\n  const fetchMore = useCallback(async () => {\n    if (!appId) return\n    setLoading(true)\n    const page = currentPage + 1\n    try {\n      const { data } = await fetchSnapShotList({\n        page,\n        appID: appId,\n      })\n      dispatch(\n        currentAppHistoryActions.updateCurrentAppHistoryReducer({\n          ...data,\n          currentPage: page,\n          hasMore: data.totalPages !== page,\n        }),\n      )\n    } catch (error) {\n      // Handle error\n      console.error(error)\n    } finally {\n      setLoading(false)\n    }\n  }, [appId, currentPage, dispatch])\n\n  return (\n    <div>\n      {loading ? (\n        <div css={actionWrapperStyle}>\n          <Loading colorScheme=\"techPurple\" />\n        </div>\n      ) : (\n        <div css={actionTextStyle} onClick={fetchMore}>\n          {t(\"editor.history.more\")}\n        </div>\n      )}\n    </div>\n  )\n}\n\nActionArea.displayName = \"ActionArea\"\n"
  },
  {
    "path": "apps/builder/src/page/History/components/ActionArea/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const actionWrapperStyle = css`\n  padding: 8px 0;\n  min-height: 38px;\n`\n\nexport const actionTextStyle = css`\n  min-height: 38px;\n  padding: 8px;\n  color: ${getColor(\"techPurple\", \"03\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n  cursor: pointer;\n`\n"
  },
  {
    "path": "apps/builder/src/page/History/components/HistoryNavBar/index.tsx",
    "content": "import { getILLABuilderURL, getILLACloudURL } from \"@illa-public/utils\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { Link, useParams } from \"react-router-dom\"\nimport { Button, ExitIcon } from \"@illa-design/react\"\nimport Logo from \"@/assets/illa-logo.svg?react\"\nimport {\n  informationStyle,\n  logoCursorStyle,\n  nameStyle,\n  navBarStyle,\n  rowCenter,\n} from \"@/page/App/Module/PageNavBar/style\"\nimport { navDescStyle } from \"@/page/History/components/HistoryNavBar/style\"\nimport { getAppInfo } from \"@/redux/currentApp/appInfo/appInfoSelector\"\n\nexport const HistoryNavBar: FC = () => {\n  const { teamIdentifier, appId } = useParams()\n  const { t } = useTranslation()\n\n  const appInfo = useSelector(getAppInfo)\n\n  return (\n    <div css={navBarStyle}>\n      <div css={rowCenter}>\n        <Link to={getILLACloudURL(window.customDomain)}>\n          <Logo width=\"34px\" css={logoCursorStyle} />\n        </Link>\n        <div css={informationStyle}>\n          <div css={nameStyle}>{appInfo.appName}</div>\n        </div>\n      </div>\n      <span css={navDescStyle}>{t(\"editor.history.history_list.label\")}</span>\n      <Link\n        to={`${getILLABuilderURL(\n          window.customDomain,\n        )}/${teamIdentifier}/app/${appId}`}\n      >\n        <Button minW=\"200px\" colorScheme=\"techPurple\" leftIcon={<ExitIcon />}>\n          {t(\"exit_preview\")}\n        </Button>\n      </Link>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/History/components/HistoryNavBar/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const navDescStyle = css`\n  font-weight: 500;\n  font-size: 14px;\n  line-height: 22px;\n  margin-right: 19px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n"
  },
  {
    "path": "apps/builder/src/page/History/components/SnapShotItem/index.tsx",
    "content": "import { Avatar } from \"@illa-public/avatar\"\nimport { isILLAAPiError } from \"@illa-public/illa-net\"\nimport { getILLABuilderURL } from \"@illa-public/utils\"\nimport { formatDate } from \"@illa-public/utils\"\nimport { FC, useCallback, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useParams } from \"react-router-dom\"\nimport { Button, useMessage } from \"@illa-design/react\"\nimport { Signal } from \"@/api/ws/ILLA_PROTO\"\nimport {\n  ModifyHistory,\n  Snapshot,\n  SnapshotTriggerMode,\n} from \"@/redux/currentAppHistory/currentAppHistoryState\"\nimport { recoverSnapShot, recoverSnapShotWS } from \"@/services/history\"\nimport SaveIcon from \"./assets/save.svg?react\"\nimport {\n  applyDotStyle,\n  applyTimeStyle,\n  avatarStyle,\n  badgeDotStyle,\n  contentStyle,\n  descStyle,\n  editorInfoStyle,\n  itemHeaderStyle,\n  leftWrapperStyle,\n  lineStyle,\n  manualStyle,\n  modifyContentStyle,\n  nameStyle,\n  textStyle,\n  timelineStyle,\n} from \"./style\"\n\ninterface SnapShotListProps {\n  snapshot: Snapshot\n  selected?: boolean\n  last: boolean\n  onChangeCurrentID: (snapshotID: string) => void\n}\n\nconst getKeyFromBroadcast = (type: string) => {\n  const typeList = type.split(\"/\")\n  const reduxAction = typeList[1] || \"\"\n  // Basic rules\n  if (reduxAction.startsWith(\"add\")) {\n    return \"editor.history.operation.Added\"\n  } else if (reduxAction.startsWith(\"delete\")) {\n    return \"editor.history.operation.Deleted\"\n  } else if (reduxAction.startsWith(\"update\")) {\n    return \"editor.history.operation.Updated\"\n  } else if (reduxAction.startsWith(\"reset\")) {\n    return \"editor.history.operation.Reseted\"\n  }\n}\n\nexport const SnapShotItem: FC<SnapShotListProps> = (props) => {\n  const message = useMessage()\n  const { teamIdentifier } = useParams()\n  const { t } = useTranslation()\n  const { snapshot, selected, last, onChangeCurrentID } = props\n  const [loading, setLoading] = useState(false)\n\n  const getDescFromBroadcast = useCallback(\n    (type: string, payload: any, operationTargetName: string) => {\n      const typeList = type.split(\"/\")\n      const reduxAction = typeList[1] || \"\"\n      // Supplementary rules\n      if (reduxAction === \"setGlobalStateReducer\") {\n        if (payload?.oldKey) {\n          return t(\"editor.history.operation.Updated\", {\n            operationTargetName: \"globalData\",\n          })\n        }\n        return t(\"editor.history.operation.Added\", {\n          operationTargetName: \"globalData\",\n        })\n      }\n      return t(\"editor.history.operation.Added\", {\n        operationTargetName,\n      })\n    },\n    [t],\n  )\n\n  const getOperationDesc = useCallback(\n    (history: ModifyHistory) => {\n      const {\n        operation,\n        operationTargetName,\n        operationBroadcastType,\n        operationBroadcastPayload,\n        operationTargetModifiedAt,\n      } = history\n\n      switch (operation) {\n        case Signal.UPDATE_STATE:\n          const operationKey = getKeyFromBroadcast(operationBroadcastType)\n          if (operationKey) {\n            return t(operationKey, { operationTargetName })\n          } else {\n            return getDescFromBroadcast(\n              operationBroadcastType,\n              operationBroadcastPayload,\n              operationTargetName,\n            )\n          }\n        case Signal.CREATE_STATE:\n          return t(\"editor.history.operation.Created\", { operationTargetName })\n        case Signal.DELETE_STATE:\n          return t(\"editor.history.operation.Deleted\", { operationTargetName })\n        case Signal.MOVE_STATE:\n          return t(\"editor.history.operation.Moved\", { operationTargetName })\n        case Signal.RECOVER_APP_SNAPSHOT:\n          return t(\"editor.history.operation.Restored\", {\n            versionName: formatDate(operationTargetModifiedAt),\n          })\n      }\n    },\n    [t, getDescFromBroadcast],\n  )\n\n  const handleRecoverSnapShot = useCallback(async () => {\n    setLoading(true)\n    try {\n      await recoverSnapShot(snapshot.appID, snapshot.snapshotID)\n      await recoverSnapShotWS(snapshot.appID)\n      message.success({ content: t(\"editor.history.message.suc.restore\") })\n      window.location.href = `${getILLABuilderURL(\n        window.customDomain,\n      )}/${teamIdentifier}/app/${snapshot.appID}`\n    } catch (error) {\n      if (isILLAAPiError(error)) {\n        message.error({ content: t(\"editor.history.message.fail.restore\") })\n      } else {\n        message.error({ content: t(\"network_error\") })\n      }\n    } finally {\n      setLoading(false)\n    }\n  }, [snapshot.appID, snapshot.snapshotID, teamIdentifier, message, t])\n\n  const handleClickItem = useCallback(() => {\n    onChangeCurrentID(snapshot.snapshotID)\n  }, [onChangeCurrentID, snapshot.snapshotID])\n\n  return (\n    <div css={timelineStyle}>\n      <div css={leftWrapperStyle}>\n        <div css={badgeDotStyle}>\n          <div css={applyDotStyle(selected)} />\n        </div>\n        {!last && <div css={lineStyle} />}\n      </div>\n      <div css={textStyle}>\n        {snapshot.targetVersion === 0 ? (\n          <div css={applyTimeStyle(selected)} onClick={handleClickItem}>\n            {t(\"editor.history.history_list.current\")}\n          </div>\n        ) : (\n          <>\n            <div css={itemHeaderStyle}>\n              <div css={applyTimeStyle(selected)} onClick={handleClickItem}>\n                {formatDate(snapshot.createdAt)}\n              </div>\n              {snapshot.snapshotTriggerMode === SnapshotTriggerMode.MANUAL && (\n                <div css={manualStyle}>\n                  <SaveIcon />\n                  {t(\"editor.history.history_list.manual\")}\n                </div>\n              )}\n            </div>\n            {snapshot.modifyHistory.length > 0 && (\n              <div css={contentStyle}>\n                {snapshot.modifyHistory.map((modify) => {\n                  const desc = getOperationDesc(modify)\n                  return (\n                    <div key={modify.modifiedAt} css={modifyContentStyle}>\n                      <div css={editorInfoStyle}>\n                        <Avatar\n                          key={modify.modifiedBy.userID}\n                          css={avatarStyle}\n                          avatarUrl={modify.modifiedBy.avatar}\n                          name={modify.modifiedBy.nickname}\n                          id={modify.modifiedBy.userID}\n                        />\n                        <div css={nameStyle}>{modify.modifiedBy.nickname}</div>\n                      </div>\n                      <div css={descStyle}>{desc}</div>\n                    </div>\n                  )\n                })}\n              </div>\n            )}\n            {selected && (\n              <Button\n                colorScheme=\"blackAlpha\"\n                loading={loading}\n                onClick={handleRecoverSnapShot}\n              >\n                {t(\"editor.history.restore\")}\n              </Button>\n            )}\n          </>\n        )}\n      </div>\n    </div>\n  )\n}\n\nSnapShotItem.displayName = \"SnapShotItem\"\n"
  },
  {
    "path": "apps/builder/src/page/History/components/SnapShotItem/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const leftWrapperStyle = css`\n  position: relative;\n  width: 16px;\n  display: flex;\n  justify-content: center;\n`\nexport const badgeDotStyle = css`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  height: 24px;\n  position: relative;\n`\n\nexport const applyDotStyle = (selected?: boolean) => {\n  return css`\n    width: 6px;\n    height: 6px;\n    background-color: ${selected\n      ? getColor(\"techPurple\", \"03\")\n      : getColor(\"grayBlue\", \"02\")};\n    border-radius: 50%;\n  `\n}\n\nconst textEllipsisStyle = css`\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n`\n\nexport const lineStyle = css`\n  position: absolute;\n  transform: translateX(-50%);\n  left: 50%;\n  top: 24px;\n  width: 1px;\n  height: calc(100% - 24px);\n  background: ${getColor(\"grayBlue\", \"08\")};\n`\n\nexport const textStyle = css`\n  flex-direction: column;\n  justify-content: start;\n  align-items: start;\n  gap: 16px;\n  padding-bottom: 24px;\n  display: flex;\n  flex-grow: 1;\n  width: 263px;\n`\n\nexport const timelineStyle = css`\n  justify-content: start;\n  align-items: stretch;\n  gap: 8px;\n  display: flex;\n`\n\nexport const itemHeaderStyle = css`\n  display: flex;\n  justify-content: space-between;\n  width: 100%;\n`\n\nexport const applyTimeStyle = (selected?: boolean) => {\n  return css`\n    color: ${selected\n      ? getColor(\"techPurple\", \"03\")\n      : getColor(\"grayBlue\", \"02\")};\n    font-size: 16px;\n    font-weight: 500;\n    line-height: 24px;\n    cursor: pointer;\n  `\n}\n\nexport const manualStyle = css`\n  display: flex;\n  gap: 4px;\n  align-items: center;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 12px;\n  font-weight: 400;\n  line-height: 20px;\n`\nexport const contentStyle = css`\n  flex-direction: column;\n  justify-content: start;\n  align-items: start;\n  gap: 16px;\n  display: flex;\n`\n\nexport const modifyContentStyle = css`\n  flex-direction: column;\n  justify-content: center;\n  align-items: start;\n  gap: 8px;\n  display: flex;\n`\n\nexport const editorInfoStyle = css`\n  justify-content: start;\n  align-items: center;\n  gap: 8px;\n  display: flex;\n`\n\nexport const avatarStyle = css`\n  width: 24px;\n  height: 24px;\n  border-radius: 50%;\n  flex-shrink: 0;\n`\n\nexport const nameStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n  max-width: 230px;\n  ${textEllipsisStyle};\n`\n\nexport const descStyle = css`\n  color: ${getColor(\"grayBlue\", \"03\")};\n  font-size: 12px;\n  font-weight: 400;\n  line-height: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/History/components/SnapShotList/index.tsx",
    "content": "import { FC, HTMLAttributes, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Divider } from \"@illa-design/react\"\nimport { Signal } from \"@/api/ws/ILLA_PROTO\"\nimport { ActionArea } from \"@/page/History/components/ActionArea\"\nimport { SnapShotItem } from \"@/page/History/components/SnapShotItem\"\nimport {\n  contentContainerStyle,\n  headerContainerStyle,\n  snapShotListWrapperStyle,\n} from \"@/page/History/components/SnapShotList/style\"\nimport {\n  getCurrentAppSnapshotID,\n  getCurrentAppSnapshotList,\n  getSnapshotListHasMore,\n} from \"@/redux/currentAppHistory/currentAppHistorySelector\"\n\ninterface SnapShotListProps extends HTMLAttributes<HTMLDivElement> {\n  onChangeCurrentID: (snapshotID: string) => void\n}\n\nconst validOperations = [\n  Signal.CREATE_STATE,\n  Signal.DELETE_STATE,\n  Signal.UPDATE_STATE,\n  Signal.MOVE_STATE,\n  Signal.RECOVER_APP_SNAPSHOT,\n]\n\nexport const SnapShotList: FC<SnapShotListProps> = (props) => {\n  const { className, onChangeCurrentID, ...rest } = props\n  const snapshotList = useSelector(getCurrentAppSnapshotList)\n  const hasMore = useSelector(getSnapshotListHasMore)\n  const currentSnapshotID = useSelector(getCurrentAppSnapshotID)\n\n  const filteredSnapshotList = useMemo(() => {\n    return snapshotList.map((snapshot) => {\n      const modifyHistory = snapshot.modifyHistory\n        .filter((history) => {\n          return validOperations.includes(history.operation)\n        })\n        .slice(0, 2)\n\n      return {\n        ...snapshot,\n        modifyHistory,\n      }\n    })\n  }, [snapshotList])\n\n  return (\n    <div css={snapShotListWrapperStyle} className={className} {...rest}>\n      <div css={headerContainerStyle}>Version History</div>\n      <Divider />\n      <div css={contentContainerStyle}>\n        {filteredSnapshotList.map((snapshot, index) => {\n          return (\n            <SnapShotItem\n              key={snapshot.snapshotID}\n              snapshot={snapshot}\n              last={!hasMore && filteredSnapshotList.length - 1 === index}\n              selected={currentSnapshotID === snapshot.snapshotID}\n              onChangeCurrentID={onChangeCurrentID}\n            />\n          )\n        })}\n        {hasMore && <ActionArea />}\n      </div>\n    </div>\n  )\n}\n\nSnapShotList.displayName = \"SnapShotList\"\n"
  },
  {
    "path": "apps/builder/src/page/History/components/SnapShotList/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const snapShotListWrapperStyle = css`\n  overflow: hidden;\n`\nexport const headerContainerStyle = css`\n  width: 100%;\n  padding: 12px 16px;\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n`\n\nexport const contentContainerStyle = css`\n  padding: 24px 16px 64px;\n  margin-bottom: 24px;\n  overflow: scroll;\n  height: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/page/History/index.tsx",
    "content": "import { getCurrentTeamInfo, getPlanUtils } from \"@illa-public/user-data\"\nimport { canManage } from \"@illa-public/user-role-utils\"\nimport { ACTION_MANAGE, ATTRIBUTE_GROUP } from \"@illa-public/user-role-utils\"\nimport { Unsubscribe } from \"@reduxjs/toolkit\"\nimport { FC, useCallback, useEffect, useRef, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { Loading, TriggerProvider, useMessage } from \"@illa-design/react\"\nimport { updateCurrentAppInfo } from \"@/hooks/useInitApp\"\nimport { CanvasPanel } from \"@/page/App/Module/CanvasPanel\"\nimport {\n  centerPanelStyle,\n  contentStyle,\n  editorContainerStyle,\n  loadingStyle,\n  middlePanelStyle,\n  rightPanelStyle,\n} from \"@/page/App/style\"\nimport { HistoryNavBar } from \"@/page/History/components/HistoryNavBar\"\nimport { SnapShotList } from \"@/page/History/components/SnapShotList\"\nimport { setupConfigListeners } from \"@/redux/config/configListener\"\nimport { setupActionListeners } from \"@/redux/currentApp/action/actionListener\"\nimport { appInfoActions } from \"@/redux/currentApp/appInfo/appInfoSlice\"\nimport { DashboardAppInitialState } from \"@/redux/currentApp/appInfo/appInfoState\"\nimport { setupComponentsListeners } from \"@/redux/currentApp/components/componentsListener\"\nimport { setupExecutionListeners } from \"@/redux/currentApp/executionTree/executionListener\"\nimport { setupLayoutInfoListeners } from \"@/redux/currentApp/layoutInfo/layoutInfoListener\"\nimport { getCurrentAppSnapshotID } from \"@/redux/currentAppHistory/currentAppHistorySelector\"\nimport { currentAppHistoryActions } from \"@/redux/currentAppHistory/currentAppHistorySlice\"\nimport { fetchSnapShot } from \"@/services/history\"\nimport { startAppListening } from \"@/store\"\n\nexport const History: FC = () => {\n  const dispatch = useDispatch()\n  const message = useMessage()\n  const { appId } = useParams()\n  const { t } = useTranslation()\n\n  const teamInfo = useSelector(getCurrentTeamInfo)\n  const currentSnapshotID = useSelector(getCurrentAppSnapshotID)\n  const currentUserRole = teamInfo?.myRole\n  const uid = teamInfo?.uid ?? \"\"\n  const teamID = teamInfo?.id ?? \"\"\n\n  const [contentLoading, setContentLoading] = useState(false)\n  const preSnapshotID = useRef<string>()\n\n  // check if user can manage the app\n  if (currentUserRole) {\n    const canEditApp = canManage(\n      currentUserRole,\n      ATTRIBUTE_GROUP.APP,\n      getPlanUtils(teamInfo),\n      ACTION_MANAGE.EDIT_APP,\n    )\n    if (!canEditApp) {\n      throw new Error(\"You don't have permission to edit this app\")\n    }\n  }\n\n  useEffect(() => {\n    const subscriptions: Unsubscribe[] = [\n      setupExecutionListeners(startAppListening),\n      setupLayoutInfoListeners(startAppListening),\n      setupComponentsListeners(startAppListening),\n      setupActionListeners(startAppListening),\n      setupConfigListeners(startAppListening),\n    ]\n    return () => subscriptions.forEach((unsubscribe) => unsubscribe())\n  }, [])\n\n  const onChangeCurrentID = useCallback(\n    (snapshotID: string) => {\n      preSnapshotID.current = currentSnapshotID\n      dispatch(\n        currentAppHistoryActions.updateCurrentSnapshotIDReducer(snapshotID),\n      )\n    },\n    [currentSnapshotID, dispatch],\n  )\n\n  useEffect(() => {\n    const controller = new AbortController()\n    if (currentSnapshotID && appId) {\n      setContentLoading(true)\n      fetchSnapShot(appId, currentSnapshotID, controller.signal)\n        .then((res) => {\n          preSnapshotID.current = currentSnapshotID\n          updateCurrentAppInfo(res.data, \"preview\", appId, teamID, uid)\n        })\n        .catch(() => {\n          message.error({\n            content: t(\"editor.history.message.fail.preview\"),\n          })\n          preSnapshotID.current &&\n            dispatch(\n              currentAppHistoryActions.updateCurrentSnapshotIDReducer(\n                preSnapshotID.current,\n              ),\n            )\n        })\n        .finally(() => {\n          setContentLoading(false)\n        })\n    }\n    return () => {\n      controller.abort()\n      dispatch(appInfoActions.updateAppInfoReducer(DashboardAppInitialState))\n    }\n  }, [t, dispatch, message, appId, currentSnapshotID, teamID, uid])\n\n  return (\n    <div css={editorContainerStyle}>\n      <HistoryNavBar />\n      <div css={contentStyle}>\n        <div css={middlePanelStyle}>\n          {contentLoading ? (\n            <div css={loadingStyle}>\n              <Loading colorScheme=\"techPurple\" />\n            </div>\n          ) : (\n            <TriggerProvider renderInBody zIndex={10}>\n              <CanvasPanel css={centerPanelStyle} />\n            </TriggerProvider>\n          )}\n        </div>\n        <TriggerProvider renderInBody zIndex={10}>\n          <SnapShotList\n            onChangeCurrentID={onChangeCurrentID}\n            css={rightPanelStyle}\n          />\n        </TriggerProvider>\n      </div>\n    </div>\n  )\n}\n\nexport default History\n\nHistory.displayName = \"History\"\n"
  },
  {
    "path": "apps/builder/src/page/Resource/Create/index.tsx",
    "content": "import { ResourceType } from \"@illa-public/public-types\"\nimport { FC } from \"react\"\nimport { useParams } from \"react-router-dom\"\nimport { ResourceCreateOrEditPanel } from \"../CreateOrEdit\"\n\nexport const ResourceCreate: FC = () => {\n  const { resourceType } = useParams()\n\n  return (\n    <ResourceCreateOrEditPanel resourceType={resourceType as ResourceType} />\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/Resource/CreateOrEdit/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE, // ILLA_MIXPANEL_EVENT_TYPE,\n  MixpanelTrackProvider,\n} from \"@illa-public/mixpanel-utils\"\nimport {\n  ResourceCreatePanel,\n  ResourceGeneratorProvider,\n} from \"@illa-public/resource-generator\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { useMessage } from \"@illa-design/react\"\n// import { useTranslation } from \"react-i18next\"\n// import { useMessage } from \"@illa-design/react\"\nimport { getAllResources } from \"@/redux/resource/resourceSelector\"\nimport { track } from \"@/utils/mixpanelHelper\"\nimport { ResourceCreateOrEditPanelProps } from \"./interface\"\n\nexport const ResourceCreateOrEditPanel: FC<ResourceCreateOrEditPanelProps> = (\n  props,\n) => {\n  const { resourceID, resourceType } = props\n\n  const message = useMessage()\n  const { t } = useTranslation()\n  const resourceList = useSelector(getAllResources)\n\n  const handleOnFinished = () => {\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.CLICK,\n      ILLA_MIXPANEL_BUILDER_PAGE_NAME.RESOURCE_EDIT,\n      {\n        element: \"resource_configure_save\",\n      },\n    )\n    message.info({\n      content: t(\"dashboard.message.save_resource\"),\n    })\n    setTimeout(() => {\n      window.close()\n    }, 3000)\n  }\n\n  const handleClickBack = () => {\n    window.close()\n  }\n\n  return (\n    <MixpanelTrackProvider\n      basicTrack={track}\n      pageName={ILLA_MIXPANEL_BUILDER_PAGE_NAME.RESOURCE_EDIT}\n    >\n      <ResourceGeneratorProvider\n        allResource={resourceList}\n        createOrUpdateResourceCallback={handleOnFinished}\n      >\n        <ResourceCreatePanel\n          resourceID={resourceID}\n          resourceType={resourceType}\n          handleOnClickBack={handleClickBack}\n        />\n      </ResourceGeneratorProvider>\n    </MixpanelTrackProvider>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/Resource/CreateOrEdit/interface.ts",
    "content": "import { ResourceType } from \"@illa-public/public-types\"\n\nexport interface ResourceCreateOrEditPanelProps {\n  resourceType: ResourceType\n  resourceID?: string\n}\n"
  },
  {
    "path": "apps/builder/src/page/Resource/CreateOrEdit/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  display: flex;\n  justify-content: center;\n  gap: 32px;\n  width: 1032px;\n`\n\nexport const outerContainerStyle = css`\n  display: flex;\n  width: 100%;\n  justify-content: center;\n  overflow: hidden;\n  padding-top: 16px;\n`\n\nexport const innerContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n`\n"
  },
  {
    "path": "apps/builder/src/page/Resource/Edit/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Navigate, useParams } from \"react-router-dom\"\nimport { getAllResources } from \"@/redux/resource/resourceSelector\"\nimport { ResourceCreateOrEditPanel } from \"../CreateOrEdit\"\n\nexport const ResourceEdit: FC = () => {\n  const { resourceID } = useParams()\n\n  const resourceList = useSelector(getAllResources)\n\n  const resource = resourceList.find((r) => r.resourceID === resourceID)\n\n  if (!resource) {\n    return <Navigate to=\"/404\" />\n  }\n\n  const resourceType = resource.resourceType\n\n  return (\n    <ResourceCreateOrEditPanel\n      resourceType={resourceType}\n      resourceID={resourceID}\n    />\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/Resource/layout/index.tsx",
    "content": "import { getILLACloudURL } from \"@illa-public/utils\"\nimport { FC } from \"react\"\nimport { Link, Outlet } from \"react-router-dom\"\nimport Logo from \"@/assets/illa-logo.svg?react\"\nimport {\n  asideContainerStyle,\n  headerContainerStyle,\n  iconStyle,\n  resourceLayoutContainerStyle,\n} from \"./style\"\n\nexport const ResourceLayout: FC = () => {\n  return (\n    <div css={resourceLayoutContainerStyle}>\n      <header css={headerContainerStyle}>\n        <Link to={getILLACloudURL(window.customDomain)}>\n          <Logo css={iconStyle} />\n        </Link>\n      </header>\n      <aside css={asideContainerStyle}>\n        <Outlet />\n      </aside>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/Resource/layout/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const resourceLayoutContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  height: 100%;\n  width: 100%;\n`\n\nexport const headerContainerStyle = css`\n  display: flex;\n  width: 100%;\n  padding: 28px 0px 28px 40px;\n`\n\nexport const iconStyle = css`\n  width: 40px;\n  height: 28px;\n`\n\nexport const asideContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 8px;\n  overflow: hidden;\n`\n"
  },
  {
    "path": "apps/builder/src/page/Status/403/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_EVENT_TYPE,\n  ILLA_MIXPANEL_PUBLIC_PAGE_NAME,\n} from \"@illa-public/mixpanel-utils\"\nimport { FC, useEffect } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useNavigate } from \"react-router-dom\"\nimport { Button, Result403Icon } from \"@illa-design/react\"\nimport { ErrorPage } from \"@/page/Status/errorPage\"\nimport { buttonStyle, iconStyle } from \"@/page/Status/style\"\nimport { track } from \"@/utils/mixpanelHelper\"\n\nexport const Page403: FC = () => {\n  const navigate = useNavigate()\n  const { t } = useTranslation()\n  useEffect(() => {\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.VISIT,\n      ILLA_MIXPANEL_PUBLIC_PAGE_NAME.ERROR_PAGE,\n      {\n        parameter3: \"403\",\n      },\n    )\n  }, [])\n  return (\n    <ErrorPage\n      title=\"403\"\n      des={t(\"status.403.des\")}\n      img={<Result403Icon css={iconStyle} />}\n    >\n      <div css={buttonStyle}>\n        <Button onClick={() => navigate(\"/\")}>{t(\"status.back\")}</Button>\n      </div>\n    </ErrorPage>\n  )\n}\n\nexport default Page403\n"
  },
  {
    "path": "apps/builder/src/page/Status/404/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_EVENT_TYPE,\n  ILLA_MIXPANEL_PUBLIC_PAGE_NAME,\n} from \"@illa-public/mixpanel-utils\"\nimport { FC, useEffect } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useNavigate } from \"react-router-dom\"\nimport { Button, Result404Icon } from \"@illa-design/react\"\nimport { ErrorPage } from \"@/page/Status/errorPage\"\nimport { buttonStyle, iconStyle } from \"@/page/Status/style\"\nimport { track } from \"@/utils/mixpanelHelper\"\n\nexport const Page404: FC = () => {\n  const navigate = useNavigate()\n  const { t } = useTranslation()\n  useEffect(() => {\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.VISIT,\n      ILLA_MIXPANEL_PUBLIC_PAGE_NAME.ERROR_PAGE,\n      {\n        parameter3: \"404\",\n      },\n    )\n  }, [])\n  return (\n    <ErrorPage\n      title=\"404\"\n      des={t(\"status.404.des\")}\n      img={<Result404Icon css={iconStyle} />}\n    >\n      <div css={buttonStyle}>\n        <Button onClick={() => navigate(0)} colorScheme={\"gray\"}>\n          {t(\"status.404.again\")}\n        </Button>\n        <Button onClick={() => navigate(\"/\")}>{t(\"status.back\")}</Button>\n      </div>\n    </ErrorPage>\n  )\n}\n\nexport default Page404\n"
  },
  {
    "path": "apps/builder/src/page/Status/500/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_EVENT_TYPE,\n  ILLA_MIXPANEL_PUBLIC_PAGE_NAME,\n} from \"@illa-public/mixpanel-utils\"\nimport { FC, useEffect } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useNavigate } from \"react-router-dom\"\nimport { Button, Result500Icon } from \"@illa-design/react\"\nimport { ErrorPage } from \"@/page/Status/errorPage\"\nimport { buttonStyle, iconStyle } from \"@/page/Status/style\"\nimport { track } from \"@/utils/mixpanelHelper\"\n\nexport const Page500: FC = () => {\n  const navigate = useNavigate()\n  const { t } = useTranslation()\n  useEffect(() => {\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.VISIT,\n      ILLA_MIXPANEL_PUBLIC_PAGE_NAME.ERROR_PAGE,\n      {\n        parameter3: \"500\",\n      },\n    )\n  }, [])\n  return (\n    <ErrorPage\n      title=\"500\"\n      des={t(\"status.500.des\")}\n      img={<Result500Icon css={iconStyle} />}\n    >\n      <div css={buttonStyle}>\n        <Button onClick={() => navigate(\"/\")}>{t(\"status.back\")}</Button>\n      </div>\n    </ErrorPage>\n  )\n}\n\nexport default Page500\n"
  },
  {
    "path": "apps/builder/src/page/Status/MobileFobidden/index.tsx",
    "content": "import {\n  ILLA_MIXPANEL_EVENT_TYPE,\n  ILLA_MIXPANEL_PUBLIC_PAGE_NAME,\n} from \"@illa-public/mixpanel-utils\"\nimport { FC, useEffect } from \"react\"\nimport { Helmet } from \"react-helmet-async\"\nimport { useTranslation } from \"react-i18next\"\nimport LaptopIcon from \"@/assets/laptop.svg?react\"\nimport {\n  contentStyle,\n  contentWrapperStyle,\n  iconWrapperStyle,\n  wrapperStyle,\n} from \"@/page/Status/MobileFobidden/style\"\nimport { track } from \"@/utils/mixpanelHelper\"\n\nexport const MobileForbidden: FC = () => {\n  const { t } = useTranslation()\n  useEffect(() => {\n    track(\n      ILLA_MIXPANEL_EVENT_TYPE.VISIT,\n      ILLA_MIXPANEL_PUBLIC_PAGE_NAME.MOBILE_FORBIDDEN,\n    )\n  }, [])\n  return (\n    <>\n      <Helmet>\n        <title>{t(\"status.mobile_forbidden\")}</title>\n      </Helmet>\n      <div css={wrapperStyle}>\n        <div css={contentWrapperStyle}>\n          <div css={iconWrapperStyle}>\n            <LaptopIcon />\n          </div>\n          <span css={contentStyle}>{t(\"status.mobile_forbidden\")}</span>\n        </div>\n      </div>\n    </>\n  )\n}\n\nMobileForbidden.displayName = \"MobileForbidden\"\n\nexport default MobileForbidden\n"
  },
  {
    "path": "apps/builder/src/page/Status/MobileFobidden/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const wrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n`\n\nexport const contentWrapperStyle = css`\n  width: 100%;\n  padding: 35px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 20px;\n`\n\nexport const iconWrapperStyle = css`\n  width: 60px;\n  height: 60px;\n`\n\nexport const contentStyle = css`\n  font-weight: 500;\n  font-size: 16px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-family: \"Inter\", serif;\n  font-style: normal;\n`\n"
  },
  {
    "path": "apps/builder/src/page/Status/errorPage.tsx",
    "content": "import { FC } from \"react\"\nimport { Helmet } from \"react-helmet-async\"\nimport { ErrorPageProps } from \"@/page/Status/interface\"\nimport { errorPageStyle } from \"@/page/Status/style\"\n\nexport const ErrorPage: FC<ErrorPageProps> = (props) => {\n  const { title, des, img, children } = props\n  return (\n    <>\n      <Helmet>\n        <title>{title}</title>\n      </Helmet>\n      <div css={errorPageStyle}>\n        {img}\n        <span> {title} </span>\n        <span>{des}</span>\n        {children}\n      </div>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/page/Status/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface ErrorPageProps {\n  title: string\n  des: string\n  img: ReactNode\n  children: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/page/Status/style.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const errorPageStyle = css`\n  width: 100%;\n  height: 100vh;\n  display: flex;\n  flex-direction: column;\n  justify-content: start;\n  align-items: center;\n  padding-top: 30vh;\n  font-size: 14px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  font-weight: bold;\n  line-height: 22px;\n  span + span {\n    font-weight: normal;\n    color: ${globalColor(`--${illaPrefix}-grayBlue-03`)};\n  }\n`\n\nexport const iconStyle = css`\n  height: 96px;\n  width: 96px;\n  border-radius: 50px;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  margin-bottom: 24px;\n`\n\nexport const buttonStyle = css`\n  margin-top: 24px;\n  display: flex;\n  gap: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/page/Template/GuideApp.tsx",
    "content": "import { getCurrentTeamInfo, getPlanUtils } from \"@illa-public/user-data\"\nimport {\n  ACTION_MANAGE,\n  ATTRIBUTE_GROUP,\n  canManage,\n} from \"@illa-public/user-role-utils\"\nimport { Unsubscribe } from \"@reduxjs/toolkit\"\nimport { FC, useEffect, useRef } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { TriggerProvider } from \"@illa-design/react\"\nimport { Guide } from \"@/components/Guide\"\nimport { useInitGuideApp } from \"@/hooks/useInitGuideApp\"\nimport { ActionEditor } from \"@/page/App/Module/ActionEditor\"\nimport { CanvasPanel } from \"@/page/App/Module/CanvasPanel\"\nimport ComponentsManager from \"@/page/App/Module/ComponentManager\"\nimport { DataWorkspace } from \"@/page/App/Module/DataWorkspace\"\nimport { PageNavBar } from \"@/page/App/Module/PageNavBar\"\nimport { AppLoading } from \"@/page/App/components/AppLoading\"\nimport { Debugger } from \"@/page/App/components/Debugger\"\nimport {\n  bottomPanelStyle,\n  centerPanelStyle,\n  contentStyle,\n  editorContainerStyle,\n  middlePanelStyle,\n  navbarStyle,\n} from \"@/page/App/style\"\nimport { setupConfigListeners } from \"@/redux/config/configListener\"\nimport {\n  isOpenBottomPanel,\n  isOpenDebugger,\n  isOpenLeftPanel,\n  isOpenRightPanel,\n} from \"@/redux/config/configSelector\"\nimport { setupActionListeners } from \"@/redux/currentApp/action/actionListener\"\nimport { setupComponentsListeners } from \"@/redux/currentApp/components/componentsListener\"\nimport { setupExecutionListeners } from \"@/redux/currentApp/executionTree/executionListener\"\nimport { setupLayoutInfoListeners } from \"@/redux/currentApp/layoutInfo/layoutInfoListener\"\nimport { getGuideStatus } from \"@/redux/guide/guideSelector\"\nimport { startAppListening } from \"@/store\"\nimport { MediaSourceLoadProvider } from \"@/utils/mediaSourceLoad\"\nimport { Shortcut } from \"@/utils/shortcut\"\nimport { useResize } from \"../App/components/ScaleSquare/components/ResizingAndDragContainer/ResizeHandler/hooks\"\n\nconst GuideApp: FC = () => {\n  const teamInfo = useSelector(getCurrentTeamInfo)\n\n  const canvasRef = useRef<HTMLDivElement>(null)\n\n  const currentUserRole = teamInfo?.myRole\n\n  // check if user can manage the app\n  if (currentUserRole) {\n    const canEditApp = canManage(\n      currentUserRole,\n      ATTRIBUTE_GROUP.APP,\n      getPlanUtils(teamInfo),\n      ACTION_MANAGE.EDIT_APP,\n    )\n    if (!canEditApp) {\n      throw new Error(\"You don't have permission to edit this app\")\n    }\n  }\n\n  useEffect(() => {\n    const subscriptions: Unsubscribe[] = [\n      setupExecutionListeners(startAppListening),\n      setupComponentsListeners(startAppListening),\n      setupLayoutInfoListeners(startAppListening),\n      setupActionListeners(startAppListening),\n      setupConfigListeners(startAppListening),\n    ]\n    return () => subscriptions.forEach((unsubscribe) => unsubscribe())\n  }, [])\n\n  const showLeftPanel = useSelector(isOpenLeftPanel)\n  const showRightPanel = useSelector(isOpenRightPanel)\n  const showBottomPanel = useSelector(isOpenBottomPanel)\n  const showDebugger = useSelector(isOpenDebugger)\n\n  // init app\n  const { loadingState } = useInitGuideApp()\n  const isOpen = useSelector(getGuideStatus)\n  const [, resizeDropRef] = useResize()\n\n  return (\n    <div css={editorContainerStyle} ref={resizeDropRef}>\n      {loadingState && <AppLoading />}\n      {!loadingState && (\n        <Shortcut>\n          <MediaSourceLoadProvider>\n            {isOpen && <Guide canvasRef={canvasRef} />}\n            <TriggerProvider renderInBody zIndex={10}>\n              <PageNavBar css={navbarStyle} />\n            </TriggerProvider>\n            <div css={contentStyle}>\n              {showLeftPanel && <DataWorkspace />}\n              <div css={middlePanelStyle}>\n                <TriggerProvider renderInBody zIndex={10}>\n                  <CanvasPanel ref={canvasRef} css={centerPanelStyle} />\n                </TriggerProvider>\n                {showBottomPanel && !showDebugger ? <ActionEditor /> : null}\n                {showDebugger && <Debugger css={bottomPanelStyle} />}\n              </div>\n              {showRightPanel && (\n                <TriggerProvider renderInBody zIndex={10}>\n                  <ComponentsManager />\n                </TriggerProvider>\n              )}\n            </div>\n          </MediaSourceLoadProvider>\n        </Shortcut>\n      )}\n    </div>\n  )\n}\n\nexport default GuideApp\n\nGuideApp.displayName = \"GuideApp\"\n"
  },
  {
    "path": "apps/builder/src/redux/aiAgent/dashboardTeamAIAgentPayload.ts",
    "content": "import { Agent } from \"@illa-public/public-types\"\n\nexport interface AddTeamAIAgentPayload {\n  aiAgent: Agent\n}\n\nexport interface ModifyTeamAIAgentPayload {\n  aiAgentID: string\n  modifiedProps: Partial<Agent>\n}\n"
  },
  {
    "path": "apps/builder/src/redux/aiAgent/dashboardTeamAIAgentReducer.ts",
    "content": "import { Agent } from \"@illa-public/public-types\"\nimport { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport {\n  AddTeamAIAgentPayload,\n  ModifyTeamAIAgentPayload,\n} from \"./dashboardTeamAIAgentPayload\"\nimport { AIAgentState } from \"./dashboardTeamAIAgentState\"\n\nexport const updateTeamAIAgentListReducer: CaseReducer<\n  AIAgentState,\n  PayloadAction<Agent[]>\n> = (state, action) => {\n  state.list = action.payload\n}\n\nexport const addTeamAIAgentReducer: CaseReducer<\n  AIAgentState,\n  PayloadAction<AddTeamAIAgentPayload>\n> = (state, action) => {\n  let payload = action.payload\n  state.list = [payload.aiAgent, ...state.list]\n}\n\nexport const removeTeamAIAgentReducer: CaseReducer<\n  AIAgentState,\n  PayloadAction<string>\n> = (state, action) => {\n  let index = state.list.findIndex((element) => {\n    return element.aiAgentID == action.payload\n  })\n  if (index != -1) {\n    state.list.splice(index, 1)\n  }\n}\n\nexport const modifyTeamAIAgentReducer: CaseReducer<\n  AIAgentState,\n  PayloadAction<ModifyTeamAIAgentPayload>\n> = (state, action) => {\n  let index = state.list.findIndex((element) => {\n    return element.aiAgentID == action.payload.aiAgentID\n  })\n  if (index != -1) {\n    state.list[index] = {\n      ...state.list[index],\n      ...action.payload.modifiedProps,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/aiAgent/dashboardTeamAIAgentSelector.ts",
    "content": "import { Agent } from \"@illa-public/public-types\"\nimport { createSelector } from \"@reduxjs/toolkit\"\nimport { RootState } from \"@/store\"\n\nexport const getDashboardTeamAIAgentList = (state: RootState) => {\n  return state.aiAgent.list\n}\n\nexport const getAIAgentIDMapAgent = createSelector(\n  [getDashboardTeamAIAgentList],\n  (aiAgentList) => {\n    const aiAgentIDMapAgent: Record<string, Agent> = {}\n    aiAgentList.forEach((aiAgent) => {\n      aiAgentIDMapAgent[aiAgent.aiAgentID] = aiAgent\n    })\n    return aiAgentIDMapAgent\n  },\n)\n"
  },
  {
    "path": "apps/builder/src/redux/aiAgent/dashboardTeamAIAgentSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  addTeamAIAgentReducer,\n  modifyTeamAIAgentReducer,\n  removeTeamAIAgentReducer,\n  updateTeamAIAgentListReducer,\n} from \"./dashboardTeamAIAgentReducer\"\nimport { AgentInitial } from \"./dashboardTeamAIAgentState\"\n\nconst aiAgentSlice = createSlice({\n  name: \"aiAgent\",\n  initialState: AgentInitial,\n  reducers: {\n    updateTeamAIAgentListReducer,\n    addTeamAIAgentReducer,\n    removeTeamAIAgentReducer,\n    modifyTeamAIAgentReducer,\n  },\n})\n\nexport const aiAgentActions = aiAgentSlice.actions\nexport default aiAgentSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/aiAgent/dashboardTeamAIAgentState.ts",
    "content": "import { Agent } from \"@illa-public/public-types\"\n\nexport interface AIAgentState {\n  list: Agent[]\n}\n\nexport const AgentInitial: AIAgentState = {\n  list: [],\n}\n"
  },
  {
    "path": "apps/builder/src/redux/builderInfo/builderInfoReducer.ts",
    "content": "import { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport { BuilderInfo } from \"@/redux/builderInfo/builderInfoState\"\n\nexport const updateLanguageReducer: CaseReducer<\n  BuilderInfo,\n  PayloadAction<string>\n> = (state, action) => {\n  state = {\n    ...state,\n    language: action.payload,\n  }\n  return state\n}\n"
  },
  {
    "path": "apps/builder/src/redux/builderInfo/builderInfoSelector.ts",
    "content": "import { RootState } from \"@/store\"\n\nexport const getBuilderInfo = (state: RootState) => {\n  return state.builderInfo\n}\n\nexport const getLanguageValue = (state: RootState) => {\n  return state.builderInfo.language\n}\n"
  },
  {
    "path": "apps/builder/src/redux/builderInfo/builderInfoSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport { updateLanguageReducer } from \"@/redux/builderInfo/builderInfoReducer\"\nimport { BuilderInfoInitialState } from \"@/redux/builderInfo/builderInfoState\"\n\nconst builderInfoSlice = createSlice({\n  name: \"builderInfo\",\n  initialState: BuilderInfoInitialState,\n  reducers: {\n    updateLanguageReducer,\n  },\n})\n\nexport const builderInfoActions = builderInfoSlice.actions\nexport default builderInfoSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/builderInfo/builderInfoState.ts",
    "content": "export interface BuilderInfo {\n  version: string\n  language: string\n}\n\nexport const BuilderInfoInitialState: BuilderInfo = {\n  version: import.meta.env.ILLA_APP_VERSION,\n  language: \"English\",\n}\n"
  },
  {
    "path": "apps/builder/src/redux/config/configListener.ts",
    "content": "import { UnknownAction, Unsubscribe, isAnyOf } from \"@reduxjs/toolkit\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { AppListenerEffectAPI, AppStartListening } from \"@/store\"\nimport { searchParent } from \"@/utils/componentNode/search\"\nimport { updateCurrentAllComponentsAttachedUsers } from \"../currentApp/collaborators/collaboratorsHandlers\"\nimport { cursorActions } from \"../currentApp/cursor/cursorSlice\"\nimport { getWidgetExecutionResult } from \"../currentApp/executionTree/executionSelector\"\nimport { getClientWidgetLayoutInfo } from \"../currentApp/layoutInfo/layoutInfoSelector\"\n\nexport const handleUpdateSelectedComponentExecution = (\n  action: ReturnType<typeof configActions.updateSelectedComponent>,\n  listenerApi: AppListenerEffectAPI,\n) => {\n  const currentComponentsAttachedUsers =\n    listenerApi.getState().currentApp.collaborators.components\n  const widgetLayoutInfo = getClientWidgetLayoutInfo(listenerApi.getState())\n\n  const needExpandDisplayName = action.payload\n    .map((displayName) => {\n      return searchParent(displayName, widgetLayoutInfo)\n    })\n    .flat()\n  listenerApi.dispatch(\n    configActions.addExpandedWidgetReducer(needExpandDisplayName),\n  )\n  updateCurrentAllComponentsAttachedUsers(\n    action.payload,\n    currentComponentsAttachedUsers,\n  )\n}\n\nasync function handleChangeSelectedActionExecution(\n  action: ReturnType<typeof configActions.changeSelectedAction>,\n  listenerApi: AppListenerEffectAPI,\n) {\n  listenerApi.dispatch(configActions.updateCachedAction(action.payload))\n}\n\nconst getAllChildrenDisplayName = (\n  nodeDisplayName: string,\n  displayNameMapProps: Record<string, any>,\n): string[] => {\n  let result = [nodeDisplayName]\n  const node = displayNameMapProps[nodeDisplayName]\n  const children: string[] = node?.$childrenNode || []\n  if (children.length > 0) {\n    children.forEach((child) => {\n      result = [\n        ...result,\n        ...getAllChildrenDisplayName(child, displayNameMapProps),\n      ]\n    })\n  }\n  return result\n}\n\nconst batchUpdateComponentStatusInfoEffect = (\n  action: UnknownAction,\n  listenApi: AppListenerEffectAPI,\n) => {\n  if (\n    configActions.setDraggingNodeIDsReducer.match(action) ||\n    configActions.setResizingNodeIDsReducer.match(action)\n  ) {\n    const { payload } = action\n    let allChildrenDisplayName: string[] = []\n    const displayNameMapProps = getWidgetExecutionResult(listenApi.getState())\n    payload.forEach((displayName) => {\n      allChildrenDisplayName = [\n        ...allChildrenDisplayName,\n        ...getAllChildrenDisplayName(displayName, displayNameMapProps),\n      ]\n    })\n    listenApi.dispatch(\n      cursorActions.filterCursorReducer(allChildrenDisplayName),\n    )\n  }\n}\n\nexport function setupConfigListeners(\n  startListening: AppStartListening,\n): Unsubscribe {\n  const subscriptions = [\n    startListening({\n      actionCreator: configActions.changeSelectedAction,\n      effect: handleChangeSelectedActionExecution,\n    }),\n    startListening({\n      actionCreator: configActions.updateSelectedComponent,\n      effect: handleUpdateSelectedComponentExecution,\n    }),\n    startListening({\n      matcher: isAnyOf(\n        configActions.setDraggingNodeIDsReducer,\n        configActions.setResizingNodeIDsReducer,\n      ),\n      effect: batchUpdateComponentStatusInfoEffect,\n    }),\n  ]\n\n  return () => {\n    subscriptions.forEach((unsubscribe) => unsubscribe())\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/config/configPayload.ts",
    "content": "import {\n  ILLA_WEBSOCKET_CONTEXT,\n  ILLA_WEBSOCKET_STATUS,\n} from \"@/api/ws/interface\"\n\nexport interface UpdateCanvasShapePayload {\n  canvasWidth: number\n  canvasHeight: number\n}\n\nexport interface UpdateWSStatusPayload {\n  context: ILLA_WEBSOCKET_CONTEXT\n  wsStatus: ILLA_WEBSOCKET_STATUS\n}\n"
  },
  {
    "path": "apps/builder/src/redux/config/configReducer.ts",
    "content": "import {\n  INIT_ACTION_ADVANCED_CONFIG,\n  INIT_ACTION_MOCK_CONFIG,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionContent,\n  IAdvancedConfig,\n  IMockConfig,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport {\n  ConfigInitialState,\n  ConfigState,\n  IllaMode,\n} from \"@/redux/config/configState\"\nimport {\n  UpdateCanvasShapePayload,\n  UpdateWSStatusPayload,\n} from \"./configPayload\"\n\nexport const updateLeftPanel: CaseReducer<\n  ConfigState,\n  PayloadAction<boolean>\n> = (state, action) => {\n  state.openLeftPanel = action.payload\n}\n\nexport const updateIllaMode: CaseReducer<\n  ConfigState,\n  PayloadAction<IllaMode>\n> = (state, action) => {\n  state.mode = action.payload\n}\n\nexport const resetConfig: CaseReducer<ConfigState, PayloadAction> = () => {\n  return ConfigInitialState\n}\n\nexport const updateRightPanel: CaseReducer<\n  ConfigState,\n  PayloadAction<boolean>\n> = (state, action) => {\n  state.openRightPanel = action.payload\n}\n\nexport const updateBottomPanel: CaseReducer<\n  ConfigState,\n  PayloadAction<boolean>\n> = (state, action) => {\n  state.openBottomPanel = action.payload\n}\n\nexport const updateDebuggerVisible: CaseReducer<\n  ConfigState,\n  PayloadAction<boolean>\n> = (state, action) => {\n  state.openDebugger = action.payload\n}\n\nexport const updateSelectedComponent: CaseReducer<\n  ConfigState,\n  PayloadAction<string[]>\n> = (state, action) => {\n  state.selectedComponents = action.payload\n}\n\nexport const changeSelectedAction: CaseReducer<\n  ConfigState,\n  PayloadAction<ActionItem<ActionContent> | null>\n> = (state, action) => {\n  state.selectedAction = action.payload\n}\n\nexport const updateCachedAction: CaseReducer<\n  ConfigState,\n  PayloadAction<ActionItem<ActionContent> | null>\n> = (state, action) => {\n  state.cachedAction = action.payload\n}\n\nexport const updateCachedActionAdvancedConfigReducer: CaseReducer<\n  ConfigState,\n  PayloadAction<Partial<IAdvancedConfig>>\n> = (state, action) => {\n  const cachedAction = state.cachedAction\n  if (!cachedAction) return\n  if (!cachedAction.config) {\n    cachedAction.config = {\n      public: false,\n      advancedConfig: INIT_ACTION_ADVANCED_CONFIG,\n      mockConfig: INIT_ACTION_MOCK_CONFIG,\n    }\n  }\n  if (!cachedAction.config.advancedConfig) {\n    cachedAction.config.advancedConfig = INIT_ACTION_ADVANCED_CONFIG\n  }\n  cachedAction.config.advancedConfig = {\n    ...cachedAction.config.advancedConfig,\n    ...action.payload,\n  }\n  state.cachedAction = cachedAction\n}\n\nexport const updateCachedActionMockConfigReducer: CaseReducer<\n  ConfigState,\n  PayloadAction<Partial<IMockConfig>>\n> = (state, action) => {\n  const cachedAction = state.cachedAction\n  if (!cachedAction) return\n  if (!cachedAction.config) {\n    cachedAction.config = {\n      public: false,\n      advancedConfig: INIT_ACTION_ADVANCED_CONFIG,\n      mockConfig: INIT_ACTION_MOCK_CONFIG,\n    }\n  }\n  if (!cachedAction.config.mockConfig) {\n    cachedAction.config.mockConfig = INIT_ACTION_MOCK_CONFIG\n  }\n  cachedAction.config.mockConfig = {\n    ...cachedAction.config.mockConfig,\n    ...action.payload,\n  }\n  state.cachedAction = cachedAction\n}\n\nexport const updateShowDot: CaseReducer<ConfigState, PayloadAction<boolean>> = (\n  state,\n  action,\n) => {\n  state.showDot = action.payload\n}\n\nexport const plusScale: CaseReducer<ConfigState, PayloadAction<void>> = (\n  state,\n) => {\n  state.scale = state.scale + 10\n}\n\nexport const minusScale: CaseReducer<ConfigState, PayloadAction<void>> = (\n  state,\n) => {\n  state.scale = state.scale - 10\n}\n\nexport const clearSelectedComponent: CaseReducer<\n  ConfigState,\n  PayloadAction<void>\n> = (state) => {\n  state.selectedComponents = []\n}\n\nexport const setExpandedKey: CaseReducer<\n  ConfigState,\n  PayloadAction<string[]>\n> = (state, action) => {\n  state.expandedKeys = action.payload\n}\n\nexport const removeExpandedKey: CaseReducer<\n  ConfigState,\n  PayloadAction<string>\n> = (state, action) => {\n  const index = state.expandedKeys.findIndex((key) => key === action.payload)\n  index > -1 && state.expandedKeys.splice(index, 1)\n}\n\nexport const updateCanvasShapeReducer: CaseReducer<\n  ConfigState,\n  PayloadAction<UpdateCanvasShapePayload>\n> = (state, action) => {\n  const { canvasHeight, canvasWidth } = action.payload\n  state.canvasHeight = canvasHeight\n  state.canvasWidth = canvasWidth\n}\n\nexport const updateDevicesOnlineStatusReducer: CaseReducer<\n  ConfigState,\n  PayloadAction<boolean>\n> = (state, action) => {\n  state.isOnline = action.payload\n}\n\nexport const updateWSStatusReducer: CaseReducer<\n  ConfigState,\n  PayloadAction<UpdateWSStatusPayload>\n> = (state, action) => {\n  const { context, wsStatus } = action.payload\n  state.wsStatus[context] = wsStatus\n}\n\nexport const updateHoveredComponent: CaseReducer<\n  ConfigState,\n  PayloadAction<string[]>\n> = (state, action) => {\n  state.hoveredComponents = action.payload\n}\n\nexport const resetSelectedActionReducer: CaseReducer<\n  ConfigState,\n  PayloadAction<string>\n> = (state, action) => {\n  if (!state.selectedAction) return\n  const selectedActionDisplayName = state.selectedAction.displayName\n  const selectedActionID = state.selectedAction.actionID\n  if (selectedActionDisplayName === action.payload) {\n    state.selectedAction = null\n  }\n  if (!state.cachedAction) return\n  if (state.cachedAction.actionID === selectedActionID) {\n    state.cachedAction = null\n  }\n}\n\nexport const addExpandedWidgetReducer: CaseReducer<\n  ConfigState,\n  PayloadAction<string[]>\n> = (state, action) => {\n  action.payload.forEach((displayName) => {\n    state.expandedWidgets[displayName] = true\n  })\n}\n\nexport const removeExpandWidgetReducer: CaseReducer<\n  ConfigState,\n  PayloadAction<string[]>\n> = (state, action) => {\n  action.payload.forEach((displayName) => {\n    state.expandedWidgets[displayName] = false\n  })\n}\n\nexport const setDraggingNodeIDsReducer: CaseReducer<\n  ConfigState,\n  PayloadAction<string[]>\n> = (state, action) => {\n  state.draggingComponentIDs = action.payload\n}\n\nexport const setResizingNodeIDsReducer: CaseReducer<\n  ConfigState,\n  PayloadAction<string[]>\n> = (state, action) => {\n  state.resizingComponentIDs = action.payload\n}\n"
  },
  {
    "path": "apps/builder/src/redux/config/configSelector.ts",
    "content": "import { INIT_ACTION_ADVANCED_CONFIG } from \"@illa-public/public-configs\"\nimport { ACTION_RUN_TIME } from \"@illa-public/public-types\"\nimport { createSelector } from \"@reduxjs/toolkit\"\nimport { RootState } from \"@/store\"\n\nexport const getEditorConfig = (state: RootState) => {\n  return state.config\n}\n\nconst isEditMode = (state: RootState) => {\n  return state.config.mode === \"edit\" || state.config.mode === \"template-edit\"\n}\n\nexport const isOpenLeftPanel = (state: RootState) => {\n  return state.config.openLeftPanel && isEditMode(state)\n}\n\nexport const isOpenBottomPanel = (state: RootState) => {\n  return state.config.openBottomPanel && isEditMode(state)\n}\n\nexport const isOpenRightPanel = (state: RootState) => {\n  return state.config.openRightPanel && isEditMode(state)\n}\n\nexport const isOpenDebugger = (state: RootState) => {\n  return state.config.openDebugger && isEditMode(state)\n}\n\nexport const getPreviewEdgeWidth = (state: RootState) => {\n  return state.config.mode === \"edit\" ? 16 : 0\n}\n\nexport const getIllaMode = (state: RootState) => {\n  return state.config.mode\n}\n\nexport const isShowDot = createSelector(\n  [getEditorConfig, isEditMode],\n  (editorConfig, isEditMode) => {\n    return editorConfig.showDot && isEditMode\n  },\n)\n\nexport const getScale = (state: RootState) => {\n  return state.config.scale\n}\n\nexport const getSelectedComponentDisplayNames = createSelector(\n  [getEditorConfig],\n  (editorConfig) => {\n    return editorConfig.selectedComponents\n  },\n)\n\nexport const getSelectedAction = (state: RootState) => {\n  return state.config.selectedAction\n}\n\nexport const getCachedAction = (state: RootState) => {\n  return state.config.cachedAction\n}\n\nexport const isSelected = (state: RootState, displayName: string) => {\n  return (\n    state.config.selectedComponents.findIndex((value) => {\n      return value == displayName\n    }) != -1\n  )\n}\n\nexport const getExpandedKeys = (state: RootState) => {\n  return state.config.expandedKeys\n}\n\nexport const getCanvasShape = createSelector(\n  [getEditorConfig],\n  (editorConfig) => {\n    return {\n      canvasWidth: editorConfig.canvasWidth,\n      canvasHeight: editorConfig.canvasHeight,\n    }\n  },\n)\n\nexport const getIsOnline = (state: RootState) => {\n  return state.config.isOnline\n}\n\nexport const getIsILLAEditMode = (state: RootState) => {\n  return state.config.mode === \"edit\" || state.config.mode === \"template-edit\"\n}\n\nexport const getIsILLAGuideMode = (state: RootState) => {\n  return state.config.mode === \"template-edit\"\n}\n\nexport const getIsILLAPreviewMode = (state: RootState) => {\n  return state.config.mode === \"preview\"\n}\n\nexport const getIsILLAProductMode = (state: RootState) => {\n  return state.config.mode === \"production\"\n}\n\nexport const getIsLikeProductMode = createSelector(\n  [getEditorConfig],\n  (editorConfig) => {\n    return editorConfig.mode === \"preview\" || editorConfig.mode === \"production\"\n  },\n)\n\nexport const getWSStatus = (state: RootState) => {\n  return state.config.wsStatus\n}\n\nexport const getDashboardWSStatus = (state: RootState) => {\n  return state.config.wsStatus.DASHBOARD\n}\n\nexport const getAppWSStatus = (state: RootState) => {\n  return state.config.wsStatus.APP\n}\n\nexport const getAgentWSStatus = (state: RootState) => {\n  return state.config.wsStatus.AI_AGENT\n}\n\nexport const getHoveredComponents = createSelector(\n  [getEditorConfig],\n  (editorConfig) => {\n    return editorConfig.hoveredComponents\n  },\n)\n\nexport const getCachedActionAdvancedConfig = createSelector(\n  [getCachedAction],\n  (cachedAction) => {\n    if (\n      !cachedAction ||\n      !cachedAction?.config ||\n      !cachedAction?.config?.advancedConfig\n    ) {\n      const initAdvancedConfig = INIT_ACTION_ADVANCED_CONFIG\n      if (cachedAction?.triggerMode === \"automate\") {\n        initAdvancedConfig.runtime = ACTION_RUN_TIME.APP_LOADED\n      }\n      return initAdvancedConfig\n    }\n    return cachedAction.config.advancedConfig\n  },\n)\n\nexport const getExpandedWidgets = createSelector(\n  [getEditorConfig],\n  (config) => config.expandedWidgets,\n)\n"
  },
  {
    "path": "apps/builder/src/redux/config/configSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  addExpandedWidgetReducer,\n  changeSelectedAction,\n  clearSelectedComponent,\n  minusScale,\n  plusScale,\n  removeExpandWidgetReducer,\n  removeExpandedKey,\n  resetConfig,\n  resetSelectedActionReducer,\n  setDraggingNodeIDsReducer,\n  setExpandedKey,\n  setResizingNodeIDsReducer,\n  updateBottomPanel,\n  updateCachedAction,\n  updateCachedActionAdvancedConfigReducer,\n  updateCachedActionMockConfigReducer,\n  updateCanvasShapeReducer,\n  updateDebuggerVisible,\n  updateDevicesOnlineStatusReducer,\n  updateHoveredComponent,\n  updateIllaMode,\n  updateLeftPanel,\n  updateRightPanel,\n  updateSelectedComponent,\n  updateShowDot,\n  updateWSStatusReducer,\n} from \"@/redux/config/configReducer\"\nimport { ConfigInitialState } from \"@/redux/config/configState\"\n\nconst configSlice = createSlice({\n  name: \"config\",\n  initialState: ConfigInitialState,\n  reducers: {\n    resetConfig,\n    updateIllaMode,\n    updateLeftPanel,\n    updateRightPanel,\n    updateBottomPanel,\n    updateDebuggerVisible,\n    updateShowDot,\n    updateSelectedComponent,\n    clearSelectedComponent,\n    changeSelectedAction,\n    updateCachedAction,\n    updateCachedActionAdvancedConfigReducer,\n    updateCachedActionMockConfigReducer,\n    plusScale,\n    minusScale,\n    setExpandedKey,\n    removeExpandedKey,\n    updateCanvasShapeReducer,\n    updateDevicesOnlineStatusReducer,\n    updateWSStatusReducer,\n    updateHoveredComponent,\n    resetSelectedActionReducer,\n    addExpandedWidgetReducer,\n    removeExpandWidgetReducer,\n    setDraggingNodeIDsReducer,\n    setResizingNodeIDsReducer,\n  },\n})\n\nexport const configActions = configSlice.actions\nexport default configSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/config/configState.ts",
    "content": "import { ActionContent } from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport {\n  ILLA_WEBSOCKET_CONTEXT,\n  ILLA_WEBSOCKET_STATUS,\n} from \"@/api/ws/interface\"\n\nexport type IllaMode = \"preview\" | \"edit\" | \"production\" | \"template-edit\"\n\nexport interface ConfigState {\n  openLeftPanel: boolean\n  openBottomPanel: boolean\n  openRightPanel: boolean\n  openDebugger: boolean\n  showDot: boolean\n  scale: number\n  selectedComponents: string[]\n  selectedAction: ActionItem<ActionContent> | null\n  cachedAction: ActionItem<ActionContent> | null\n  expandedKeys: string[]\n  expandedWidgets: Record<string, boolean>\n  mode: IllaMode\n  canvasHeight: number\n  canvasWidth: number\n  isOnline: boolean\n  wsStatus: Record<ILLA_WEBSOCKET_CONTEXT, ILLA_WEBSOCKET_STATUS>\n  hoveredComponents: string[]\n  draggingComponentIDs: string[]\n  resizingComponentIDs: string[]\n}\n\nexport const ConfigInitialState: ConfigState = {\n  openLeftPanel: true,\n  mode: \"edit\",\n  openBottomPanel: true,\n  openRightPanel: true,\n  openDebugger: false,\n  scale: 100,\n  selectedComponents: [],\n  selectedAction: null,\n  cachedAction: null,\n  showDot: false,\n  expandedKeys: [],\n  canvasHeight: 1080,\n  canvasWidth: 1920,\n  isOnline: true,\n  hoveredComponents: [],\n  expandedWidgets: {},\n  wsStatus: {\n    [ILLA_WEBSOCKET_CONTEXT.DASHBOARD]: ILLA_WEBSOCKET_STATUS.INIT,\n    [ILLA_WEBSOCKET_CONTEXT.APP]: ILLA_WEBSOCKET_STATUS.INIT,\n    [ILLA_WEBSOCKET_CONTEXT.APP_BINARY]: ILLA_WEBSOCKET_STATUS.INIT,\n    [ILLA_WEBSOCKET_CONTEXT.AI_AGENT]: ILLA_WEBSOCKET_STATUS.INIT,\n  },\n  draggingComponentIDs: [],\n  resizingComponentIDs: [],\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/action/actionListener.ts",
    "content": "import { ActionContent, ActionItem } from \"@illa-public/public-types\"\nimport { UnknownAction, Unsubscribe, isAnyOf } from \"@reduxjs/toolkit\"\nimport {\n  getCachedAction,\n  getIsILLAGuideMode,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport { getActionExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { fetchBatchUpdateAction } from \"@/services/action\"\nimport { AppListenerEffectAPI, AppStartListening } from \"@/store\"\nimport { registerActionPeriod } from \"@/utils/action/runAction\"\nimport { mixedChangeDisplayNameHelper } from \"@/utils/changeDisplayNameHelper\"\nimport { UpdateActionSlicePropsPayload } from \"./actionState\"\n\nasync function handleAddActionItemEffect(\n  action: ReturnType<typeof actionActions.addActionItemReducer>,\n  listenerApi: AppListenerEffectAPI,\n) {\n  listenerApi.dispatch(configActions.changeSelectedAction(action.payload))\n}\n\nasync function handleUpdateActionItem(\n  action: ReturnType<typeof actionActions.updateActionItemReducer>,\n  listenerApi: AppListenerEffectAPI,\n) {\n  if (\n    action.payload.displayName ===\n    listenerApi.getState().config.selectedAction?.displayName\n  ) {\n    listenerApi.dispatch(configActions.changeSelectedAction(action.payload))\n  }\n\n  const displayName = action.payload.displayName\n\n  const actionExecutionResult = getActionExecutionResult(listenerApi.getState())\n  const currentAction = actionExecutionResult[displayName]\n  if (\n    currentAction &&\n    currentAction?.config?.advancedConfig.isPeriodically &&\n    currentAction?.config?.advancedConfig.periodInterval\n  ) {\n    registerActionPeriod(currentAction)\n  }\n}\n\nasync function handleBatchUpdateActionItem(\n  action: ReturnType<typeof actionActions.batchUpdateActionItemReducer>,\n  listenerApi: AppListenerEffectAPI,\n) {\n  const selectedAction = listenerApi.getState().config.selectedAction\n  const targetSelectedAction = action.payload.find(\n    (action) => action.actionID === selectedAction?.actionID,\n  )\n  if (targetSelectedAction) {\n    listenerApi.dispatch(\n      configActions.changeSelectedAction(targetSelectedAction),\n    )\n  }\n}\n\nconst handleUpdateDisplayNameEffect = (\n  action: ReturnType<typeof actionActions.updateActionDisplayNameReducer>,\n  listenerApi: AppListenerEffectAPI,\n) => {\n  const { oldDisplayName, newDisplayName } = action.payload\n  mixedChangeDisplayNameHelper(listenerApi, oldDisplayName, newDisplayName)\n}\n\nconst handleUpdateAsyncEffect = (\n  action: UnknownAction,\n  listenerApi: AppListenerEffectAPI,\n) => {\n  const rootState = listenerApi.getState()\n  const currentSelectedID = rootState.config.selectedAction?.actionID\n  const allChangedActions: ActionItem<ActionContent>[] = []\n  if (actionActions.updateActionDisplayNameReducer.match(action)) {\n    const { actionID } = action.payload\n    if (actionID === rootState.config.selectedAction?.actionID) {\n      const currentAction = rootState.currentApp.action.find(\n        (item) => item.actionID === actionID,\n      )\n      if (!currentAction) return\n      const cachedAction = getCachedAction(listenerApi.getState())\n      listenerApi.dispatch(configActions.changeSelectedAction(currentAction))\n      if (!cachedAction) return\n      listenerApi.dispatch(\n        configActions.updateCachedAction({\n          ...cachedAction,\n          displayName: action.payload.newDisplayName,\n        }),\n      )\n      allChangedActions.push(currentAction)\n    }\n  } else if (\n    actionActions.batchUpdateMultiActionSlicePropsReducer.match(action)\n  ) {\n    const currentActionUpdateSlice = action.payload.find(\n      (item: UpdateActionSlicePropsPayload) =>\n        item.actionID === currentSelectedID,\n    )\n    if (!currentActionUpdateSlice) return\n    const currentActionID = currentActionUpdateSlice.actionID\n    const currentAction = rootState.currentApp.action.find(\n      (item) => item.actionID === currentActionID,\n    )\n    if (!currentAction) return\n    listenerApi.dispatch(configActions.changeSelectedAction(currentAction))\n    action.payload.forEach((payloadAction) => {\n      const cAction = rootState.currentApp.action.find(\n        (item) => item.actionID === payloadAction.actionID,\n      )\n      if (cAction) {\n        allChangedActions.push(cAction)\n      }\n    })\n  }\n\n  const isGuideMode = getIsILLAGuideMode(rootState)\n  if (allChangedActions.length && !isGuideMode) {\n    fetchBatchUpdateAction(allChangedActions)\n  }\n}\n\nexport function setupActionListeners(\n  startListening: AppStartListening,\n): Unsubscribe {\n  const subscriptions = [\n    startListening({\n      actionCreator: actionActions.updateActionItemReducer,\n      effect: handleUpdateActionItem,\n    }),\n    startListening({\n      actionCreator: actionActions.batchUpdateActionItemReducer,\n      effect: handleBatchUpdateActionItem,\n    }),\n    startListening({\n      actionCreator: actionActions.addActionItemReducer,\n      effect: handleAddActionItemEffect,\n    }),\n    startListening({\n      actionCreator: actionActions.updateActionDisplayNameReducer,\n      effect: handleUpdateDisplayNameEffect,\n    }),\n    startListening({\n      matcher: isAnyOf(\n        actionActions.updateActionDisplayNameReducer,\n        actionActions.batchUpdateMultiActionSlicePropsReducer,\n      ),\n      effect: handleUpdateAsyncEffect,\n    }),\n  ]\n\n  return () => {\n    subscriptions.forEach((unsubscribe) => unsubscribe())\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/action/actionReducer.ts",
    "content": "import { ActionContent, ActionItem } from \"@illa-public/public-types\"\nimport { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport { klona } from \"klona/json\"\nimport { set } from \"lodash-es\"\nimport {\n  RemoveActionItemReducerPayload,\n  UpdateActionDisplayNamePayload,\n  UpdateActionSlicePropsPayload,\n  actionInitialState,\n} from \"@/redux/currentApp/action/actionState\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { isObject } from \"@/utils/typeHelper\"\n\nexport const initActionListReducer: CaseReducer<\n  ActionItem<ActionContent>[],\n  PayloadAction<ActionItem<ActionContent>[]>\n> = (_, action) => {\n  return action.payload\n}\n\nexport const addActionItemReducer: CaseReducer<\n  ActionItem<ActionContent>[],\n  PayloadAction<ActionItem<ActionContent>>\n> = (state, action) => {\n  state.push(action.payload)\n  return state\n}\n\nexport const batchAddActionItemReducer: CaseReducer<\n  ActionItem<ActionContent>[],\n  PayloadAction<ActionItem<ActionContent>[]>\n> = (state, action) => {\n  return state.concat(action.payload)\n}\n\nexport const updateActionItemReducer: CaseReducer<\n  ActionItem<ActionContent>[],\n  PayloadAction<ActionItem<ActionContent>>\n> = (state, action) => {\n  const index = state.findIndex((item: ActionItem<ActionContent>) => {\n    return item.actionID === action.payload.actionID\n  })\n  if (index != -1) {\n    state[index] = action.payload\n  }\n  return state\n}\n\nexport const updateActionDisplayNameReducer: CaseReducer<\n  ActionItem<ActionContent>[],\n  PayloadAction<UpdateActionDisplayNamePayload>\n> = (state, action) => {\n  const index = state.findIndex((item: ActionItem<ActionContent>) => {\n    return item.actionID === action.payload.actionID\n  })\n  if (index != -1) {\n    DisplayNameGenerator.removeDisplayName(state[index].displayName)\n    state[index].displayName = action.payload.newDisplayName\n    DisplayNameGenerator.addDisplayNames([action.payload.newDisplayName])\n  }\n  return state\n}\n\nexport const batchUpdateMultiActionSlicePropsReducer: CaseReducer<\n  ActionItem<ActionContent>[],\n  PayloadAction<UpdateActionSlicePropsPayload[]>\n> = (state, action) => {\n  action.payload.forEach(({ actionID, displayName, propsSlice }) => {\n    if (!isObject(propsSlice) || !displayName) {\n      return\n    }\n    const actionIndex = state.findIndex((item) => {\n      return item.actionID === actionID\n    })\n    if (actionIndex === -1) return\n    const action = state[actionIndex]\n    const clonedAction = klona(action)\n    Object.keys(propsSlice).forEach((path) => {\n      const newValue = propsSlice[path]\n      set(clonedAction, path, newValue)\n    })\n    state[actionIndex] = clonedAction\n  })\n}\n\nexport const removeActionItemReducer: CaseReducer<\n  ActionItem<ActionContent>[],\n  PayloadAction<RemoveActionItemReducerPayload>\n> = (state, action) => {\n  state.splice(\n    state.findIndex(\n      (item: ActionItem<ActionContent>) =>\n        item.displayName === action.payload.displayName,\n    ),\n    1,\n  )\n  DisplayNameGenerator.removeDisplayName(action.payload.displayName)\n\n  return state\n}\n\nexport const resetActionReducer: CaseReducer<\n  ActionItem<ActionContent>[],\n  PayloadAction\n> = () => {\n  return actionInitialState\n}\n\nexport const batchUpdateResourceID: CaseReducer<\n  ActionItem<ActionContent>[],\n  PayloadAction<Record<string, { actionID: string; resourceID: string }>>\n> = (state, action) => {\n  const payload = action.payload\n  Object.values(payload).forEach(({ actionID, resourceID }) => {\n    const index = state.findIndex((item: ActionItem<ActionContent>) => {\n      return item.actionID === actionID\n    })\n    if (index != -1) {\n      state[index].resourceID = resourceID\n    }\n  })\n}\n\nexport const batchUpdateActionItemReducer: CaseReducer<\n  ActionItem<ActionContent>[],\n  PayloadAction<ActionItem<ActionContent>[]>\n> = (state, action) => {\n  action.payload.forEach((item) => {\n    const index = state.findIndex((actionItem) => {\n      return actionItem.actionID === item.actionID\n    })\n    if (index != -1) {\n      state[index] = item\n    }\n  })\n  return state\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/action/actionSelector.ts",
    "content": "import { getTutorialLink } from \"@illa-public/missing-resource-module/util\"\nimport { ActionContent, ActionItem } from \"@illa-public/public-types\"\nimport { createSelector } from \"@reduxjs/toolkit\"\nimport { RootState } from \"@/store\"\nimport { getAIAgentIDMapAgent } from \"../../aiAgent/dashboardTeamAIAgentSelector\"\nimport { getResourceIDMapResource } from \"../../resource/resourceSelector\"\nimport { getGlobalDataToActionList } from \"../components/componentsSelector\"\n\nexport const getActionList = (state: RootState) => state.currentApp.action\n\nexport const getActionItemByDisplayName = (\n  state: RootState,\n  displayName: string,\n) => {\n  const actionList = getActionList(state)\n  return actionList.find((item) => {\n    return item.displayName === displayName\n  })\n}\n\nexport const getActionIDMapAction = createSelector(\n  [getActionList],\n  (actions) => {\n    const actionIDMapAction: Record<string, ActionItem<ActionContent>> = {}\n    actions.forEach((action) => {\n      actionIDMapAction[action.actionID] = action\n    })\n    return actionIDMapAction\n  },\n)\n\nexport const getDisplayNameMapActions = createSelector(\n  [getActionList],\n  (actions) => {\n    const displayNameMapActions: Record<string, any> = {}\n    actions.forEach((action) => {\n      displayNameMapActions[action.displayName] = action\n    })\n    return displayNameMapActions\n  },\n)\n\nexport const getActionMixedList = createSelector(\n  [getActionList, getGlobalDataToActionList],\n  (actionList, globalDataList) => {\n    return actionList.concat(...globalDataList)\n  },\n)\n\nexport const getMissingResourceActionList = createSelector(\n  [getResourceIDMapResource, getActionList, getAIAgentIDMapAgent],\n  (resourceMap, actionList, aiAgentList) => {\n    const missingResourceActionList: ActionItem<ActionContent>[] = []\n    actionList.forEach((action) => {\n      const resource = resourceMap[action.resourceID!]\n      const agent = aiAgentList[action.resourceID!]\n      if (\n        !resource &&\n        !agent &&\n        action.actionType !== \"globalData\" &&\n        action.actionType !== \"transformer\" &&\n        action.actionType !== \"illadrive\"\n      ) {\n        missingResourceActionList.push(action)\n      }\n    })\n    return missingResourceActionList\n  },\n)\n\nexport const getMissingResourceActionGroupByTutorialOrResourceID =\n  createSelector(\n    [getMissingResourceActionList],\n    (missingResourceActionList) => {\n      const tutorialLinkMapActions: Record<\n        string,\n        {\n          actionIDs: string[]\n          resourceType: string\n          tutorialHref: string\n          hasLink: boolean\n        }\n      > = {}\n      missingResourceActionList.forEach((action) => {\n        const hrefLink = action.config.tutorialLink\n\n        if (hrefLink) {\n          if (!tutorialLinkMapActions[hrefLink]) {\n            tutorialLinkMapActions[hrefLink] = {\n              actionIDs: [],\n              resourceType: action.actionType,\n              tutorialHref: hrefLink,\n              hasLink: true,\n            }\n          }\n          tutorialLinkMapActions[hrefLink].actionIDs.push(action.actionID)\n        } else {\n          const resourceID = action.resourceID!\n          if (!tutorialLinkMapActions[resourceID]) {\n            tutorialLinkMapActions[resourceID] = {\n              actionIDs: [],\n              resourceType: action.actionType,\n              tutorialHref: getTutorialLink(action.actionType),\n              hasLink: false,\n            }\n          }\n          tutorialLinkMapActions[resourceID].actionIDs.push(action.actionID)\n        }\n      })\n      return tutorialLinkMapActions\n    },\n  )\n\nexport const getHasMissingResourceAction = createSelector(\n  [getMissingResourceActionList],\n  (missingResourceActionList) => {\n    return missingResourceActionList.length > 0\n  },\n)\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/action/actionSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  addActionItemReducer,\n  batchAddActionItemReducer,\n  batchUpdateActionItemReducer,\n  batchUpdateMultiActionSlicePropsReducer,\n  batchUpdateResourceID,\n  initActionListReducer,\n  removeActionItemReducer,\n  resetActionReducer,\n  updateActionDisplayNameReducer,\n  updateActionItemReducer,\n} from \"@/redux/currentApp/action/actionReducer\"\nimport { actionInitialState } from \"@/redux/currentApp/action/actionState\"\n\nconst actionSlice = createSlice({\n  name: \"action\",\n  initialState: actionInitialState,\n  reducers: {\n    initActionListReducer,\n    addActionItemReducer,\n    batchAddActionItemReducer,\n    updateActionItemReducer,\n    removeActionItemReducer,\n    resetActionReducer,\n    updateActionDisplayNameReducer,\n    batchUpdateMultiActionSlicePropsReducer,\n    batchUpdateResourceID,\n    batchUpdateActionItemReducer,\n  },\n})\n\nexport const actionActions = actionSlice.actions\nexport default actionSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/action/actionState.ts",
    "content": "import { ActionContent, ActionItem } from \"@illa-public/public-types\"\n\n// TODO @aruseito not use any\nexport interface Events {\n  successEvent?: any[]\n  failedEvent?: any[]\n}\n\nexport interface UpdateActionDisplayNamePayload {\n  oldDisplayName: string\n  newDisplayName: string\n  actionID: string\n}\n\nexport interface UpdateActionSlicePropsPayload {\n  displayName: string\n  actionID: string\n  propsSlice: {\n    [key: string]: unknown\n  }\n}\n\nexport const actionInitialState: ActionItem<ActionContent>[] = []\n\nexport interface RemoveActionItemReducerPayload {\n  actionID: string\n  displayName: string\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/appInfo/appInfoReducer.ts",
    "content": "import { AppInfoShape } from \"@illa-public/public-types\"\nimport { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\n\nexport const updateAppInfoReducer: CaseReducer<\n  AppInfoShape,\n  PayloadAction<AppInfoShape>\n> = (state, action) => {\n  return action.payload\n}\n\nexport const updateAppContributeReducer: CaseReducer<\n  AppInfoShape,\n  PayloadAction<boolean>\n> = (state, action) => {\n  state.config.publishedToMarketplace = action.payload\n}\n\nexport const updateAppPublicReducer: CaseReducer<\n  AppInfoShape,\n  PayloadAction<boolean>\n> = (state, action) => {\n  state.config.public = action.payload\n}\n\nexport const updateAppDeployedReducer: CaseReducer<\n  AppInfoShape,\n  PayloadAction<boolean>\n> = (state, action) => {\n  state.deployed = action.payload\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/appInfo/appInfoSelector.ts",
    "content": "import { createSelector } from \"@reduxjs/toolkit\"\nimport { RootState } from \"@/store\"\n\nexport const getAppInfo = (state: RootState) => {\n  return state.currentApp.appInfo\n}\n\nexport const getCurrentAppWaterMarkConfig = (state: RootState) => {\n  return state.currentApp.appInfo?.config?.waterMark\n}\n\nexport const getAppId = createSelector([getAppInfo], (appInfo) => {\n  return appInfo.appId\n})\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/appInfo/appInfoSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  updateAppContributeReducer,\n  updateAppDeployedReducer,\n  updateAppInfoReducer,\n  updateAppPublicReducer,\n} from \"@/redux/currentApp/appInfo/appInfoReducer\"\nimport { DashboardAppInitialState } from \"./appInfoState\"\n\nconst appInfoSlice = createSlice({\n  name: \"appInfo\",\n  initialState: DashboardAppInitialState,\n  reducers: {\n    updateAppInfoReducer,\n    updateAppContributeReducer,\n    updateAppPublicReducer,\n    updateAppDeployedReducer,\n  },\n})\n\nexport const appInfoActions = appInfoSlice.actions\nexport default appInfoSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/appInfo/appInfoState.ts",
    "content": "import { APP_TYPE, AppInfoShape } from \"@illa-public/public-types\"\n\nexport const DashboardAppInitialState: AppInfoShape = {\n  updatedAt: \"\",\n  updatedBy: \"\",\n  appId: \"\",\n  appName: \"\",\n  deployed: false,\n  config: {\n    public: false,\n    waterMark: false,\n    publishedToMarketplace: false,\n    publishWithAIAgent: false,\n    appType: APP_TYPE.PC,\n  },\n  appActivity: {\n    modifier: \"\",\n    modifiedAt: \"\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/collaborators/collaboratorsHandlers.ts",
    "content": "import { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { Connection, getTextMessagePayload } from \"@/api/ws\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { CollaboratorsInfo } from \"@/redux/currentApp/collaborators/collaboratorsState\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport store, { AppListenerEffectAPI } from \"@/store\"\n\nexport const getDisattachedComponents = (\n  currentAttached: Record<string, CollaboratorsInfo[]>,\n  currentSelected: string[],\n) => {\n  const preciousAttached = Object.keys(currentAttached) || []\n  return preciousAttached.filter(\n    (displayName) => !currentSelected.includes(displayName),\n  )\n}\n\nexport const updateSelectedComponentUsersHandler = (payload: string[]) => {\n  const currentAppID = store.getState().currentApp.appInfo.appId ?? \"\"\n  const { id: teamID = \"\", uid = \"\" } =\n    getCurrentTeamInfo(store.getState()) ?? {}\n  Connection.getTextRoom(\"app\", currentAppID)?.send(\n    getTextMessagePayload(\n      TextSignal.COOPERATE_ATTACH,\n      TextTarget.COMPONENTS,\n      true,\n      {\n        type: \"attachComponent\",\n        payload: [],\n      },\n      teamID,\n      uid,\n      payload,\n    ),\n  )\n}\n\nexport const clearComponentAttachedUsersHandler = (payload: string[]) => {\n  const currentAppID = store.getState().currentApp.appInfo.appId ?? \"\"\n  const { id: teamID = \"\", uid = \"\" } =\n    getCurrentTeamInfo(store.getState()) ?? {}\n  Connection.getTextRoom(\"app\", currentAppID)?.send(\n    getTextMessagePayload(\n      TextSignal.COOPERATE_DISATTACH,\n      TextTarget.COMPONENTS,\n      true,\n      {\n        type: \"attachComponent\",\n        payload: [],\n      },\n      teamID,\n      uid,\n      payload,\n    ),\n  )\n}\n\nexport const updateCurrentAllComponentsAttachedUsers = (\n  displayName: string[],\n  currentComponentsAttachedUsers: Record<string, CollaboratorsInfo[]>,\n) => {\n  updateSelectedComponentUsersHandler(displayName)\n  const disattachedComponents = getDisattachedComponents(\n    currentComponentsAttachedUsers,\n    displayName,\n  )\n  if (!!disattachedComponents.length) {\n    clearComponentAttachedUsersHandler(disattachedComponents)\n  }\n}\n\nexport const handleClearSelectedComponentExecution = (\n  action: ReturnType<typeof componentsActions.deleteComponentNodeReducer>,\n  listenerApi: AppListenerEffectAPI,\n) => {\n  let currentSelected = listenerApi.getState().config.selectedComponents\n  if (Array.isArray(currentSelected) && currentSelected.length > 0) {\n    currentSelected = currentSelected.filter(\n      (item) => !action.payload.displayNames.includes(item),\n    )\n  }\n  listenerApi.dispatch(configActions.updateSelectedComponent(currentSelected))\n  clearComponentAttachedUsersHandler(action.payload.displayNames)\n}\n\nexport const AVATAR_WIDTH = 14\nexport const AVATAR_GAP = 4\n\nexport const MIN_DISABLE_MARGIN_WIDTH = 34\n\nexport const MIN_THREE_AVATAR_WIDTH = 50\n\nexport const MIN_THREE_AVATAR_MOVE_BAR_WIDTH = 70\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/collaborators/collaboratorsReducer.ts",
    "content": "import { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport {\n  CollaboratorsInfo,\n  CollaboratorsState,\n} from \"@/redux/currentApp/collaborators/collaboratorsState\"\n\n// update component attach user\nexport const clearComponentAttachedUsers: CaseReducer<\n  CollaboratorsState,\n  PayloadAction<Record<string, CollaboratorsInfo[]>>\n> = (state, action) => {\n  const payload = action.payload || {}\n  state.components =\n    Object.keys(payload).reduce((result, key) => {\n      return {\n        ...result,\n        [key]: (payload[key] || []).reverse(),\n      }\n    }, {}) || {}\n}\n\n// update component attach user\nexport const updateComponentAttachedUsers: CaseReducer<\n  CollaboratorsState,\n  PayloadAction<Record<string, CollaboratorsInfo[]>>\n> = (state, action) => {\n  const payload = action.payload || {}\n  state.components =\n    Object.keys(payload).reduce((result, key) => {\n      return {\n        ...result,\n        [key]: (payload[key] || []).reverse(),\n      }\n    }, {}) || {}\n}\n\n// enter room\nexport const setInRoomUsers: CaseReducer<\n  CollaboratorsState,\n  PayloadAction<{ inRoomUsers: CollaboratorsInfo[] }>\n> = (state, action) => {\n  state.inRoomUsers = action.payload.inRoomUsers.reverse()\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/collaborators/collaboratorsSelector.ts",
    "content": "import { RootState } from \"@/store\"\nimport { CollaboratorsInfo } from \"./collaboratorsState\"\n\nexport const getComponentAttachUsers = (state: RootState) => {\n  return state.currentApp.collaborators.components\n}\n\nexport const getCurrentAppAttachUsers = (state: RootState) => {\n  return state.currentApp.collaborators.inRoomUsers\n}\n\nexport const getTargetCurrentUsersExpendMe = (\n  attachUsers: Record<string, CollaboratorsInfo[]>,\n  targetComponentDisplayName: string,\n  currentUserId: string,\n): CollaboratorsInfo[] => {\n  const targetComponentAttachUsers = attachUsers[targetComponentDisplayName]\n  if (!targetComponentAttachUsers) return []\n  return targetComponentAttachUsers.filter((user) => user.id !== currentUserId)\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/collaborators/collaboratorsSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  clearComponentAttachedUsers,\n  setInRoomUsers,\n  updateComponentAttachedUsers,\n} from \"@/redux/currentApp/collaborators/collaboratorsReducer\"\nimport { CollaboratorsInitialState } from \"@/redux/currentApp/collaborators/collaboratorsState\"\n\nconst collaboratorsSlice = createSlice({\n  name: \"collaborators\",\n  initialState: CollaboratorsInitialState,\n  reducers: {\n    setInRoomUsers,\n    clearComponentAttachedUsers,\n    updateComponentAttachedUsers,\n  },\n})\n\nexport const collaboratorsActions = collaboratorsSlice.actions\nexport default collaboratorsSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/collaborators/collaboratorsState.ts",
    "content": "import { SenderType } from \"@/page/AI/components/PreviewChat/interface\"\n\nexport interface CollaboratorsInfo {\n  id: string\n  nickname: string\n  avatar: string\n  roomRole: SenderType\n}\n\nexport interface CollaboratorsState {\n  components: Record<string, CollaboratorsInfo[]>\n  inRoomUsers: CollaboratorsInfo[]\n}\n\nexport const CollaboratorsInitialState: CollaboratorsState = {\n  inRoomUsers: [],\n  components: {},\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/components/componentsListener.ts",
    "content": "import { ComponentMapNode } from \"@illa-public/public-types\"\nimport { CONTAINER_TYPE } from \"@illa-public/public-types\"\nimport { AnyAction, Unsubscribe, isAnyOf } from \"@reduxjs/toolkit\"\nimport { REDUX_ACTION_FROM } from \"@/middleware/undoRedo/interface\"\nimport {\n  applyEffectMapToComponentNodes,\n  getNearComponentNodes,\n  getReflowResult,\n} from \"@/page/App/components/DotPanel/calc\"\nimport { getNewPositionWithCrossing } from \"@/page/App/components/DotPanel/utils/crossingHelper\"\nimport { combineWidgetInfos } from \"@/page/App/components/DotPanel/utils/getDragShadow\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { handleClearSelectedComponentExecution } from \"@/redux/currentApp/collaborators/collaboratorsHandlers\"\nimport {\n  getComponentMap,\n  getGlobalDataToActionList,\n  searchComponentFromMap,\n  searchDSLByDisplayName,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { cursorActions } from \"@/redux/currentApp/cursor/cursorSlice\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { AppListenerEffectAPI, AppStartListening } from \"@/store\"\nimport { mixedChangeDisplayNameHelper } from \"@/utils/changeDisplayNameHelper\"\nimport IllaUndoRedoManager from \"@/utils/undoRedo/undo\"\nimport { getClientWidgetLayoutInfo } from \"../layoutInfo/layoutInfoSelector\"\nimport { layoutInfoActions } from \"../layoutInfo/layoutInfoSlice\"\nimport { WidgetLayoutInfo } from \"../layoutInfo/layoutInfoState\"\n\nfunction handleUpdateComponentDisplayNameEffect(\n  action: ReturnType<\n    typeof componentsActions.updateComponentDisplayNameReducer\n  >,\n  listenApi: AppListenerEffectAPI,\n) {\n  const { newDisplayName } = action.payload\n  const rootState = listenApi.getState()\n  const components = getComponentMap(rootState)\n  const newComponent = searchComponentFromMap(components, newDisplayName)\n  if (\n    newComponent &&\n    newComponent.containerType === CONTAINER_TYPE.EDITOR_SCALE_SQUARE\n  ) {\n    listenApi.dispatch(\n      configActions.updateSelectedComponent([newComponent.displayName]),\n    )\n  }\n}\n\nasync function handleChangeCurrentPageWhenDelete(\n  action: ReturnType<typeof componentsActions.deletePageNodeReducer>,\n  listenerApi: AppListenerEffectAPI,\n) {\n  const rootState = listenerApi.getState()\n  const executionTree = getExecutionResult(rootState)\n  const rootNode = executionTree.root\n  const { currentPageIndex, homepageDisplayName, pageSortedKey } = rootNode\n  const { displayName, originPageSortedKey } = action.payload\n  const newSortedKey = originPageSortedKey.filter((key) => key !== displayName)\n  const currentPageDisplayName = originPageSortedKey[currentPageIndex]\n  if (displayName === homepageDisplayName) {\n    if (currentPageDisplayName === homepageDisplayName) {\n      listenerApi.dispatch(\n        componentsActions.updateRootNodePropsReducer({\n          currentPageIndex: 0,\n          homepageDisplayName: pageSortedKey[0],\n          pageSortedKey,\n        }),\n      )\n    } else {\n      listenerApi.dispatch(\n        componentsActions.updateRootNodePropsReducer({\n          currentPageIndex: 0,\n          homepageDisplayName: pageSortedKey[0],\n          pageSortedKey,\n        }),\n      )\n      setTimeout(() => {\n        const newIndex = pageSortedKey.findIndex(\n          (key: string) => key === currentPageDisplayName,\n        )\n        const currentIndex = newIndex === -1 ? 0 : newIndex\n        listenerApi.dispatch(\n          executionActions.updateExecutionByDisplayNameReducer({\n            displayName: \"root\",\n            value: {\n              currentPageIndex: currentIndex,\n            },\n          }),\n        )\n      })\n    }\n  } else {\n    const newIndex = pageSortedKey.findIndex(\n      (key: string) => key === currentPageDisplayName,\n    )\n    listenerApi.dispatch(\n      executionActions.updateExecutionByDisplayNameReducer({\n        displayName: \"root\",\n        value: {\n          currentPageIndex: newIndex === -1 ? 0 : newIndex,\n          pageSortedKey: newSortedKey,\n        },\n      }),\n    )\n  }\n}\n\nasync function handleChangeCurrentSectionWhenDelete(\n  action: ReturnType<typeof componentsActions.deleteSectionViewReducer>,\n  listenerApi: AppListenerEffectAPI,\n) {\n  const { viewDisplayName, originPageSortedKey, parentNodeName } =\n    action.payload\n  const rootState = listenerApi.getState()\n  const executionTree = getExecutionResult(rootState)\n  const parentNode = executionTree[parentNodeName]\n  if (!parentNode) return\n  const oldIndex = originPageSortedKey.findIndex(\n    (key) => key === viewDisplayName,\n  )\n  if (oldIndex === parentNode.currentViewIndex) {\n    listenerApi.dispatch(\n      executionActions.updateExecutionByDisplayNameReducer({\n        displayName: parentNodeName,\n        value: {\n          currentViewIndex: 0,\n        },\n      }),\n    )\n  }\n}\n\nconst updateComponentReflowComponentsAdapter = (\n  action: ReturnType<\n    | typeof componentsActions.addComponentReducer\n    | typeof componentsActions.updateComponentLayoutInfoReducer\n    | typeof componentsActions.updateComponentPositionReducer\n  >,\n  currentLayoutInfo: Record<string, WidgetLayoutInfo>,\n) => {\n  switch (action.type) {\n    case \"components/updateComponentPositionReducer\": {\n      const { newParentNodeDisplayName, updateSlices } = action.payload\n      const square = combineWidgetInfos(updateSlices)\n      const effectedDisplayNames = updateSlices.map(\n        (slice) => slice.displayName,\n      )\n      const originUpdateSlice = updateSlices.map((slice) => ({\n        displayName: slice.displayName,\n        layoutInfo: {\n          x: slice.x,\n          y: slice.y,\n          w: slice.w,\n          h: slice.h,\n        },\n      }))\n      return {\n        parentDisplayName: newParentNodeDisplayName,\n        effectedDisplayNames,\n        square,\n        originUpdateSlice,\n      }\n    }\n    case \"components/addComponentReducer\": {\n      const effectedDisplayNames = action.payload.map(\n        (item) => item.displayName,\n      )\n      const square = combineWidgetInfos(action.payload)\n\n      const originUpdateSlice = action.payload.map((slice) => ({\n        displayName: slice.displayName,\n        layoutInfo: {\n          x: slice.x,\n          y: slice.y,\n          w: slice.w,\n          h: slice.h,\n        },\n      }))\n      return {\n        parentDisplayName: action.payload[0].parentNode!,\n        effectedDisplayNames: effectedDisplayNames,\n        square: square,\n        originUpdateSlice: originUpdateSlice,\n      }\n    }\n    case \"components/updateComponentLayoutInfoReducer\": {\n      const { displayName, layoutInfo } = action.payload\n      const currentWidgetLayoutInfo = currentLayoutInfo[displayName]\n      return {\n        parentDisplayName: action.payload.parentNode,\n        effectedDisplayNames: [displayName],\n        square: {\n          x: layoutInfo.x,\n          y: layoutInfo.y,\n          w: layoutInfo.w,\n          h: layoutInfo.h ?? currentWidgetLayoutInfo.layoutInfo.h,\n        },\n        originUpdateSlice: [\n          {\n            displayName,\n            layoutInfo: {\n              ...layoutInfo,\n              h: layoutInfo.h ?? currentWidgetLayoutInfo.layoutInfo.h,\n            },\n          },\n        ],\n      }\n    }\n  }\n}\n\nfunction handleUpdateComponentReflowEffect(\n  action: AnyAction,\n  listenApi: AppListenerEffectAPI,\n) {\n  const currentLayoutInfo = getClientWidgetLayoutInfo(listenApi.getState())\n  const updateComponents = updateComponentReflowComponentsAdapter(\n    action as ReturnType<\n      | typeof componentsActions.addComponentReducer\n      | typeof componentsActions.updateComponentLayoutInfoReducer\n      | typeof componentsActions.updateComponentPositionReducer\n    >,\n    currentLayoutInfo,\n  )\n\n  const updateSlice = updateComponents.originUpdateSlice\n\n  const effectMap = getNewPositionWithCrossing(\n    updateComponents.square,\n    updateComponents.parentDisplayName,\n    updateComponents.effectedDisplayNames,\n  )\n\n  if (effectMap && effectMap.size > 0) {\n    effectMap.forEach((widgetLayoutInfo) => {\n      updateSlice.push({\n        displayName: widgetLayoutInfo.displayName,\n        layoutInfo: {\n          x: widgetLayoutInfo.layoutInfo.x,\n          y: widgetLayoutInfo.layoutInfo.y,\n          w: widgetLayoutInfo.layoutInfo.w,\n          h: widgetLayoutInfo.layoutInfo.h,\n        },\n      })\n    })\n  }\n\n  if (!action.from || action.from === REDUX_ACTION_FROM.REDO) {\n    const filteredUpdateSlice = updateSlice.filter(\n      (slice) =>\n        !updateComponents.effectedDisplayNames.includes(slice.displayName),\n    )\n    const rootState = listenApi.getState()\n    const originLayoutInfos = filteredUpdateSlice.map((slice) => {\n      const originLayoutInfo = searchDSLByDisplayName(\n        slice.displayName,\n        rootState,\n      )\n      return {\n        displayName: slice.displayName,\n        layoutInfo: {\n          x: originLayoutInfo!.x,\n          y: originLayoutInfo!.y,\n          w: originLayoutInfo!.w,\n          h: originLayoutInfo!.h,\n        },\n      }\n    })\n    const newAction = {\n      type: \"components/batchUpdateComponentLayoutInfoWhenReflowReducer\",\n      payload: originLayoutInfos,\n      from: action.from,\n    }\n    IllaUndoRedoManager.modifyUndoStackAtLast(\n      [JSON.parse(JSON.stringify(newAction))],\n      action.from === REDUX_ACTION_FROM.REDO,\n    )\n  }\n\n  listenApi.dispatch(\n    componentsActions.batchUpdateComponentLayoutInfoWhenReflowReducer(\n      updateSlice,\n    ),\n  )\n}\n\nconst handleUpdateHeightEffect = (\n  action: ReturnType<typeof componentsActions.updateComponentNodeHeightReducer>,\n  listenerApi: AppListenerEffectAPI,\n) => {\n  const { displayName, height, oldHeight } = action.payload\n  const rootState = listenerApi.getState()\n  const components = getComponentMap(rootState)\n  const newItem = searchComponentFromMap(components, displayName)\n  if (!newItem) return\n  const parentNodeDisplayName = newItem.parentNode\n  const target = searchComponentFromMap(components, parentNodeDisplayName)\n  let allComponents: ComponentMapNode[] = []\n  if (target) {\n    allComponents = target.childrenNode.map(\n      (displayName) => components[displayName],\n    )\n  }\n\n  const cloneDeepAllComponents = allComponents.filter(\n    (node) => node.displayName !== newItem.displayName,\n  )\n\n  if (oldHeight <= newItem.h && oldHeight < height) {\n    const result = getReflowResult(newItem, cloneDeepAllComponents, false)\n    listenerApi.dispatch(\n      componentsActions.updateComponentReflowReducer([\n        {\n          parentDisplayName: newItem.parentNode || \"root\",\n          childNodes: result.finalState,\n        },\n      ]),\n    )\n  }\n  if (oldHeight >= newItem.h && oldHeight > height) {\n    const effectRows = oldHeight - newItem.h\n    const effectMap = getNearComponentNodes(\n      {\n        ...newItem,\n        h: oldHeight,\n      },\n      cloneDeepAllComponents,\n    )\n    effectMap.set(newItem.displayName, newItem)\n    effectMap.forEach((node) => {\n      if (node.displayName !== newItem.displayName) {\n        node.y -= effectRows\n      }\n    })\n    let finalState = applyEffectMapToComponentNodes(effectMap, allComponents)\n    listenerApi.dispatch(\n      componentsActions.updateComponentReflowReducer([\n        {\n          parentDisplayName: newItem.parentNode || \"root\",\n          childNodes: finalState,\n        },\n      ]),\n    )\n  }\n}\n\nconst handleUpdateDisplayNameEffect = (\n  action: ReturnType<\n    typeof componentsActions.updateComponentDisplayNameReducer\n  >,\n  listenerApi: AppListenerEffectAPI,\n) => {\n  const { displayName, newDisplayName } = action.payload\n  mixedChangeDisplayNameHelper(listenerApi, displayName, newDisplayName)\n  listenerApi.dispatch(\n    layoutInfoActions.updateWidgetLayoutInfoWhenChangeDisplayNameReducer({\n      oldDisplayName: displayName,\n      newDisplayName,\n    }),\n  )\n}\n\nconst handleUpdateGlobalDataDisplayNameEffect = (\n  action: ReturnType<typeof componentsActions.setGlobalStateReducer>,\n  listenerApi: AppListenerEffectAPI,\n) => {\n  const { key, oldKey } = action.payload\n  if (!oldKey) return\n  const rootState = listenerApi.getState()\n  const globalDataList = getGlobalDataToActionList(rootState)\n  const currentGlobalData = globalDataList.find(\n    (action) => action.displayName === key,\n  )\n  if (!currentGlobalData) return\n  listenerApi.dispatch(configActions.changeSelectedAction(currentGlobalData))\n  mixedChangeDisplayNameHelper(listenerApi, oldKey, key, \"globalDataKey\")\n}\n\nconst handlerUpdateViewportSizeEffect = (\n  action: ReturnType<typeof componentsActions.updateViewportSizeReducer>,\n  listenApi: AppListenerEffectAPI,\n) => {\n  listenApi.dispatch(cursorActions.resetCursorReducer())\n}\n\nconst updateSubPagePathEffect = (\n  action: ReturnType<typeof componentsActions.updateSubPagePathReducer>,\n  listenApi: AppListenerEffectAPI,\n) => {\n  const { pageName, subPagePath, oldSubPagePath } = action.payload\n  const oldExecutionResult = getExecutionResult(listenApi.getState())\n  const rootNode = oldExecutionResult.root\n  mixedChangeDisplayNameHelper(listenApi, oldSubPagePath, subPagePath)\n  if (rootNode.currentSubPagePath === oldSubPagePath) {\n    listenApi.dispatch(\n      executionActions.updateCurrentPagePathReducer({\n        pageDisplayName: pageName,\n        subPagePath,\n      }),\n    )\n  }\n}\n\nconst handleDeleteSubPageViewNodeEffect = (\n  action: ReturnType<typeof componentsActions.deleteSubPageViewNodeReducer>,\n  listenApi: AppListenerEffectAPI,\n) => {\n  const { pageName, subPagePath } = action.payload\n  const oldExecutionResult = getExecutionResult(listenApi.getState())\n  const rootNode = oldExecutionResult.root\n  if (rootNode.currentSubPagePath === subPagePath) {\n    listenApi.dispatch(\n      executionActions.updateCurrentPagePathReducer({\n        pageDisplayName: pageName,\n        subPagePath: undefined,\n      }),\n    )\n  }\n}\n\nexport function setupComponentsListeners(\n  startListening: AppStartListening,\n): Unsubscribe {\n  const subscriptions = [\n    startListening({\n      actionCreator: componentsActions.updateComponentDisplayNameReducer,\n      effect: handleUpdateComponentDisplayNameEffect,\n    }),\n    startListening({\n      matcher: isAnyOf(\n        componentsActions.addComponentReducer,\n        componentsActions.updateComponentLayoutInfoReducer,\n        componentsActions.batchUpdateComponentLayoutInfoReducer,\n        componentsActions.updateComponentPositionReducer,\n      ),\n      effect: handleUpdateComponentReflowEffect,\n    }),\n    startListening({\n      actionCreator: componentsActions.deletePageNodeReducer,\n      effect: handleChangeCurrentPageWhenDelete,\n    }),\n    startListening({\n      actionCreator: componentsActions.deleteComponentNodeReducer,\n      effect: handleClearSelectedComponentExecution,\n    }),\n    startListening({\n      actionCreator: componentsActions.deleteSectionViewReducer,\n      effect: handleChangeCurrentSectionWhenDelete,\n    }),\n    startListening({\n      actionCreator: componentsActions.updateComponentNodeHeightReducer,\n      effect: handleUpdateHeightEffect,\n    }),\n    startListening({\n      actionCreator: componentsActions.updateComponentDisplayNameReducer,\n      effect: handleUpdateDisplayNameEffect,\n    }),\n    startListening({\n      actionCreator: componentsActions.setGlobalStateReducer,\n      effect: handleUpdateGlobalDataDisplayNameEffect,\n    }),\n    startListening({\n      actionCreator: componentsActions.updateViewportSizeReducer,\n      effect: handlerUpdateViewportSizeEffect,\n    }),\n    startListening({\n      actionCreator: componentsActions.updateSubPagePathReducer,\n      effect: updateSubPagePathEffect,\n    }),\n    startListening({\n      actionCreator: componentsActions.deleteSubPageViewNodeReducer,\n      effect: handleDeleteSubPageViewNodeEffect,\n    }),\n  ]\n\n  return () => {\n    subscriptions.forEach((unsubscribe) => unsubscribe())\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/components/componentsPayload.ts",
    "content": "export interface UpdateComponentPositionPayload {\n  oldParentNodeDisplayName: string\n  newParentNodeDisplayName: string\n  updateSlices: {\n    displayName: string\n    x: number\n    y: number\n    w: number\n    h: number\n  }[]\n  columnNumberWhenDrag: number\n  columnNumberWhenDrop: number\n}\nexport interface LayoutInfo {\n  w: number\n  h: number\n  x: number\n  y: number\n  z: number\n  minW: number\n  minH: number\n}\n\nexport interface StatusInfo {\n  isDragging: boolean\n  isResizing: boolean\n}\n\nexport interface UpdateComponentNodeLayoutInfoPayload {\n  displayName: string\n  layoutInfo: {\n    x: number\n    y: number\n    h?: number\n    w: number\n  }\n  statusInfo?: Partial<StatusInfo>\n  parentNode: string\n}\n\nexport interface BatchUpdateComponentNodeLayoutInfoPayload {\n  displayName: string\n  layoutInfo: {\n    x: number\n    y: number\n    h: number\n    w: number\n  }\n}\n\nexport interface UpdateComponentSlicePropsPayload {\n  displayName: string\n  propsSlice: {\n    [key: string]: unknown\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/components/componentsReducer.ts",
    "content": "import {\n  ComponentMapNode,\n  ComponentTreeNode,\n  SectionViewShape,\n} from \"@illa-public/public-types\"\nimport { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport { klona } from \"klona/json\"\nimport { difference, set, unset } from \"lodash-es\"\nimport {\n  generateNewViewItem,\n  generateNewViewItemFromBodySectionConfig,\n} from \"@/page/App/components/PagePanel/Components/ViewsList/utils\"\nimport {\n  BatchUpdateComponentNodeLayoutInfoPayload,\n  LayoutInfo,\n  UpdateComponentNodeLayoutInfoPayload,\n  UpdateComponentPositionPayload,\n  UpdateComponentSlicePropsPayload,\n} from \"@/redux/currentApp/components/componentsPayload\"\nimport { searchComponentFromMap } from \"@/redux/currentApp/components/componentsSelector\"\nimport {\n  AddModalComponentPayload,\n  AddSectionViewByConfigPayload,\n  AddSectionViewPayload,\n  AddTargetPageSectionPayload,\n  ComponentsInitialState,\n  ComponentsState,\n  DeleteComponentNodePayload,\n  DeleteCurrentPageStylePayload,\n  DeleteGlobalStatePayload,\n  DeletePageNodePayload,\n  DeleteSectionViewPayload,\n  DeleteSubPageViewNodePayload,\n  DeleteTargetPageSectionPayload,\n  RootComponentNode,\n  RootComponentNodeProps,\n  SetGlobalStatePayload,\n  SortComponentNodeChildrenPayload,\n  UpdateComponentDisplayNamePayload,\n  UpdateComponentNodeHeightPayload,\n  UpdateComponentPropsPayload,\n  UpdateComponentReflowPayload,\n  UpdateCurrentPageStylePayload,\n  UpdateSectionViewPropsPayload,\n  UpdateTargetPageLayoutPayload,\n  UpdateTargetPagePropsPayload,\n  ViewportSizeType,\n} from \"@/redux/currentApp/components/componentsState\"\nimport { getNewWidgetPropsByUpdateSlice } from \"@/utils/componentNode\"\nimport { flatTreeToMap, transTreeToMap } from \"@/utils/componentNode/flatTree\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport {\n  generateModalSectionConfig,\n  generateSectionConfig,\n  generateSectionContainerConfig,\n  layoutValueMapGenerateConfig,\n} from \"@/utils/generators/generatePageOrSectionConfig\"\nimport { isObject } from \"@/utils/typeHelper\"\n\nfunction removeDisplayNames(\n  targetComponentNode: ComponentMapNode,\n  components: ComponentsState,\n) {\n  const needDeleteDisplayNames: string[] = [targetComponentNode.displayName]\n  delete components[targetComponentNode.displayName]\n  targetComponentNode.childrenNode?.forEach((childDisplayName) => {\n    return needDeleteDisplayNames.push(\n      ...removeDisplayNames(components[childDisplayName], components),\n    )\n  })\n\n  return needDeleteDisplayNames\n}\n\nexport const initComponentReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<ComponentsState>\n> = (state, action) => {\n  return action.payload\n}\n\n// update real-time\nexport const addComponentReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<ComponentTreeNode[]>\n> = (state, action) => {\n  action.payload.forEach((dealRootNode) => {\n    const dealNodeMap = flatTreeToMap(dealRootNode)\n    if (state == null || dealRootNode.parentNode == null) {\n      return state\n    } else {\n      const parentNode = searchComponentFromMap(state, dealRootNode.parentNode)\n      if (parentNode != null) {\n        if (dealRootNode.props) {\n          dealRootNode.props = getNewWidgetPropsByUpdateSlice(\n            dealRootNode.props ?? {},\n            {},\n          )\n        }\n        if (!Array.isArray(parentNode.childrenNode)) {\n          parentNode.childrenNode = [dealRootNode.displayName]\n        } else {\n          parentNode.childrenNode.push(dealRootNode.displayName)\n        }\n        Object.keys(dealNodeMap).forEach((key) => {\n          const node = dealNodeMap[key]\n          if (node.props) {\n            node.props = getNewWidgetPropsByUpdateSlice(node.props ?? {}, {})\n          }\n          state[key] = node\n        })\n      }\n    }\n  })\n}\n\nexport const addModalComponentReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<AddModalComponentPayload>\n> = (state, action) => {\n  const { currentPageDisplayName, modalComponentNode } = action.payload\n  if (!currentPageDisplayName || !modalComponentNode) {\n    return state\n  }\n  const currentPageNode = searchComponentFromMap(state, currentPageDisplayName)\n  if (currentPageNode == null || !Array.isArray(currentPageNode.childrenNode))\n    return state\n  const modalSectionNodeDisplayName = currentPageNode.childrenNode.find(\n    (childDisplayName) => {\n      return state[childDisplayName].type === \"MODAL_SECTION_NODE\"\n    },\n  )\n  if (!modalSectionNodeDisplayName) {\n    const newModalSectionNode = transTreeToMap(\n      generateModalSectionConfig(currentPageDisplayName, \"modalSection\"),\n    )\n    modalComponentNode.parentNode = newModalSectionNode.displayName\n    newModalSectionNode.childrenNode = [modalComponentNode.displayName]\n    currentPageNode.childrenNode.push(newModalSectionNode.displayName)\n    state[newModalSectionNode.displayName] = newModalSectionNode\n  } else {\n    modalComponentNode.parentNode = modalSectionNodeDisplayName\n    if (!Array.isArray(state[modalSectionNodeDisplayName].childrenNode)) {\n      state[modalSectionNodeDisplayName].childrenNode = []\n    }\n    const needAddNode = flatTreeToMap(modalComponentNode)\n    Object.keys(needAddNode).forEach((key) => {\n      const node = needAddNode[key]\n      if (node.props) {\n        node.props = getNewWidgetPropsByUpdateSlice(node.props ?? {}, {})\n      }\n      state[key] = node\n    })\n    state[modalSectionNodeDisplayName].childrenNode.push(\n      modalComponentNode.displayName,\n    )\n  }\n}\n\nexport const deleteComponentNodeReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<DeleteComponentNodePayload>\n> = (state, action) => {\n  const { displayNames } = action.payload\n  if (state == null) {\n    return\n  }\n  const rootNode = state\n  const tempTargetNode = searchComponentFromMap(rootNode, displayNames[0])\n  if (!tempTargetNode) return\n  const parentNodeDisplayName = tempTargetNode.parentNode\n  const parentNode = searchComponentFromMap(rootNode, parentNodeDisplayName)\n  if (!parentNode || !Array.isArray(parentNode.childrenNode)) return\n  let needRemoveDisplayName: string[] = []\n  const newChildrenNode = parentNode.childrenNode.filter((childDisplayName) => {\n    if (displayNames.includes(childDisplayName)) {\n      const removedDisplayNames = removeDisplayNames(\n        state[childDisplayName],\n        state,\n      )\n      needRemoveDisplayName.push(...removedDisplayNames)\n      return false\n    }\n    return true\n  })\n  parentNode.childrenNode = newChildrenNode\n  DisplayNameGenerator.removeDisplayNameMulti(needRemoveDisplayName)\n}\n\nexport const deletePageNodeReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<DeletePageNodePayload>\n> = (state, action) => {\n  const { displayName } = action.payload\n  if (state == null) {\n    return\n  }\n  const rootNode = state.root\n\n  const searchNode = searchComponentFromMap(state, displayName)\n  if (!searchNode) return\n  const parentNode = rootNode\n  const childrenNodes = parentNode.childrenNode\n  const currentIndex = childrenNodes.findIndex((value) => {\n    return value === searchNode.displayName\n  })\n  if (currentIndex === -1) return\n  const indexOfSortedKey = parentNode.props?.pageSortedKey.findIndex(\n    (key: string) => key === displayName,\n  )\n  if (indexOfSortedKey === -1) return\n  const targetNode = childrenNodes[currentIndex]\n  const needDeleteDisplayNames = removeDisplayNames(state[targetNode], state)\n  DisplayNameGenerator.removeDisplayNameMulti(needDeleteDisplayNames)\n  childrenNodes.splice(currentIndex, 1)\n  parentNode.props!.pageSortedKey.splice(indexOfSortedKey, 1)\n}\n\nexport const sortComponentNodeChildrenReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<SortComponentNodeChildrenPayload>\n> = (state, action) => {\n  const { parentDisplayName, newChildrenNode } = action.payload\n  const parentNode = searchComponentFromMap(state, parentDisplayName)\n  if (!parentNode) return\n\n  parentNode.childrenNode = newChildrenNode\n}\n\nexport const updateComponentPropsReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateComponentPropsPayload>\n> = (state, action) => {\n  const { displayName, updateSlice } = action.payload\n  if (!isObject(updateSlice) || !displayName) {\n    return\n  }\n  const node = searchComponentFromMap(state, displayName)\n  if (!node) return\n  const widgetProps = node.props || {}\n  const clonedWidgetProps = klona(widgetProps)\n  node.props = getNewWidgetPropsByUpdateSlice(updateSlice, clonedWidgetProps)\n}\n\nexport const setComponentPropsReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateComponentPropsPayload>\n> = (state, action) => {\n  const { displayName, updateSlice } = action.payload\n  if (!isObject(updateSlice) || !displayName) {\n    return\n  }\n  const node = searchComponentFromMap(state, displayName)\n  if (!node) return\n  node.props = getNewWidgetPropsByUpdateSlice(updateSlice, {})\n}\n\nexport const updateMultiComponentPropsReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateComponentPropsPayload[]>\n> = (state, action) => {\n  action.payload.forEach(({ displayName, updateSlice }) => {\n    if (!isObject(updateSlice) || !displayName) {\n      return\n    }\n    const node = searchComponentFromMap(state, displayName)\n    if (!node) return\n    const widgetProps = node.props || {}\n    const clonedWidgetProps = klona(widgetProps)\n    node.props = getNewWidgetPropsByUpdateSlice(updateSlice, clonedWidgetProps)\n  })\n}\n\nexport const batchUpdateMultiComponentSlicePropsReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateComponentSlicePropsPayload[]>\n> = (state, action) => {\n  action.payload.forEach(({ displayName, propsSlice }) => {\n    if (!isObject(propsSlice) || !displayName) {\n      return\n    }\n    const node = searchComponentFromMap(state, displayName)\n    if (!node) return\n    const widgetProps = node.props || {}\n    const clonedWidgetProps = klona(widgetProps)\n    Object.keys(propsSlice).forEach((path) => {\n      const newValue = propsSlice[path]\n      set(clonedWidgetProps, path, newValue)\n    })\n    node.props = clonedWidgetProps\n  })\n}\n\nexport const updateComponentDisplayNameReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateComponentDisplayNamePayload>\n> = (state, action) => {\n  const { displayName, newDisplayName } = action.payload\n  DisplayNameGenerator.removeDisplayName(displayName)\n  DisplayNameGenerator.addDisplayNames([newDisplayName])\n  if (!newDisplayName || !displayName) {\n    return\n  }\n  const node = searchComponentFromMap(state, displayName)\n  if (!node) return\n  delete state[displayName]\n  node.displayName = newDisplayName\n  state[newDisplayName] = node\n  if (Array.isArray(node.childrenNode)) {\n    node.childrenNode.forEach((child) => {\n      state[child].parentNode = newDisplayName\n    })\n  }\n  const parentNode = searchComponentFromMap(state, node.parentNode)\n  if (parentNode && parentNode.props) {\n    parentNode.childrenNode = parentNode.childrenNode.map((child) => {\n      if (child === displayName) {\n        return newDisplayName\n      }\n      return child\n    })\n    if (Array.isArray(parentNode.props.pageSortedKey)) {\n      const indexOfOldDisplayName = parentNode.props.pageSortedKey.findIndex(\n        (originDisplayName) => originDisplayName === displayName,\n      )\n      if (indexOfOldDisplayName !== -1) {\n        parentNode.props.pageSortedKey.splice(\n          indexOfOldDisplayName,\n          1,\n          newDisplayName,\n        )\n      }\n    }\n    if (Array.isArray(parentNode.props.viewSortedKey)) {\n      const indexOfOldDisplayName = parentNode.props.viewSortedKey.findIndex(\n        (originDisplayName) => originDisplayName === displayName,\n      )\n      if (indexOfOldDisplayName !== -1) {\n        parentNode.props.pageSortedKey.splice(\n          indexOfOldDisplayName,\n          1,\n          newDisplayName,\n        )\n      }\n    }\n    if (parentNode.displayName === \"root\" && parentNode.props) {\n      if (parentNode.props.homepageDisplayName === displayName) {\n        parentNode.props.homepageDisplayName = newDisplayName\n      }\n      if (!parentNode.props.homepageDisplayName) {\n        parentNode.props.homepageDisplayName = parentNode.props.pageSortedKey[0]\n      }\n    }\n  }\n}\n\nconst scaleChildrenNodeHelper = (\n  state: ComponentsState,\n  displayName: string,\n  columnNumberWhenDrag: number,\n  columnNumberWhenDrop: number,\n) => {\n  const targetNode = searchComponentFromMap(state, displayName)\n  if (!targetNode) return\n  if (Array.isArray(targetNode.childrenNode)) {\n    targetNode.childrenNode.forEach((nodeDisplayName) =>\n      scaleChildrenNodeHelper(\n        state,\n        nodeDisplayName,\n        columnNumberWhenDrag,\n        columnNumberWhenDrop,\n      ),\n    )\n  }\n  targetNode.w = Math.floor(\n    targetNode.w * (columnNumberWhenDrop / columnNumberWhenDrag),\n  )\n  targetNode.x = Math.floor(\n    targetNode.x * (columnNumberWhenDrop / columnNumberWhenDrag),\n  )\n}\n\nexport const updateComponentPositionReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateComponentPositionPayload>\n> = (state, action) => {\n  const {\n    oldParentNodeDisplayName,\n    newParentNodeDisplayName,\n    updateSlices,\n    columnNumberWhenDrag = 1,\n    columnNumberWhenDrop = 1,\n  } = action.payload\n\n  if (oldParentNodeDisplayName === newParentNodeDisplayName) {\n    updateSlices.forEach((slice) => {\n      const currentNode = searchComponentFromMap(state, slice.displayName)\n      if (!currentNode) return\n      currentNode.x = slice.x\n      currentNode.y = slice.y\n      currentNode.w = slice.w\n      currentNode.h = slice.h\n    })\n    return\n  }\n\n  updateSlices.forEach((slice) => {\n    // delete Old\n    const currentNode = searchComponentFromMap(state, slice.displayName)\n    if (!currentNode) return\n    const olaParentNode = searchComponentFromMap(\n      state,\n      oldParentNodeDisplayName,\n    )\n    if (!olaParentNode) return\n    const currentIndex = olaParentNode.childrenNode.findIndex(\n      (childDisplayName) => childDisplayName === currentNode.displayName,\n    )\n    if (currentIndex === -1) return\n    olaParentNode.childrenNode.splice(currentIndex, 1)\n    // add New\n    const newParentNode = searchComponentFromMap(\n      state,\n      newParentNodeDisplayName,\n    )\n    if (!newParentNode) return\n    currentNode.parentNode = newParentNodeDisplayName\n    currentNode.x = slice.x\n    currentNode.y = slice.y\n    currentNode.w = slice.w\n    currentNode.h = slice.h\n    if (Array.isArray(currentNode.childrenNode)) {\n      currentNode.childrenNode.forEach((childDisplayName) =>\n        scaleChildrenNodeHelper(\n          state,\n          childDisplayName,\n          columnNumberWhenDrag,\n          columnNumberWhenDrop,\n        ),\n      )\n    }\n    if (!Array.isArray(newParentNode.childrenNode)) {\n      newParentNode.childrenNode = [currentNode.displayName]\n    } else {\n      newParentNode.childrenNode.push(currentNode.displayName)\n    }\n  })\n}\n\nexport const updateComponentReflowReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateComponentReflowPayload[]>\n> = (state, action) => {\n  const payloadArray = action.payload\n  payloadArray.forEach((payload) => {\n    const { parentDisplayName, childNodes } = payload\n    const targetNode = searchComponentFromMap(state, parentDisplayName)\n    if (targetNode) {\n      childNodes.forEach((node) => {\n        state[node.displayName] = {\n          ...state[node.displayName],\n          w: node.w,\n          h: node.h,\n          x: node.x,\n          y: node.y,\n        }\n      })\n    }\n  })\n}\n\nexport const updateTargetPageLayoutReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateTargetPageLayoutPayload>\n> = (state, action) => {\n  if (!state) return state\n  const { pageName, layout, originPageNode } = action.payload\n  const rootNode = state.root\n  let targetPageNodeIndex = rootNode.childrenNode.findIndex(\n    (nodeDisplayName) => nodeDisplayName === pageName,\n  )\n  if (layout !== \"Custom\") {\n    const config = layoutValueMapGenerateConfig[layout]\n\n    if (targetPageNodeIndex === -1) return state\n    const targetPageNode = rootNode.childrenNode[targetPageNodeIndex]\n    if (!targetPageNode) return state\n    const needRemoveDisplayName = removeDisplayNames(\n      state[targetPageNode],\n      state,\n    )\n    const pageConfig = config(targetPageNode)\n    const needAddNode = originPageNode ?? pageConfig\n\n    DisplayNameGenerator.removeDisplayNameMulti(needRemoveDisplayName)\n    rootNode.childrenNode.splice(\n      targetPageNodeIndex,\n      1,\n      needAddNode.displayName,\n    )\n    const needAddMapNode = flatTreeToMap(needAddNode)\n    Object.keys(needAddMapNode).forEach((displayName) => {\n      state[displayName] = needAddMapNode[displayName]\n    })\n  } else {\n    const needAddMapNode = flatTreeToMap(originPageNode!)\n    Object.keys(needAddMapNode).forEach((displayName) => {\n      state[displayName] = needAddMapNode[displayName]\n    })\n    rootNode.childrenNode.splice(\n      targetPageNodeIndex,\n      1,\n      originPageNode!.displayName,\n    )\n  }\n}\n\nexport const updateTargetPagePropsReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateTargetPagePropsPayload>\n> = (state, action) => {\n  const rootNode = state.root\n  if (!rootNode?.props) return state\n  const { pageName, newProps } = action.payload\n  const currentPage = rootNode.childrenNode.find(\n    (childDisplayName) => childDisplayName === pageName,\n  )\n  if (!currentPage) return state\n  state[currentPage].props = {\n    ...state[currentPage].props,\n    ...newProps,\n  }\n}\n\nconst generationPageOptionsWhenDelete = (\n  deletedSectionName:\n    | \"leftSection\"\n    | \"rightSection\"\n    | \"headerSection\"\n    | \"footerSection\",\n) => {\n  switch (deletedSectionName) {\n    case \"leftSection\": {\n      return {\n        hasLeft: false,\n        leftWidth: 0,\n        leftPosition: \"NONE\",\n        layout: \"Custom\",\n      }\n    }\n    case \"rightSection\": {\n      return {\n        hasRight: false,\n        rightWidth: 0,\n        rightPosition: \"NONE\",\n        layout: \"Custom\",\n      }\n    }\n    case \"headerSection\": {\n      return {\n        hasHeader: false,\n        topHeight: 0,\n        layout: \"Custom\",\n      }\n    }\n    case \"footerSection\": {\n      return {\n        hasFooter: false,\n        bottomHeight: 0,\n        layout: \"Custom\",\n      }\n    }\n  }\n}\n\nexport const deleteTargetPageSectionReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<DeleteTargetPageSectionPayload>\n> = (state, action) => {\n  const rootNode = state.root\n  if (!rootNode?.childrenNode) return state\n  const { pageName, deleteSectionName } = action.payload\n  const targetPageIndex = rootNode.childrenNode.findIndex(\n    (childDisplayName) => childDisplayName === pageName,\n  )\n  if (targetPageIndex === -1) return state\n  const targetPage = state[rootNode.childrenNode[targetPageIndex]]\n\n  targetPage.props = {\n    ...targetPage.props,\n    ...generationPageOptionsWhenDelete(deleteSectionName),\n  }\n\n  const targetPageChildrenNodeIndex = targetPage.childrenNode.findIndex(\n    (childDisplayName) => childDisplayName === deleteSectionName,\n  )\n  if (targetPageChildrenNodeIndex === -1) return state\n  const targetPageChildeNode =\n    targetPage.childrenNode[targetPageChildrenNodeIndex]\n  const needDeleteDisplayNames = removeDisplayNames(\n    state[targetPageChildeNode],\n    state,\n  )\n  DisplayNameGenerator.removeDisplayNameMulti(needDeleteDisplayNames)\n  targetPage.childrenNode.splice(targetPageChildrenNodeIndex, 1)\n  rootNode.childrenNode.splice(targetPageIndex, 1, targetPage.displayName)\n}\n\nconst generationPageOptionsWhenAdd = (\n  deletedSectionName:\n    | \"leftSection\"\n    | \"rightSection\"\n    | \"headerSection\"\n    | \"footerSection\",\n) => {\n  switch (deletedSectionName) {\n    case \"leftSection\": {\n      return {\n        hasLeft: true,\n        leftWidth: 20,\n        leftPosition: \"FULL\",\n        layout: \"Custom\",\n      }\n    }\n    case \"rightSection\": {\n      return {\n        hasRight: true,\n        rightWidth: 20,\n        rightPosition: \"FULL\",\n        layout: \"Custom\",\n      }\n    }\n    case \"headerSection\": {\n      return {\n        hasHeader: true,\n        topHeight: 96,\n        layout: \"Custom\",\n      }\n    }\n    case \"footerSection\": {\n      return {\n        hasFooter: true,\n        bottomHeight: 96,\n        layout: \"Custom\",\n      }\n    }\n  }\n}\n\nexport const addTargetPageSectionReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<AddTargetPageSectionPayload>\n> = (state, action) => {\n  const rootNode = state.root\n  if (!rootNode?.childrenNode) return state\n  const { pageName, addedSectionName, originSectionNode } = action.payload\n  const targetPageIndex = rootNode.childrenNode.findIndex(\n    (childDisplayName) => childDisplayName === pageName,\n  )\n  if (targetPageIndex === -1) return state\n  const targetPage = state[rootNode.childrenNode[targetPageIndex]]\n\n  targetPage.props = {\n    ...targetPage.props,\n    ...generationPageOptionsWhenAdd(addedSectionName),\n  }\n\n  if (originSectionNode) {\n    const newOriginSectionNode = klona(originSectionNode)\n    newOriginSectionNode.parentNode = targetPage.displayName\n    targetPage.childrenNode.push(newOriginSectionNode.displayName)\n    const needAddMapNode = flatTreeToMap(newOriginSectionNode)\n    Object.keys(needAddMapNode).forEach((displayName) => {\n      state[displayName] = needAddMapNode[displayName]\n    })\n  } else {\n    let bodySectionSubPaths: string[] = []\n    const bodySectionNode = targetPage.childrenNode.find(\n      (childDisplayName) => childDisplayName === \"bodySection\",\n    )\n    if (bodySectionNode) {\n      bodySectionSubPaths =\n        state[bodySectionNode].props?.sectionViewConfigs.map(\n          (config: Record<string, string>) => config.path,\n        ) ?? []\n    }\n    if (bodySectionSubPaths.length === 0) {\n      bodySectionSubPaths = [\"sub-page1\"]\n    }\n    const config = generateSectionConfig(\n      pageName,\n      addedSectionName,\n      bodySectionSubPaths,\n    )\n    if (!config) return state\n    targetPage.childrenNode.push(config.displayName)\n    const needAddMapNode = flatTreeToMap(config)\n    Object.keys(needAddMapNode).forEach((displayName) => {\n      state[displayName] = needAddMapNode[displayName]\n    })\n  }\n}\n\nexport const updateRootNodePropsReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<Partial<RootComponentNodeProps>>\n> = (state, action) => {\n  const rootNode = state.root\n  if (!rootNode) return state\n  if (!rootNode.props) {\n    rootNode.props = action.payload\n  } else {\n    rootNode.props = {\n      ...rootNode.props,\n      ...action.payload,\n    }\n  }\n}\n\nexport const addPageNodeWithSortOrderReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<ComponentTreeNode>\n> = (state, action) => {\n  const node = action.payload\n  const parentNode = searchComponentFromMap(\n    state,\n    node.parentNode,\n  ) as RootComponentNode | null\n  if (!parentNode) return\n  parentNode.props.pageSortedKey.push(node.displayName)\n  if (!Array.isArray(parentNode.childrenNode)) {\n    parentNode.childrenNode = [node.displayName]\n  } else {\n    parentNode.childrenNode.push(node.displayName)\n  }\n  const needAddMapNode = flatTreeToMap(node)\n  Object.keys(needAddMapNode).forEach((displayName) => {\n    state[displayName] = needAddMapNode[displayName]\n  })\n}\n\nexport const addSectionViewHelper = (\n  sectionViewNodeConfig: ComponentTreeNode,\n  sectionViewConfig: SectionViewShape,\n  sectionNode: ComponentMapNode,\n  originChildrenNode?: ComponentTreeNode[],\n) => {\n  if (originChildrenNode && Array.isArray(originChildrenNode)) {\n    let cloneDeepChildrenNode = JSON.parse(\n      JSON.stringify(originChildrenNode),\n    ) as ComponentTreeNode[]\n    cloneDeepChildrenNode = cloneDeepChildrenNode.map((node) => ({\n      ...node,\n      parentNode: sectionViewNodeConfig.displayName,\n    }))\n    sectionViewNodeConfig.childrenNode = cloneDeepChildrenNode\n  }\n  if (Array.isArray(sectionNode.childrenNode)) {\n    sectionNode.childrenNode.push(sectionViewNodeConfig.displayName)\n  } else {\n    sectionNode.childrenNode = [sectionViewNodeConfig.displayName]\n  }\n  sectionNode.props!.viewSortedKey.push(sectionViewNodeConfig.displayName)\n  sectionNode.props!.sectionViewConfigs.push(sectionViewConfig)\n}\n\nexport const addSectionViewReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<AddSectionViewPayload>\n> = (state, action) => {\n  const { parentNodeName, sectionName, originChildrenNode } = action.payload\n\n  const parentNode = searchComponentFromMap(state, parentNodeName)\n  if (!parentNode || !parentNode.props) return\n  let bodySectionSubPaths: string[] = []\n  if (sectionName !== \"bodySection\") {\n    const pageNode = searchComponentFromMap(state, parentNode.parentNode)\n    if (!pageNode) return\n    const bodySectionNodeDisplayName = pageNode.childrenNode.find(\n      (childDisplayName) => childDisplayName === \"bodySection\",\n    )\n    if (!bodySectionNodeDisplayName) return\n    bodySectionSubPaths =\n      state[bodySectionNodeDisplayName].props?.sectionViewConfigs.map(\n        (config: Record<string, string>) => config.path,\n      ) ?? []\n  }\n\n  const config = generateSectionContainerConfig(\n    parentNodeName,\n    `${sectionName}Container`,\n  )\n  const hasPaths = parentNode.props.sectionViewConfigs.map(\n    (item: SectionViewShape) => item.path,\n  )\n  const diffSubPaths = difference(bodySectionSubPaths, hasPaths)\n\n  const newSectionViewConfig = generateNewViewItemFromBodySectionConfig(\n    hasPaths,\n    config.displayName,\n    parentNodeName,\n    diffSubPaths,\n  )\n  addSectionViewHelper(\n    config,\n    newSectionViewConfig,\n    parentNode,\n    originChildrenNode,\n  )\n  const needAddMapNode = flatTreeToMap(config)\n  Object.keys(needAddMapNode).forEach((displayName) => {\n    state[displayName] = needAddMapNode[displayName]\n  })\n}\n\nexport const addSectionViewConfigByConfigReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<AddSectionViewByConfigPayload>\n> = (state, action) => {\n  const {\n    parentNodeName,\n    originChildrenNode,\n    sectionViewNode,\n    sectionViewConfig,\n  } = action.payload\n  const parentNode = searchComponentFromMap(state, parentNodeName)\n  if (!parentNode || !parentNode.props) return\n  addSectionViewHelper(\n    sectionViewNode,\n    sectionViewConfig,\n    parentNode,\n    originChildrenNode,\n  )\n  const needAddMapNode = flatTreeToMap(sectionViewNode)\n  Object.keys(needAddMapNode).forEach((displayName) => {\n    state[displayName] = needAddMapNode[displayName]\n  })\n}\n\nexport const updateSectionViewPropsReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateSectionViewPropsPayload>\n> = (state, action) => {\n  const { parentNodeName, newProps } = action.payload\n  const parentNode = searchComponentFromMap(state, parentNodeName)\n  if (!parentNode || !parentNode.props) return\n  parentNode.props = {\n    ...parentNode.props,\n    ...newProps,\n  }\n}\n\nexport const deleteSectionViewReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<DeleteSectionViewPayload>\n> = (state, action) => {\n  const { viewDisplayName } = action.payload\n  const currentNode = searchComponentFromMap(state, viewDisplayName)\n  if (!currentNode) return\n  const parentNode = searchComponentFromMap(state, currentNode.parentNode)\n  if (!parentNode || !parentNode.props) return\n  const currentIndex = parentNode.childrenNode.findIndex(\n    (childDisplayName) => childDisplayName === viewDisplayName,\n  )\n  if (currentIndex === -1) return\n  const viewSortedKeyIndex = parentNode.props.viewSortedKey.findIndex(\n    (key: string) => key === viewDisplayName,\n  )\n  if (viewSortedKeyIndex === -1) return\n  const sectionViewConfigsIndex = parentNode.props.sectionViewConfigs.findIndex(\n    (config: SectionViewShape) => config.viewDisplayName === viewDisplayName,\n  )\n  if (sectionViewConfigsIndex === -1) return\n  const targetNode = parentNode.childrenNode[currentIndex]\n  if (!targetNode) return\n  const needDeleteDisplayNames = removeDisplayNames(state[targetNode], state)\n  DisplayNameGenerator.removeDisplayNameMulti(needDeleteDisplayNames)\n  parentNode.childrenNode.splice(currentIndex, 1)\n  parentNode.props.viewSortedKey.splice(viewSortedKeyIndex, 1)\n  parentNode.props.sectionViewConfigs.splice(sectionViewConfigsIndex, 1)\n}\n\nexport const updateViewportSizeReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<{\n    viewportWidth?: number\n    viewportHeight?: number\n    viewportSizeType?: ViewportSizeType\n  }>\n> = (state, action) => {\n  const rootNode = state.root\n  if (!rootNode) return\n  if (!rootNode.props) rootNode.props = {}\n  rootNode.props.viewportWidth = action.payload.viewportWidth\n  rootNode.props.viewportHeight = action.payload.viewportHeight\n  rootNode.props.viewportSizeType = action.payload.viewportSizeType\n}\n\nexport const resetComponentsReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction\n> = () => {\n  return ComponentsInitialState\n}\n\nconst updateComponentLayoutInfoHelper = (\n  state: ComponentsState,\n  displayName: string,\n  layoutInfo: Partial<LayoutInfo>,\n) => {\n  let currentNode = searchComponentFromMap(state, displayName)\n  if (!currentNode || !layoutInfo || Object.keys(layoutInfo).length === 0)\n    return\n  ;(Object.keys(layoutInfo) as Partial<Array<keyof LayoutInfo>>).forEach(\n    (key) => {\n      currentNode![key as keyof LayoutInfo] = layoutInfo[\n        key as keyof LayoutInfo\n      ] as number\n    },\n  )\n}\n\nexport const updateComponentNodeHeightReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateComponentNodeHeightPayload>\n> = (state, action) => {\n  if (!state) return\n  const { displayName, height } = action.payload\n  const currentNode = searchComponentFromMap(state, displayName)\n  if (!currentNode) return\n  currentNode.h = Math.max(height, currentNode.minH)\n}\n\nexport const updateComponentLayoutInfoReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateComponentNodeLayoutInfoPayload>\n> = (state, action) => {\n  if (!state) return\n  const { displayName, layoutInfo } = action.payload\n  updateComponentLayoutInfoHelper(state, displayName, layoutInfo)\n}\n\nexport const batchUpdateComponentLayoutInfoWhenReflowReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<BatchUpdateComponentNodeLayoutInfoPayload[]>\n> = (state, action) => {\n  if (!state) return\n  action.payload.forEach((updateSlice) => {\n    const { displayName, layoutInfo } = updateSlice\n    updateComponentLayoutInfoHelper(state, displayName, layoutInfo)\n  })\n}\n\nexport const batchUpdateComponentLayoutInfoReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateComponentNodeLayoutInfoPayload[]>\n> = (state, action) => {\n  if (!state) return\n  action.payload.forEach((updateSlice) => {\n    const { displayName, layoutInfo } = updateSlice\n    updateComponentLayoutInfoHelper(state, displayName, layoutInfo)\n  })\n}\n\nexport const setGlobalStateReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<SetGlobalStatePayload>\n> = (state, action) => {\n  const rootNode = state.root\n  if (!state || !rootNode) return\n  const { value, key, oldKey } = action.payload\n  const originGlobalData = rootNode.props?.globalData || {}\n  if (oldKey && originGlobalData.hasOwnProperty(oldKey)) {\n    delete originGlobalData[oldKey]\n  }\n  const newProps = {\n    ...rootNode.props,\n    globalData: {\n      ...originGlobalData,\n      [key]: value,\n    },\n  }\n  rootNode.props = getNewWidgetPropsByUpdateSlice(\n    newProps ?? {},\n    rootNode.props ?? {},\n  )\n}\n\nexport const deleteGlobalStateByKeyReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<DeleteGlobalStatePayload>\n> = (state, action) => {\n  const rootNode = state.root\n  if (!rootNode || !rootNode.props) return\n  const { key } = action.payload\n  const originGlobalData = rootNode.props?.globalData || {}\n  if (\n    (Object.hasOwn && Object.hasOwn(originGlobalData, key)) ||\n    Object.prototype.hasOwnProperty.call(originGlobalData, key)\n  )\n    delete originGlobalData[key]\n}\n\nexport const getNeedDeleteSectionViewDisplayNames = (\n  components: ComponentsState,\n  pageName: string,\n  subPagePath: string,\n) => {\n  const pageNode = searchComponentFromMap(components, pageName)\n  if (!pageNode) return []\n  const sectionNodeDisplayNames = pageNode.childrenNode.filter(\n    (displayName) => components[displayName].type !== \"MODAL_SECTION_NODE\",\n  )\n  let needDeleteDisplayNames: string[] = []\n  sectionNodeDisplayNames.forEach((sectionNode) => {\n    const sectionViewConfigs =\n      components[sectionNode].props?.sectionViewConfigs ?? []\n    const targetSectionViewConfig = sectionViewConfigs.filter(\n      (config: Record<string, string>) => config.path === subPagePath,\n    )\n    const currentNeedDeleteDisplayNames = targetSectionViewConfig.map(\n      (config: Record<string, string>) => config.viewDisplayName,\n    )\n    needDeleteDisplayNames.push(...currentNeedDeleteDisplayNames)\n  })\n  return needDeleteDisplayNames\n}\n\nexport const deleteSubPageViewNodeReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<DeleteSubPageViewNodePayload>\n> = (state, action) => {\n  const { pageName, subPagePath } = action.payload\n  const rootNode = state.root\n  if (!state || !rootNode) return\n  const needDeleteSectionDisplayNames = getNeedDeleteSectionViewDisplayNames(\n    state,\n    pageName,\n    subPagePath,\n  )\n\n  needDeleteSectionDisplayNames.forEach((displayName) => {\n    const targetComponentNode = searchComponentFromMap(state, displayName)\n    if (!targetComponentNode) return\n    const parentNode = searchComponentFromMap(\n      state,\n      targetComponentNode.parentNode,\n    )\n    if (!parentNode) return\n    parentNode.childrenNode = parentNode.childrenNode.filter(\n      (childDisplayName) => childDisplayName !== displayName,\n    )\n    parentNode.props!.viewSortedKey = parentNode.props?.viewSortedKey.filter(\n      (key: string) => key !== displayName,\n    )\n    parentNode.props!.sectionViewConfigs =\n      parentNode.props?.sectionViewConfigs.filter(\n        (config: Record<string, string>) =>\n          config.viewDisplayName !== displayName,\n      )\n  })\n  needDeleteSectionDisplayNames.flatMap((displayName) =>\n    removeDisplayNames(state[displayName], state),\n  )\n  DisplayNameGenerator.removeDisplayNameMulti(needDeleteSectionDisplayNames)\n}\n\nexport const updateSubPagePathReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<{\n    pageName: string\n    subPagePath: string\n    oldSubPagePath: string\n  }>\n> = (state, action) => {\n  const { pageName, subPagePath, oldSubPagePath } = action.payload\n  const pageNode = searchComponentFromMap(state, pageName)\n  if (!pageNode) return\n  const sectionNodes = pageNode.childrenNode.filter(\n    (displayName) => state[displayName].type !== \"MODAL_SECTION_NODE\",\n  )\n  sectionNodes.forEach((sectionNode) => {\n    state[sectionNode].props?.sectionViewConfigs.forEach(\n      (config: Record<string, string>) => {\n        if (config.path === oldSubPagePath) {\n          config.path = subPagePath\n        }\n      },\n    )\n  })\n}\n\nexport const updateDefaultSubPagePathReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<{\n    pageName: string\n    subPagePath: string\n  }>\n> = (state, action) => {\n  const { pageName, subPagePath } = action.payload\n  const pageNode = searchComponentFromMap(state, pageName)\n  if (!pageNode) return\n  const sectionNodeDisplayNames = pageNode.childrenNode.filter(\n    (sectionNodeDisplayName) =>\n      state[sectionNodeDisplayName].type !== \"MODAL_SECTION_NODE\",\n  )\n  sectionNodeDisplayNames.forEach((displayName) => {\n    state[displayName].props!.defaultViewKey = subPagePath\n  })\n}\n\nexport const addSubPageReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<{ pageName: string }>\n> = (state, action) => {\n  if (!state) return\n  const pageNode = searchComponentFromMap(state, action.payload.pageName)\n  if (!pageNode) return\n  const bodySectionDisplayName = pageNode.childrenNode.find(\n    (sectionDisplayName) => {\n      return state[sectionDisplayName].showName === \"bodySection\"\n    },\n  )\n  if (!bodySectionDisplayName) {\n    return\n  }\n  const bodySectionNode = state[bodySectionDisplayName]\n  if (!bodySectionNode) return\n  const bodySectionConfig = generateSectionContainerConfig(\n    bodySectionDisplayName,\n    `bodySectionContainer`,\n  )\n\n  const hasKeys = bodySectionNode.props!.sectionViewConfigs.map(\n    (item: SectionViewShape) => {\n      return `${bodySectionDisplayName}-${item.path}`\n    },\n  )\n  const newSectionViewConfig = generateNewViewItem(\n    hasKeys,\n    bodySectionConfig.displayName,\n    bodySectionDisplayName,\n  )\n  if (Array.isArray(bodySectionNode.childrenNode)) {\n    bodySectionNode.childrenNode.push(bodySectionConfig.displayName)\n  } else {\n    bodySectionNode.childrenNode = [bodySectionConfig.displayName]\n  }\n  const needAddMapNode = flatTreeToMap(bodySectionConfig)\n  Object.keys(needAddMapNode).forEach((displayName) => {\n    state[displayName] = needAddMapNode[displayName]\n  })\n  bodySectionNode.props!.viewSortedKey.push(bodySectionConfig.displayName)\n  bodySectionNode.props!.sectionViewConfigs.push(newSectionViewConfig)\n}\n\nexport const updateCurrentPageStyleReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<UpdateCurrentPageStylePayload>\n> = (state, action) => {\n  const pageNode = searchComponentFromMap(state, action.payload.pageName)\n  if (!pageNode || !Array.isArray(pageNode.childrenNode)) return\n  const targetSectionNodeDisplayName = pageNode.childrenNode.find(\n    (childDisplayName) => {\n      return state[childDisplayName].showName === action.payload.sectionName\n    },\n  )\n  if (!targetSectionNodeDisplayName) return\n  const targetSectionNode = state[targetSectionNodeDisplayName]\n  if (!targetSectionNode.props) return\n  if (!targetSectionNode.props.style) {\n    targetSectionNode.props.style = action.payload.style\n  } else {\n    Object.keys(action.payload.style).forEach((key) => {\n      if (action.payload.style[key] === undefined) {\n        unset(targetSectionNode.props?.style ?? {}, key)\n      }\n      targetSectionNode.props!.style[key] = action.payload.style[key]\n    })\n  }\n}\n\nexport const deleteCurrentPageStyleReducer: CaseReducer<\n  ComponentsState,\n  PayloadAction<DeleteCurrentPageStylePayload>\n> = (state, action) => {\n  const pageNode = searchComponentFromMap(state, action.payload.pageName)\n  if (!pageNode || !Array.isArray(pageNode.childrenNode)) return\n  const targetSectionNodeDisplayName = pageNode.childrenNode.find(\n    (childDisplayName) => {\n      return state[childDisplayName].showName === action.payload.sectionName\n    },\n  )\n  if (\n    !targetSectionNodeDisplayName ||\n    !state[targetSectionNodeDisplayName].props\n  )\n    return\n  unset(\n    state[targetSectionNodeDisplayName].props?.style ?? {},\n    action.payload.styleKey,\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/components/componentsSelector.ts",
    "content": "import {\n  ActionItem,\n  ComponentMapNode,\n  ComponentTreeNode,\n  GlobalDataActionContent,\n} from \"@illa-public/public-types\"\nimport { createSelector } from \"@reduxjs/toolkit\"\nimport { get, set } from \"lodash-es\"\nimport { DEFAULT_MIN_COLUMN } from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { getSelectedComponentDisplayNames } from \"@/redux/config/configSelector\"\nimport store, { RootState } from \"@/store\"\nimport { WidgetLayoutInfo } from \"../layoutInfo/layoutInfoState\"\nimport { ComponentsState } from \"./componentsState\"\n\nexport function searchDSLByDisplayName(\n  displayName: string,\n  rootState: RootState = store.getState(),\n) {\n  const components = getComponentMap(rootState)\n  return components[displayName]\n}\n\nexport function searchComponentFromMap(\n  components: Record<string, ComponentMapNode>,\n  findDisplayName: string | null,\n) {\n  if (components == null || findDisplayName == null) {\n    return null\n  }\n  return components[findDisplayName]\n}\n\nexport function searchDSLFromTree(\n  componentTree: ComponentTreeNode,\n  findDisplayName: string,\n) {\n  const queue = [componentTree]\n  while (queue.length > 0) {\n    const head = queue[0]\n    if (head.displayName === findDisplayName) {\n      return head\n    }\n    queue.shift()\n    if (head.childrenNode) {\n      head.childrenNode.forEach((child) => {\n        queue.push(child)\n      })\n    }\n  }\n}\n\nexport function filterContainerNode(components: ComponentsState): {\n  [key: string]: ComponentMapNode\n} {\n  let res = {}\n  Object.keys(components).forEach((key) => {\n    if (components[key].type !== \"CONTAINER_NODE\") {\n      res = { ...res, [key]: components[key] }\n    }\n  })\n\n  return res\n}\n\nexport function flattenDslToArray(componentNodes: ComponentsState) {\n  let res: ComponentMapNode[] = []\n  Object.keys(componentNodes).forEach((key) => {\n    if (componentNodes[key].containerType !== \"EDITOR_DOT_PANEL\") {\n      res.push(componentNodes[key])\n    }\n  })\n\n  return res\n}\n\nexport const getComponentMap = (state: RootState) => {\n  return state.currentApp.components\n}\n\nexport const getRootComponentNode = createSelector(\n  [getComponentMap],\n  (components) => components.root,\n)\n\nexport const getComponentNodeBySingleSelected = createSelector(\n  [getComponentMap, getSelectedComponentDisplayNames],\n  (components, selectedComponentDisplayNames) => {\n    if (selectedComponentDisplayNames.length === 1) {\n      return components[selectedComponentDisplayNames[0]]\n    }\n    return null\n  },\n)\n\nconst getAllDescendantNodeDisplayNames = (\n  nodeDisplayName: string,\n  components: ComponentsState,\n) => {\n  const node = components[nodeDisplayName]\n  const queue = [node]\n  let res: string[] = []\n  while (queue.length > 0) {\n    const head = queue[queue.length - 1]\n    res.push(head.displayName)\n    queue.pop()\n    if (head.childrenNode) {\n      head.childrenNode.forEach((child) => {\n        if (components[child]) {\n          queue.push(components[child])\n        }\n      })\n    }\n  }\n  return res\n}\n\nexport const getCurrentAppPageNames = createSelector(\n  [getComponentMap],\n  (components) => {\n    const rootNodeProps = components.root.props\n    if (!components || !rootNodeProps || !rootNodeProps.pageSortedKey)\n      return [] as string[]\n    const pageDisplayNames = rootNodeProps.pageSortedKey as string[]\n    const passCheckedDisplayNames: string[] = []\n    pageDisplayNames.forEach((pageDisplayName) => {\n      const pageNode = components[pageDisplayName]\n      if (!pageNode || !Array.isArray(pageNode.childrenNode)) return\n      passCheckedDisplayNames.push(pageNode.displayName)\n    })\n    return passCheckedDisplayNames\n  },\n)\n\nexport const getPageNameMapDescendantNodeDisplayNames = createSelector(\n  [getComponentMap],\n  (components) => {\n    const rootNode = components.root\n    const rootNodeProps = rootNode?.props\n\n    if (!rootNode || !rootNodeProps || !rootNodeProps.pageSortedKey) return {}\n    const pageDisplayNames = rootNodeProps.pageSortedKey as string[]\n    const pageNameMapHasNodeDisplayNames: Record<string, string[]> = {}\n    pageDisplayNames.forEach((pageDisplayName) => {\n      const pageNode = components[pageDisplayName]\n      if (!pageNode || !Array.isArray(pageNode.childrenNode)) return\n      const descendantNodeDisplayNames = getAllDescendantNodeDisplayNames(\n        pageNode.displayName,\n        components,\n      )\n      pageNameMapHasNodeDisplayNames[pageDisplayName] =\n        descendantNodeDisplayNames\n    })\n    return pageNameMapHasNodeDisplayNames\n  },\n)\n\nexport const getAllComponentDisplayNameMapProps = createSelector(\n  [getComponentMap, getPageNameMapDescendantNodeDisplayNames],\n  (componentsMap, pageNameMapDescendantNodeDisplayNames) => {\n    if (componentsMap == null) {\n      return null\n    }\n    const reversePageNameMapDescendantNodeDisplayNames: Record<string, string> =\n      {}\n\n    Object.keys(pageNameMapDescendantNodeDisplayNames).forEach((pageName) => {\n      pageNameMapDescendantNodeDisplayNames[pageName].forEach((displayName) => {\n        reversePageNameMapDescendantNodeDisplayNames[displayName] = pageName\n      })\n    })\n\n    const filteredResult = filterContainerNode(componentsMap)\n    if (!filteredResult) return\n    const res: Record<string, any> = {}\n    Object.keys(filteredResult).forEach((key) => {\n      res[key] = {\n        ...filteredResult[key].props,\n        displayName: filteredResult[key].displayName,\n        $parentNode: filteredResult[key].parentNode,\n        $type: \"WIDGET\",\n        $widgetType: filteredResult[key].type,\n        $childrenNode: filteredResult[key].childrenNode,\n        $parentPageName: reversePageNameMapDescendantNodeDisplayNames[key],\n      }\n    })\n    return res\n  },\n)\n\nexport const getAllComponentDisplayNameMapLayoutInfo = createSelector(\n  [getComponentMap],\n  (components) => {\n    if (components == null) {\n      return null\n    }\n    const res: Record<string, WidgetLayoutInfo> = {}\n    Object.keys(components).forEach((key) => {\n      const {\n        displayName,\n        parentNode,\n        type,\n        containerType,\n        x,\n        y,\n        z,\n        w,\n        h,\n        minH,\n        childrenNode,\n      } = components[key]\n      res[key] = {\n        displayName: displayName,\n        parentNode: parentNode ?? \"\",\n        widgetType: type,\n        childrenNode: childrenNode,\n        containerType: containerType,\n        layoutInfo: {\n          x,\n          y,\n          z,\n          w,\n          h,\n          minW: DEFAULT_MIN_COLUMN,\n          minH,\n        },\n      }\n    })\n    return res\n  },\n)\n\nexport const getAllContainerWidget = createSelector(\n  [getComponentMap],\n  (components) => {\n    if (!components) return\n    const res: Record<string, any> = {}\n    Object.keys(components).forEach((key) => {\n      if (components[key].type === \"CONTAINER_WIDGET\") {\n        res[key] = {\n          ...components[key].props,\n          $type: \"WIDGET\",\n          $widgetType: components[key].type,\n        }\n      }\n    })\n    return res\n  },\n)\n\nexport const getFlattenArrayComponentNodes = createSelector(\n  [getComponentMap],\n  (components) => {\n    if (components == null) {\n      return null\n    }\n    return flattenDslToArray(components)\n  },\n)\n\nexport const getCurrentPageNode = createSelector(\n  [getComponentMap],\n  (components) => {\n    const rootDSL = components.root\n    if (rootDSL == null || !rootDSL.props) {\n      return null\n    }\n    const { currentPageIndex, pageSortedKey } = rootDSL.props\n    const currentPageDisplayName = pageSortedKey[currentPageIndex]\n    const currentPage = rootDSL.childrenNode.find(\n      (nodeDisplayName) => nodeDisplayName === currentPageDisplayName,\n    )\n    if (!currentPage) return null\n    return components[currentPage]\n  },\n)\n\nexport const getCurrentPageProps = createSelector(\n  [getCurrentPageNode],\n  (currentPageNode) => {\n    if (currentPageNode == null || !currentPageNode.props) {\n      return {}\n    }\n    return currentPageNode.props\n  },\n)\n\nexport const getCurrentPageDisplayName = createSelector(\n  [getCurrentPageNode],\n  (currentPageNode) => {\n    if (currentPageNode == null || !currentPageNode.props) {\n      return null\n    }\n    return currentPageNode.displayName\n  },\n)\n\nexport const getRootNodeProps = createSelector(\n  [getComponentMap],\n  (rootNode) => {\n    if (!rootNode)\n      return {\n        currentPageIndex: 0,\n        pageSortedKey: [\"page1\"],\n        homepageDisplayName: \"page1\",\n      }\n    return rootNode.props\n  },\n)\n\nexport const getContainerListWidget = createSelector(\n  [getFlattenArrayComponentNodes],\n  (componentNodes) => {\n    if (!Array.isArray(componentNodes)) {\n      return null\n    }\n\n    return componentNodes.filter((node) => {\n      return node.type === \"LIST_WIDGET\" || node.type === \"GRID_LIST_WIDGET\"\n    })\n  },\n)\n\nexport const getContainerListDisplayNameMappedChildrenNodeDisplayName =\n  createSelector(\n    [getContainerListWidget, getComponentMap],\n    (listNodes, components) => {\n      const displayNameMappedChildren: Record<string, string[]> = {}\n      if (!listNodes) return displayNameMappedChildren\n      const dfsWithListNode = (\n        containerNode: ComponentMapNode,\n        result: Record<string, string[]>,\n        listDisplayName: string,\n      ) => {\n        containerNode.childrenNode?.forEach((nodeDisplayName) => {\n          if (!Array.isArray(get(result, listDisplayName))) {\n            set(result, listDisplayName, [])\n          }\n          result[listDisplayName].push(nodeDisplayName)\n          dfsWithListNode(components[nodeDisplayName], result, listDisplayName)\n        })\n      }\n      listNodes.forEach((node) => {\n        const containerNodeDisplayName = node.childrenNode[0]\n        if (!Array.isArray(get(displayNameMappedChildren, node.displayName))) {\n          set(displayNameMappedChildren, node.displayName, [])\n        }\n\n        if (containerNodeDisplayName) {\n          displayNameMappedChildren[node.displayName].push(\n            containerNodeDisplayName,\n          )\n          dfsWithListNode(\n            components[containerNodeDisplayName],\n            displayNameMappedChildren,\n            node.displayName,\n          )\n        }\n      })\n\n      return displayNameMappedChildren\n    },\n  )\n\nexport const getViewportSizeSelector = createSelector(\n  [getRootComponentNode],\n  (rootComponentNode) => {\n    if (!rootComponentNode || !rootComponentNode.props)\n      return {\n        viewportWidth: undefined,\n        viewportHeight: undefined,\n        viewportSizeType: \"fluid\",\n      }\n    const { viewportWidth, viewportHeight, viewportSizeType } =\n      rootComponentNode.props\n    return {\n      viewportWidth: viewportWidth,\n      viewportHeight: viewportHeight,\n      viewportSizeType,\n    }\n  },\n)\n\nfunction getNodeDepths(tree: ComponentsState) {\n  const nodeDepths: Record<string, number> = {}\n  function traverse(node: ComponentMapNode, depth: number) {\n    nodeDepths[node.displayName] = depth\n    if (node.childrenNode) {\n      for (let i = 0; i < node.childrenNode.length; i++) {\n        traverse(tree[node.childrenNode[i]], depth + 1)\n      }\n    }\n  }\n  traverse(tree.root, 0)\n  return nodeDepths\n}\n\nexport const getComponentDisplayNameMapDepth = createSelector(\n  [getComponentMap],\n  (components) => {\n    if (!components) return {}\n    return getNodeDepths(components)\n  },\n)\n\nexport const getOriginalGlobalData = createSelector(\n  [getRootComponentNode],\n  (rootNode) => {\n    return (rootNode?.props?.globalData ?? {}) as Record<string, string>\n  },\n)\n\nexport const getOriginalGlobalDataNames = createSelector(\n  [getRootComponentNode],\n  (rootNode) => {\n    return Object.keys(rootNode?.props?.globalData ?? {})\n  },\n)\n\nexport const getGlobalDataToActionList = createSelector(\n  [getRootComponentNode],\n  (rootNode) => {\n    const globalData = (rootNode?.props?.globalData ?? {}) as Record<\n      string,\n      string\n    >\n\n    const result: ActionItem<GlobalDataActionContent>[] =\n      Object.keys(globalData)?.map((key) => {\n        return {\n          actionID: key,\n          displayName: key,\n          actionType: \"globalData\",\n          triggerMode: \"manually\",\n          isVirtualResource: true,\n          content: {\n            initialValue: globalData[key],\n          },\n          transformer: {\n            enable: false,\n            rawData: \"\",\n          },\n          config: {\n            public: false,\n          },\n        }\n      }) ?? []\n\n    return result\n  },\n)\n\nexport const getPageDisplayNameMapViewDisplayName = createSelector(\n  [getComponentMap],\n  (components) => {\n    const rootNode = components.root\n    if (!rootNode) return {}\n    const pageDisplayNameMapViewDisplayName: Record<string, Set<string>> = {}\n    const pageNodes = rootNode.childrenNode\n    pageNodes.forEach((pageNode) => {\n      pageDisplayNameMapViewDisplayName[pageNode] = new Set()\n      const sectionNodes = components[pageNode].childrenNode\n      sectionNodes.forEach((sectionNode) => {\n        const sectionConfigs =\n          components[sectionNode].props?.sectionViewConfigs ?? []\n        sectionConfigs.forEach((sectionConfig: Record<string, string>) => {\n          pageDisplayNameMapViewDisplayName[pageNode].add(sectionConfig.path)\n        })\n      })\n    })\n    return pageDisplayNameMapViewDisplayName\n  },\n)\n\nexport const getCurrentPageSortedKeys = createSelector(\n  [getRootComponentNode],\n  (rootNode) => {\n    if (!rootNode) return []\n    return rootNode.props?.pageSortedKey ?? []\n  },\n)\n\nexport const getWidgetCount = createSelector(\n  [getComponentMap],\n  (components) => {\n    let count = 0\n    Object.keys(components).forEach((key) => {\n      if (components[key].type.endsWith(\"_WIDGET\")) {\n        count++\n      }\n    })\n    return count\n  },\n)\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/components/componentsSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  addComponentReducer,\n  addModalComponentReducer,\n  addPageNodeWithSortOrderReducer,\n  addSectionViewConfigByConfigReducer,\n  addSectionViewReducer,\n  addSubPageReducer,\n  addTargetPageSectionReducer,\n  batchUpdateComponentLayoutInfoReducer,\n  batchUpdateComponentLayoutInfoWhenReflowReducer,\n  batchUpdateMultiComponentSlicePropsReducer,\n  deleteComponentNodeReducer,\n  deleteCurrentPageStyleReducer,\n  deleteGlobalStateByKeyReducer,\n  deletePageNodeReducer,\n  deleteSectionViewReducer,\n  deleteSubPageViewNodeReducer,\n  deleteTargetPageSectionReducer,\n  initComponentReducer,\n  resetComponentsReducer,\n  setComponentPropsReducer,\n  setGlobalStateReducer,\n  sortComponentNodeChildrenReducer,\n  updateComponentDisplayNameReducer,\n  updateComponentLayoutInfoReducer,\n  updateComponentNodeHeightReducer,\n  updateComponentPositionReducer,\n  updateComponentPropsReducer,\n  updateComponentReflowReducer,\n  updateCurrentPageStyleReducer,\n  updateDefaultSubPagePathReducer,\n  updateMultiComponentPropsReducer,\n  updateRootNodePropsReducer,\n  updateSectionViewPropsReducer,\n  updateSubPagePathReducer,\n  updateTargetPageLayoutReducer,\n  updateTargetPagePropsReducer,\n  updateViewportSizeReducer,\n} from \"@/redux/currentApp/components/componentsReducer\"\nimport { ComponentsInitialState } from \"@/redux/currentApp/components/componentsState\"\n\nconst componentsSlice = createSlice({\n  name: \"components\",\n  initialState: ComponentsInitialState,\n  reducers: {\n    updateComponentNodeHeightReducer,\n    addComponentReducer,\n    initComponentReducer,\n    updateComponentPropsReducer,\n    setComponentPropsReducer,\n    deleteComponentNodeReducer,\n    sortComponentNodeChildrenReducer,\n    updateComponentDisplayNameReducer,\n    updateComponentReflowReducer,\n    updateComponentPositionReducer,\n    updateMultiComponentPropsReducer,\n    updateTargetPageLayoutReducer,\n    updateTargetPagePropsReducer,\n    deleteTargetPageSectionReducer,\n    addTargetPageSectionReducer,\n    updateRootNodePropsReducer,\n    addPageNodeWithSortOrderReducer,\n    deletePageNodeReducer,\n    addSectionViewReducer,\n    addSectionViewConfigByConfigReducer,\n    deleteSectionViewReducer,\n    updateSectionViewPropsReducer,\n    updateViewportSizeReducer,\n    addModalComponentReducer,\n    resetComponentsReducer,\n    updateComponentLayoutInfoReducer,\n    batchUpdateComponentLayoutInfoWhenReflowReducer,\n    batchUpdateMultiComponentSlicePropsReducer,\n    batchUpdateComponentLayoutInfoReducer,\n    setGlobalStateReducer,\n    deleteGlobalStateByKeyReducer,\n    deleteSubPageViewNodeReducer,\n    updateSubPagePathReducer,\n    updateDefaultSubPagePathReducer,\n    addSubPageReducer,\n    updateCurrentPageStyleReducer,\n    deleteCurrentPageStyleReducer,\n  },\n})\n\nexport const componentsActions = componentsSlice.actions\nexport default componentsSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/components/componentsState.ts",
    "content": "import {\n  ComponentMapNode,\n  ComponentTreeNode,\n  SECTION_POSITION,\n  SectionViewShape,\n} from \"@illa-public/public-types\"\n\nexport type ViewportSizeType = \"fluid\" | \"desktop\" | \"tablet\" | \"custom\"\n\nexport interface RootComponentNodeProps {\n  currentPageIndex: number\n  pageSortedKey: string[]\n  homepageDisplayName?: string\n  viewportWidth?: number\n  viewportHeight?: number\n  viewportSizeType?: ViewportSizeType\n  currentSubPagePath?: string\n}\n\nexport interface RootComponentNode extends ComponentMapNode {\n  type: \"DOT_PANEL\"\n  props: RootComponentNodeProps\n}\n\nexport interface PageNodeProps {\n  canvasSize: \"auto\" | \"fixed\"\n  canvasWidth: number\n  layout: string\n  leftPosition: SECTION_POSITION\n  rightPosition: SECTION_POSITION\n  hasLeft: boolean\n  hasRight: boolean\n  hasHeader: boolean\n  hasFooter: boolean\n  isLeftFixed: boolean\n  isRightFixed: boolean\n  isHeaderFixed: boolean\n  isFooterFixed: boolean\n  leftWidth: number\n  rightWidth: number\n  topHeight: number\n  bottomHeight: number\n  showLeftFoldIcon: boolean\n  showRightFoldIcon: boolean\n  leftColumns?: number\n  rightColumns?: number\n  bodyColumns?: number\n  headerColumns?: number\n  footerColumns?: number\n}\n\nexport interface PageNode extends ComponentTreeNode {\n  type: \"PAGE_NODE\"\n  props: PageNodeProps\n}\n\nexport type ComponentsState = Record<string, ComponentMapNode>\nexport const ComponentsInitialState: ComponentsState = {}\n\nexport interface DeleteComponentNodePayload {\n  displayNames: string[]\n  source?: \"keyboard\" | \"manage_delete\" | \"left_delete\" | \"left_multi_delete\"\n}\n\nexport interface DeletePageNodePayload {\n  displayName: string\n  originPageSortedKey: string[]\n}\n\nexport interface SortComponentNodeChildrenPayload {\n  parentDisplayName: string\n  newChildrenNode: string[]\n}\n\nexport interface UpdateComponentPropsPayload {\n  displayName: string\n  updateSlice: Record<string, unknown>\n  notUseUndoRedo?: boolean\n}\n\nexport interface AddContainerComponentViewsReducerPayload {\n  displayName: string\n  containerDisplayName: string\n  linkedDisplayName?: string\n  addedViewItem: {\n    id: string\n    key: string\n    label: string\n    disabled?: string\n    hidden?: string\n  }[]\n  addComponent: ComponentTreeNode\n}\n\nexport interface DeleteContainerComponentViewsReducerPayload {\n  displayName: string\n  containerDisplayName: string\n  linkedDisplayName?: string\n  deletedIndex: number\n}\nexport interface UpdateComponentDisplayNamePayload {\n  displayName: string\n  newDisplayName: string\n}\n\nexport interface UpdateComponentReflowPayload {\n  parentDisplayName: string\n  childNodes: ComponentMapNode[]\n}\n\nexport interface UpdateTargetPageLayoutPayload {\n  pageName: string\n  layout:\n    | \"default\"\n    | \"presetA\"\n    | \"presetB\"\n    | \"presetC\"\n    | \"presetD\"\n    | \"presetE\"\n    | \"Custom\"\n  originPageNode?: ComponentTreeNode\n}\n\nexport interface UpdateTargetPagePropsPayload {\n  pageName: string\n  newProps: Partial<PageNodeProps>\n  options?: Record<string, unknown>\n  notUseUndoRedo?: boolean\n}\n\nexport interface DeleteTargetPageSectionPayload {\n  pageName: string\n  deleteSectionName:\n    | \"leftSection\"\n    | \"rightSection\"\n    | \"headerSection\"\n    | \"footerSection\"\n}\n\nexport interface AddTargetPageSectionPayload {\n  pageName: string\n  addedSectionName:\n    | \"leftSection\"\n    | \"rightSection\"\n    | \"headerSection\"\n    | \"footerSection\"\n  originSectionNode?: ComponentTreeNode\n}\n\nexport interface AddSectionViewPayload {\n  parentNodeName: string\n  sectionName:\n    | \"leftSection\"\n    | \"rightSection\"\n    | \"headerSection\"\n    | \"footerSection\"\n    | \"bodySection\"\n  originChildrenNode?: ComponentTreeNode[]\n}\n\nexport interface AddSectionViewByConfigPayload extends AddSectionViewPayload {\n  sectionViewNode: ComponentTreeNode\n  sectionViewConfig: SectionViewShape\n}\n\nexport interface DeleteSectionViewPayload {\n  viewDisplayName: string\n  parentNodeName: string\n  originPageSortedKey: string[]\n}\n\nexport interface UpdateSectionViewPropsPayload {\n  parentNodeName: string\n  newProps: Record<string, any>\n}\n\nexport interface AddModalComponentPayload {\n  currentPageDisplayName: string\n  modalComponentNode: ComponentTreeNode\n}\n\nexport interface UpdateComponentNodeHeightPayload {\n  displayName: string\n  height: number\n  oldHeight: number\n}\n\nexport interface SetGlobalStatePayload {\n  key: string\n  value: string\n  oldKey?: string\n}\n\nexport interface DeleteGlobalStatePayload {\n  key: string\n}\n\nexport interface DeleteSubPageViewNodePayload {\n  pageName: string\n  subPagePath: string\n}\n\nexport interface UpdateCurrentPageStylePayload {\n  pageName: string\n  style: Record<string, any>\n  sectionName:\n    | \"leftSection\"\n    | \"rightSection\"\n    | \"headerSection\"\n    | \"footerSection\"\n    | \"bodySection\"\n}\n\nexport interface DeleteCurrentPageStylePayload {\n  pageName: string\n  styleKey: string\n  sectionName:\n    | \"leftSection\"\n    | \"rightSection\"\n    | \"headerSection\"\n    | \"footerSection\"\n    | \"bodySection\"\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/cursor/cursorReducer.ts",
    "content": "import { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport {\n  CursorState,\n  UpdateCursorPayload,\n} from \"@/redux/currentApp/cursor/cursorState\"\n\nexport const updateCursorReducer: CaseReducer<\n  CursorState,\n  PayloadAction<UpdateCursorPayload>\n> = (state, action) => {\n  const { userID } = action.payload\n  const hasUser = !!state[userID]\n  if (!hasUser) {\n    state[userID] = []\n  }\n  if (state[userID].length === 1) {\n    state[userID].splice(0, 1, action.payload)\n  } else {\n    state[userID].push(action.payload)\n  }\n}\n\nexport const deleteCursorReducer: CaseReducer<\n  CursorState,\n  PayloadAction<string>\n> = (state, action) => {\n  const userID = action.payload\n  const hasUser = !!state[userID]\n  if (hasUser) {\n    delete state[userID]\n  }\n}\n\nexport const removeAnimationEndCursorInfo: CaseReducer<\n  CursorState,\n  PayloadAction<string>\n> = (state, action) => {\n  const targetUserCursorInfo = state[action.payload]\n  if (targetUserCursorInfo.length > 1) {\n    targetUserCursorInfo.shift()\n  }\n}\n\nexport const resetCursorReducer: CaseReducer<CursorState> = (state) => {\n  Object.keys(state).forEach((userID) => {\n    delete state[userID]\n  })\n}\n\nexport const filterCursorReducer: CaseReducer<\n  CursorState,\n  PayloadAction<string[]>\n> = (state, action) => {\n  action.payload.forEach((displayName) => {\n    Object.keys(state).forEach((userID) => {\n      const targetUserCursorInfo = state[userID]\n      if (\n        Array.isArray(targetUserCursorInfo) &&\n        targetUserCursorInfo.length > 0\n      ) {\n        state[userID] = targetUserCursorInfo.filter(\n          (cursorInfo) => cursorInfo.parentDisplayName !== displayName,\n        )\n      }\n    })\n  })\n}\n\nexport const leaveContainerReducer: CaseReducer<\n  CursorState,\n  PayloadAction<string>\n> = (state, action) => {\n  const targetUserCursorInfo = state[action.payload]\n\n  if (targetUserCursorInfo.length > 0) {\n    targetUserCursorInfo.shift()\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/cursor/cursorSelector.ts",
    "content": "import { createSelector } from \"@reduxjs/toolkit\"\nimport { RootState } from \"@/store\"\n\nexport const getCursor = (state: RootState) => {\n  return state.currentApp.cursor\n}\n\nexport const getCursorArray = createSelector([getCursor], (cursor) =>\n  Object.values(cursor),\n)\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/cursor/cursorSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  deleteCursorReducer,\n  filterCursorReducer,\n  leaveContainerReducer,\n  removeAnimationEndCursorInfo,\n  resetCursorReducer,\n  updateCursorReducer,\n} from \"./cursorReducer\"\nimport { CursorInitialState } from \"./cursorState\"\n\nconst cursorSlice = createSlice({\n  name: \"cursor\",\n  initialState: CursorInitialState,\n  reducers: {\n    updateCursorReducer,\n    deleteCursorReducer,\n    removeAnimationEndCursorInfo,\n    leaveContainerReducer,\n    resetCursorReducer,\n    filterCursorReducer,\n  },\n})\n\nexport const cursorActions = cursorSlice.actions\nexport default cursorSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/cursor/cursorState.ts",
    "content": "import { MovingMessageBin } from \"@/api/ws/ILLA_PROTO\"\n\nexport interface CursorInfo {\n  userID: MovingMessageBin[\"userID\"]\n  nickname: MovingMessageBin[\"nickname\"]\n  parentDisplayName: MovingMessageBin[\"parentDisplayName\"]\n  status: MovingMessageBin[\"status\"] // -1 is is Leave,1 is moving, 0 is empty\n  xInteger: MovingMessageBin[\"cursorXInteger\"]\n  yInteger: MovingMessageBin[\"cursorYInteger\"]\n  xMod: MovingMessageBin[\"cursorXMod\"]\n  yMod: MovingMessageBin[\"cursorYMod\"]\n  lastUpdateTime: number\n}\n\nexport type UpdateCursorPayload = CursorInfo\n\nexport type CursorState = Record<string, CursorInfo[]>\n\nexport const CursorInitialState: CursorState = {}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/dragShadow/dragShadowReducer.ts",
    "content": "import { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport { DragShadowState, UpdateCursorPayload } from \"./dragShadowState\"\n\nexport const updateDragShadowInfoReducer: CaseReducer<\n  DragShadowState,\n  PayloadAction<UpdateCursorPayload>\n> = (state, action) => {\n  const { userID } = action.payload\n  const hasUser = !!state[userID]\n  if (!hasUser) {\n    state[userID] = []\n  }\n  if (state[userID].length === 1) {\n    state[userID].splice(0, 1, action.payload)\n  } else {\n    state[userID].push(action.payload)\n  }\n}\n\nexport const deleteDragShadowInfoReducer: CaseReducer<\n  DragShadowState,\n  PayloadAction<string>\n> = (state, action) => {\n  const userID = action.payload\n  const hasUser = !!state[userID]\n  if (hasUser) {\n    delete state[userID]\n  }\n}\n\nexport const removeAnimationEndDragShadowInfoReducer: CaseReducer<\n  DragShadowState,\n  PayloadAction<string>\n> = (state, action) => {\n  const targetUserCursorInfo = state[action.payload]\n  if (targetUserCursorInfo.length > 1) {\n    targetUserCursorInfo.shift()\n  }\n}\n\nexport const resetDragShadowInfoReducer: CaseReducer<DragShadowState> = (\n  state,\n) => {\n  Object.keys(state).forEach((userID) => {\n    delete state[userID]\n  })\n}\n\nexport const filterDragShadowInfoReducer: CaseReducer<\n  DragShadowState,\n  PayloadAction<string[]>\n> = (state, action) => {\n  action.payload.forEach((displayName) => {\n    Object.keys(state).forEach((userID) => {\n      const targetUserCursorInfo = state[userID]\n      if (\n        Array.isArray(targetUserCursorInfo) &&\n        targetUserCursorInfo.length > 0\n      ) {\n        state[userID] = targetUserCursorInfo.filter(\n          (cursorInfo) => cursorInfo.parentDisplayName !== displayName,\n        )\n      }\n    })\n  })\n}\n\nexport const leaveContainerDragShadowInfoReducer: CaseReducer<\n  DragShadowState,\n  PayloadAction<string>\n> = (state, action) => {\n  const targetUserCursorInfo = state[action.payload]\n\n  if (targetUserCursorInfo.length > 0) {\n    targetUserCursorInfo.shift()\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/dragShadow/dragShadowSelector.ts",
    "content": "import { createSelector } from \"@reduxjs/toolkit\"\nimport { RootState } from \"@/store\"\n\nexport const getDragShadowInfo = (state: RootState) => {\n  return state.currentApp.dragShadow\n}\n\nexport const getDragShadowInfoArray = createSelector(\n  [getDragShadowInfo],\n  (cursor) => Object.values(cursor),\n)\n\nexport const getFirstDragShadowInfo = createSelector(\n  [getDragShadowInfo],\n  (dragShadows) => {\n    return Object.keys(dragShadows).map((userID) => {\n      if (dragShadows[userID].length > 0) {\n        return dragShadows[userID][0]\n      }\n    })\n  },\n)\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/dragShadow/dragShadowSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  deleteDragShadowInfoReducer,\n  filterDragShadowInfoReducer,\n  leaveContainerDragShadowInfoReducer,\n  removeAnimationEndDragShadowInfoReducer,\n  resetDragShadowInfoReducer,\n  updateDragShadowInfoReducer,\n} from \"./dragShadowReducer\"\nimport { DragShadowInitialState } from \"./dragShadowState\"\n\nconst dragShadowSlice = createSlice({\n  name: \"dragShadow\",\n  initialState: DragShadowInitialState,\n  reducers: {\n    updateDragShadowInfoReducer,\n    deleteDragShadowInfoReducer,\n    removeAnimationEndDragShadowInfoReducer,\n    leaveContainerDragShadowInfoReducer,\n    resetDragShadowInfoReducer,\n    filterDragShadowInfoReducer,\n  },\n})\n\nexport const dragShadowActions = dragShadowSlice.actions\nexport default dragShadowSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/dragShadow/dragShadowState.ts",
    "content": "import { MovingMessageBin } from \"@/api/ws/ILLA_PROTO\"\n\nexport interface DragShadowInfo {\n  userID: MovingMessageBin[\"userID\"]\n  nickname: MovingMessageBin[\"nickname\"]\n  parentDisplayName: MovingMessageBin[\"parentDisplayName\"]\n  displayNames: MovingMessageBin[\"displayNames\"]\n  status: MovingMessageBin[\"status\"] // 1 is Dragging move, 2 is resize,-1 is dragging end\n  xInteger: MovingMessageBin[\"cursorXInteger\"]\n  yInteger: MovingMessageBin[\"cursorYInteger\"]\n  xMod: MovingMessageBin[\"cursorXMod\"]\n  yMod: MovingMessageBin[\"cursorYMod\"]\n  rectX: MovingMessageBin[\"widgetX\"]\n  rectY: MovingMessageBin[\"widgetY\"]\n  rectW: MovingMessageBin[\"widgetW\"]\n  rectH: MovingMessageBin[\"widgetH\"]\n  lastUpdateTime: number\n}\n\nexport type UpdateCursorPayload = DragShadowInfo\n\nexport type DragShadowState = Record<string, DragShadowInfo[]>\n\nexport const DragShadowInitialState: DragShadowState = {}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/executionTree/executionListener.ts",
    "content": "import { UnknownAction, Unsubscribe, isAnyOf } from \"@reduxjs/toolkit\"\nimport { diff } from \"deep-diff\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport {\n  getExecutionResult,\n  getRawTree,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { AppListenerEffectAPI, AppStartListening } from \"@/store\"\nimport { ExecutionTreeFactory } from \"@/utils/executionTreeHelper/executionTreeFactory\"\n\nexport let executionTree: ExecutionTreeFactory | undefined\n\nexport const destroyExecutionTree = () => {\n  if (executionTree) {\n    executionTree = executionTree.destroyTree()\n  }\n}\n\nconst asyncExecutionDataToRedux = (\n  executionResult: Record<string, any>,\n  oldExecutionTree: Record<string, any>,\n  listenerApi: AppListenerEffectAPI,\n) => {\n  const errorTree = executionResult.errorTree\n  const evaluatedTree = executionResult.evaluatedTree\n  const dependencyMap = executionResult.dependencyTree\n  const independencyMap = executionResult.independencyTree\n  const updates = diff(oldExecutionTree, evaluatedTree) || []\n  listenerApi.dispatch(\n    executionActions.setExecutionResultReducer({\n      updates,\n    }),\n  )\n  listenerApi.dispatch(\n    executionActions.setDependenciesReducer({\n      ...dependencyMap,\n    }),\n  )\n  listenerApi.dispatch(\n    executionActions.setIndependenciesReducer({\n      ...independencyMap,\n    }),\n  )\n  listenerApi.dispatch(\n    executionActions.setExecutionErrorReducer({\n      ...errorTree,\n    }),\n  )\n}\n\nasync function handleStartExecution(\n  action: UnknownAction,\n  listenerApi: AppListenerEffectAPI,\n) {\n  const rootState = listenerApi.getState()\n  const rawTree = getRawTree(rootState)\n  if (!rawTree) return\n  const oldExecutionTree = getExecutionResult(rootState)\n  if (!executionTree) {\n    executionTree = new ExecutionTreeFactory()\n    const executionResult = executionTree.initTree(rawTree)\n    asyncExecutionDataToRedux(executionResult, oldExecutionTree, listenerApi)\n  } else {\n    const isAddAction =\n      action.type.startsWith(\"components/add\") ||\n      action.type.startsWith(\"action/add\") ||\n      action.type.startsWith(\"action/batchAdd\") ||\n      componentsActions.batchUpdateMultiComponentSlicePropsReducer.match(\n        action,\n      ) ||\n      actionActions.batchUpdateMultiActionSlicePropsReducer.match(action)\n    const executionResult = executionTree.updateTree(rawTree, isAddAction)\n    asyncExecutionDataToRedux(executionResult, oldExecutionTree, listenerApi)\n  }\n}\n\nasync function handleStartExecutionOnCanvas(\n  action: UnknownAction,\n  listenerApi: AppListenerEffectAPI,\n) {\n  const rootState = listenerApi.getState()\n  const oldExecutionTree = getExecutionResult(rootState)\n  if (executionTree) {\n    const executionResult =\n      executionTree.updateTreeFromExecution(oldExecutionTree)\n    const evaluatedTree = executionResult.evaluatedTree\n    const errorTree = executionResult.errorTree\n    const updates = diff(oldExecutionTree, evaluatedTree) || []\n    if (updates.length > 0) {\n      listenerApi.dispatch(\n        executionActions.setExecutionResultReducer({\n          updates,\n        }),\n      )\n      listenerApi.dispatch(\n        executionActions.setExecutionErrorReducer({\n          ...errorTree,\n        }),\n      )\n    }\n  }\n}\n\nfunction handleUpdateModalEffect(\n  action: ReturnType<typeof componentsActions.addModalComponentReducer>,\n  listenerApi: AppListenerEffectAPI,\n) {\n  const { payload } = action\n  const { modalComponentNode } = payload\n  const parentNodeDisplayName = modalComponentNode.parentNode\n  if (!parentNodeDisplayName) return\n  const rootState = listenerApi.getState()\n  const components = getComponentMap(rootState)\n  if (!components) return\n  const parentNode = searchComponentFromMap(components, parentNodeDisplayName)\n  if (!parentNode || !Array.isArray(parentNode.childrenNode)) return\n  const otherNode = parentNode.childrenNode.filter((childDisplayName) => {\n    return childDisplayName !== modalComponentNode.displayName\n  })\n  const updateSlice = [\n    {\n      displayName: modalComponentNode.displayName,\n      value: {\n        isVisible: true,\n      },\n    },\n  ]\n  otherNode.forEach((otherNodeChildDisplayName) => {\n    updateSlice.push({\n      displayName: otherNodeChildDisplayName,\n      value: {\n        isVisible: false,\n      },\n    })\n  })\n  listenerApi.dispatch(\n    executionActions.updateExecutionByMultiDisplayNameReducer(updateSlice),\n  )\n}\n\nexport function setupExecutionListeners(\n  startListening: AppStartListening,\n): Unsubscribe {\n  const subscriptions = [\n    startListening({\n      matcher: isAnyOf(\n        componentsActions.addComponentReducer,\n        componentsActions.updateComponentPropsReducer,\n        componentsActions.setComponentPropsReducer,\n        componentsActions.deleteComponentNodeReducer,\n        componentsActions.batchUpdateMultiComponentSlicePropsReducer,\n        componentsActions.updateMultiComponentPropsReducer,\n        componentsActions.addTargetPageSectionReducer,\n        componentsActions.updateTargetPagePropsReducer,\n        componentsActions.deleteTargetPageSectionReducer,\n        componentsActions.addPageNodeWithSortOrderReducer,\n        componentsActions.updateRootNodePropsReducer,\n        componentsActions.updateTargetPageLayoutReducer,\n        componentsActions.deletePageNodeReducer,\n        componentsActions.addSectionViewReducer,\n        componentsActions.addSectionViewConfigByConfigReducer,\n        componentsActions.deleteSectionViewReducer,\n        componentsActions.updateSectionViewPropsReducer,\n        componentsActions.addModalComponentReducer,\n        componentsActions.setGlobalStateReducer,\n        componentsActions.deleteGlobalStateByKeyReducer,\n        componentsActions.deleteSubPageViewNodeReducer,\n        componentsActions.updateDefaultSubPagePathReducer,\n        componentsActions.updateSubPagePathReducer,\n        componentsActions.addSubPageReducer,\n        componentsActions.updateCurrentPageStyleReducer,\n        componentsActions.deleteCurrentPageStyleReducer,\n        actionActions.addActionItemReducer,\n        actionActions.batchAddActionItemReducer,\n        actionActions.removeActionItemReducer,\n        actionActions.updateActionItemReducer,\n        actionActions.batchUpdateMultiActionSlicePropsReducer,\n        executionActions.startExecutionReducer,\n      ),\n      effect: handleStartExecution,\n    }),\n    startListening({\n      matcher: isAnyOf(\n        executionActions.updateExecutionByDisplayNameReducer,\n        executionActions.updateExecutionByMultiDisplayNameReducer,\n        executionActions.updateModalDisplayReducer,\n        executionActions.setGlobalStateInExecutionReducer,\n        executionActions.setInGlobalStateInExecutionReducer,\n        executionActions.setLocalStorageInExecutionReducer,\n        executionActions.clearLocalStorageInExecutionReducer,\n        executionActions.updateCurrentPagePathReducer,\n      ),\n      effect: handleStartExecutionOnCanvas,\n    }),\n    startListening({\n      actionCreator: componentsActions.addModalComponentReducer,\n      effect: handleUpdateModalEffect,\n    }),\n  ]\n\n  return () => {\n    subscriptions.forEach((unsubscribe) => unsubscribe())\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/executionTree/executionReducer.ts",
    "content": "import { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport { applyChange } from \"deep-diff\"\nimport { has, set } from \"lodash-es\"\nimport {\n  DependenciesState,\n  ErrorShape,\n  ExecutionState,\n  UpdateCurrentPagePathPayload,\n  UpdateExecutionByDisplayNamePayload,\n  executionInitialState,\n  setExecutionResultPayload,\n} from \"@/redux/currentApp/executionTree/executionState\"\nimport { CUSTOM_STORAGE_PREFIX } from \"@/utils/storage\"\nimport { isObject } from \"@/utils/typeHelper\"\n\nexport const setDependenciesReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<DependenciesState>\n> = (state, action) => {\n  state.dependencies = action.payload\n}\n\nexport const setIndependenciesReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<DependenciesState>\n> = (state, action) => {\n  state.independencies = action.payload\n}\n\nexport const setExecutionResultReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<setExecutionResultPayload>\n> = (state, action) => {\n  const { updates } = action.payload\n  if (updates.length === 0) {\n    return state\n  }\n\n  for (const update of updates) {\n    if (!Array.isArray(update.path) || update.path.length === 0) {\n      continue\n    }\n    try {\n      applyChange(state.result, undefined, update)\n    } catch (e) {\n      console.error(e)\n    }\n  }\n}\n\nexport const setExecutionErrorReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<Record<string, ErrorShape[]>>\n> = (state, action) => {\n  state.error = action.payload\n}\n\nexport const startExecutionReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<void>\n> = (state) => {\n  return state\n}\n\nexport const updateExecutionByDisplayNameReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<UpdateExecutionByDisplayNamePayload>\n> = (state, action) => {\n  const { displayName, value } = action.payload\n  state.result[displayName] = {\n    ...state.result[displayName],\n    ...value,\n  }\n}\n\nexport const updateExecutionByMultiDisplayNameReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<UpdateExecutionByDisplayNamePayload[]>\n> = (state, action) => {\n  action.payload.forEach(({ displayName, value }) => {\n    state.result[displayName] = {\n      ...state.result[displayName],\n      ...value,\n    }\n  })\n}\n\nexport const updateModalDisplayReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<{\n    displayName: string\n    display: boolean\n  }>\n> = (state, action) => {\n  const result = state.result\n  const currentNode = result[action.payload.displayName]\n  if (!currentNode) return state\n  const parentNodeDisplayName = currentNode.$parentNode\n  if (!parentNodeDisplayName) return state\n  const parentNode = result[parentNodeDisplayName]\n  if (\n    !parentNode ||\n    !Array.isArray(parentNode.$childrenNode) ||\n    parentNode.$childrenNode.length === 0\n  )\n    return state\n  const otherNodeDisplayNames = parentNode.$childrenNode.filter(\n    (key: string) => key !== action.payload.displayName,\n  )\n  currentNode.isVisible = action.payload.display\n  if (action.payload.display) {\n    otherNodeDisplayNames.forEach((key: string) => {\n      const node = result[key]\n      if (node) {\n        node.isVisible = false\n      }\n    })\n  }\n}\n\nexport const resetExecutionResultReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction\n> = () => {\n  return executionInitialState\n}\n\nexport const setGlobalStateInExecutionReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<{\n    key: string\n    value: unknown\n  }>\n> = (state, action) => {\n  const result = state.result\n  if (!result) return\n  const globalState = result.globalData\n  const rootNode = result.root\n  const rootGlobalState = rootNode.globalData\n  if (!globalState || !rootGlobalState) return\n  globalState[action.payload.key] = action.payload.value\n  rootGlobalState[action.payload.key] = action.payload.value\n}\n\nexport const setInGlobalStateInExecutionReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<{\n    key: string\n    path: string\n    value: unknown\n  }>\n> = (state, action) => {\n  const result = state.result\n  if (!result) return\n  const globalState = result.globalData\n  const rootNode = result.root\n  const rootGlobalState = rootNode.globalData\n  if (!isObject(globalState) || !isObject(rootGlobalState)) return\n  const targetState = globalState[action.payload.key]\n  const targetRootState = rootGlobalState[action.payload.key]\n  if (\n    (isObject(targetState) || Array.isArray(targetState)) &&\n    has(targetState, action.payload.path)\n  ) {\n    set(targetState, action.payload.path, action.payload.value)\n    set(\n      targetRootState as Record<string, any>,\n      action.payload.path,\n      action.payload.value,\n    )\n  }\n}\n\nexport const clearLocalStorageInExecutionReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction\n> = (state) => {\n  state.result.localStorage = {}\n  window.localStorage.removeItem(CUSTOM_STORAGE_PREFIX)\n}\n\nexport const setLocalStorageInExecutionReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<{\n    key: string\n    value: unknown\n  }>\n> = (state, action) => {\n  const { key, value } = action.payload\n  const localStorage = state.result.localStorage ?? {}\n  const newLocalStorage = {\n    ...localStorage,\n    [key]: value,\n  }\n  state.result.localStorage = newLocalStorage\n  window.localStorage.setItem(\n    CUSTOM_STORAGE_PREFIX,\n    JSON.stringify(newLocalStorage),\n  )\n}\n\nexport const updateCurrentPagePathReducer: CaseReducer<\n  ExecutionState,\n  PayloadAction<UpdateCurrentPagePathPayload>\n> = (state, action) => {\n  const { pageDisplayName, subPagePath } = action.payload\n  const rootNode = state.result.root\n  if (!rootNode) return\n  const pageSortedKey = rootNode.$childrenNode\n  if (!Array.isArray(pageSortedKey)) return\n  const currentIndex = pageSortedKey.findIndex(\n    (pageName) => pageName === pageDisplayName,\n  )\n  if (currentIndex === -1) return\n  const currentPageNode = state.result[pageDisplayName]\n  const pageChildrenNodeDisplayName: string[] = currentPageNode.$childrenNode\n  rootNode.currentSubPagePath = subPagePath\n  rootNode.currentPageIndex = currentIndex\n  if (subPagePath) {\n    pageChildrenNodeDisplayName.forEach((sectionDisplayName) => {\n      const sectionNode = state.result[sectionDisplayName]\n      if (!sectionNode) return\n      if (sectionNode.$widgetType === \"MODAL_SECTION_NODE\") return\n      const sectionViewConfig = sectionNode.sectionViewConfigs.find(\n        (config: Record<string, string>) => config.path === subPagePath,\n      )\n      let sectionIndex = sectionNode.viewSortedKey.findIndex(\n        (viewDisplayName: string) =>\n          viewDisplayName === sectionViewConfig?.viewDisplayName,\n      )\n      if (sectionIndex === -1) {\n        const defaultViewPath = sectionNode.defaultViewKey\n        const defaultSectionViewConfig = sectionNode.sectionViewConfigs.find(\n          (config: Record<string, string>) => config.path === defaultViewPath,\n        )\n        sectionIndex = sectionNode.viewSortedKey.findIndex(\n          (viewDisplayName: string) =>\n            viewDisplayName === defaultSectionViewConfig?.viewDisplayName,\n        )\n        if (sectionIndex === -1) {\n          sectionIndex = 0\n        }\n      }\n      sectionNode.currentViewIndex = sectionIndex\n    })\n  } else {\n    pageChildrenNodeDisplayName.forEach((sectionDisplayName) => {\n      const sectionNode = state.result[sectionDisplayName]\n      if (!sectionNode) return\n      if (sectionNode.$widgetType === \"MODAL_SECTION_NODE\") return\n      let sectionIndex = 0\n      const defaultViewPath = sectionNode.defaultViewKey\n      const defaultSectionViewConfig = sectionNode.sectionViewConfigs.find(\n        (config: Record<string, string>) => config.path === defaultViewPath,\n      )\n      sectionIndex = sectionNode.viewSortedKey.findIndex(\n        (viewDisplayName: string) =>\n          viewDisplayName === defaultSectionViewConfig?.viewDisplayName,\n      )\n      if (sectionIndex === -1) {\n        sectionIndex = 0\n      }\n      sectionNode.currentViewIndex = sectionIndex\n    })\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/executionTree/executionSelector.ts",
    "content": "import { getCurrentUser } from \"@illa-public/user-data\"\nimport { createSelector } from \"@reduxjs/toolkit\"\nimport { klona } from \"klona/json\"\nimport { get } from \"lodash-es\"\nimport { getBuilderInfo } from \"@/redux/builderInfo/builderInfoSelector\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport {\n  getAllComponentDisplayNameMapProps,\n  getOriginalGlobalData,\n  getPageNameMapDescendantNodeDisplayNames,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { RootState } from \"@/store\"\nimport { NeedBuildNode, buildForest } from \"@/utils/componentNode/buildTree\"\nimport { RawTreeFactory } from \"@/utils/executionTreeHelper/rawTreeFactory\"\nimport { recursiveDelete } from \"@/utils/executionTreeHelper/rrecursiveDelete\"\nimport { getEditorConfig } from \"../../config/configSelector\"\nimport { getClientWidgetLayoutInfo } from \"../layoutInfo/layoutInfoSelector\"\nimport { WidgetLayoutInfo } from \"../layoutInfo/layoutInfoState\"\nimport { getAllDescendantNodeDisplayNamesByExecution } from \"../layoutInfo/utils\"\n\nexport const getRawTree = createSelector(\n  [\n    getActionList,\n    getAllComponentDisplayNameMapProps,\n    getCurrentUser,\n    getBuilderInfo,\n    getOriginalGlobalData,\n  ],\n  (actions, widgets, currentUserInfo, builderInfo, globalData) => {\n    return RawTreeFactory.create({\n      actions: actions ?? [],\n      widgets: widgets ?? {},\n      currentUserInfo,\n      builderInfo,\n      globalData,\n    })\n  },\n)\n\nexport const getCurrentApp = (state: RootState) => state.currentApp\n\nexport const getExecution = createSelector(\n  [getCurrentApp],\n  (currentApp) => currentApp.execution,\n)\n\nexport const getExecutionResult = createSelector(\n  [getExecution],\n  (execution) => {\n    return execution.result || {}\n  },\n)\n\nexport const getExecutionError = createSelector(\n  [getExecution],\n  (execution) => execution.error ?? {},\n)\n\nexport const IGNORE_WIDGET_TYPES = new Set<string>([\n  \"PAGE_NODE\",\n  \"SECTION_NODE\",\n  \"CANVAS\",\n  \"DOT_PANEL\",\n  \"MODAL_SECTION_NODE\",\n])\n\nexport const getWidgetExecutionResult = createSelector(\n  [getExecutionResult],\n  (executionResult) => {\n    const widgetExecutionResult: Record<string, any> = {}\n    Object.keys(executionResult).forEach((key) => {\n      const widgetOrAction = executionResult[key]\n      if (widgetOrAction && widgetOrAction.$type === \"WIDGET\") {\n        widgetExecutionResult[key] = widgetOrAction\n      }\n    })\n    return widgetExecutionResult\n  },\n)\n\nexport const getPageExecutionResultArray = createSelector(\n  [getWidgetExecutionResult],\n  (widgetExecutionResult) => {\n    const widgetExecutionResultArray: Record<string, any>[] = []\n    Object.keys(widgetExecutionResult).forEach((key) => {\n      if (\n        widgetExecutionResult[key] &&\n        widgetExecutionResult[key].$widgetType === \"PAGE_NODE\"\n      ) {\n        widgetExecutionResultArray.push({\n          ...widgetExecutionResult[key],\n          displayName: key,\n        })\n      }\n    })\n    return widgetExecutionResultArray\n  },\n)\n\nexport const getSectionExecutionResultArray = createSelector(\n  [getWidgetExecutionResult],\n  (widgetExecutionResult) => {\n    const sectionExecutionResult: Record<string, any> = {}\n    Object.keys(widgetExecutionResult).forEach((key) => {\n      if (\n        widgetExecutionResult[key] &&\n        widgetExecutionResult[key].$widgetType === \"SECTION_NODE\"\n      ) {\n        sectionExecutionResult[key] = {\n          ...widgetExecutionResult[key],\n          displayName: key,\n        }\n      }\n    })\n    return sectionExecutionResult\n  },\n)\n\nexport const getRootNodeExecutionResult = createSelector(\n  [getWidgetExecutionResult],\n  (widgetExecutionResult) => {\n    const rootNode = widgetExecutionResult[\"root\"]\n    return rootNode\n      ? rootNode\n      : {\n          currentPageIndex: 0,\n          pageSortedKey: [\"page1\"],\n          homepageDisplayName: \"page1\",\n        }\n  },\n)\n\nexport const getActionExecutionResult = createSelector(\n  [getExecutionResult],\n  (executionResult) => {\n    const actionExecutionResult: Record<string, any> = {}\n    Object.keys(executionResult).forEach((key) => {\n      const widgetOrAction = executionResult[key]\n      if (widgetOrAction && widgetOrAction.$type === \"ACTION\") {\n        actionExecutionResult[key] = widgetOrAction\n      }\n    })\n    return actionExecutionResult\n  },\n)\n\nexport const getActionExecutionResultWithOutIgnoreKey = createSelector(\n  [getActionExecutionResult],\n  (actionExecutionResult) => {\n    return recursiveDelete(actionExecutionResult, [\"displayName\"])\n  },\n)\n\nexport const getActionExecutionResultArray = createSelector(\n  [getActionExecutionResult],\n  (actionExecutionResult) => {\n    const actionExecutionResultArray: Record<string, any>[] = []\n    Object.keys(actionExecutionResult).forEach((key) => {\n      actionExecutionResultArray.push({\n        ...actionExecutionResult[key],\n        displayName: key,\n      })\n    })\n    return actionExecutionResultArray\n  },\n)\n\nexport const getCurrentPageIndex = createSelector(\n  [getRootNodeExecutionResult],\n  (rootNode) => rootNode.currentPageIndex as number,\n)\n\nexport const getCurrentPageDisplayName = createSelector(\n  [getRootNodeExecutionResult],\n  (rootNode) => {\n    const { pageSortedKey, currentPageIndex } = rootNode\n    if (currentPageIndex > pageSortedKey.lengths)\n      return pageSortedKey[0] as string\n    return pageSortedKey[currentPageIndex] as string\n  },\n)\n\nexport const getExecutionResultToGlobalCodeMirror = createSelector(\n  [getExecutionResult],\n  (executionResult) => {\n    const result: Record<string, unknown> = {}\n    Object.keys(executionResult).forEach((key) => {\n      if (\n        !IGNORE_WIDGET_TYPES.has(executionResult[key]?.$widgetType) &&\n        executionResult[key] != undefined\n      ) {\n        result[key] = klona(executionResult[key])\n      }\n    })\n    return result\n  },\n)\n\nexport const getExecutionResultToCurrentPageCodeMirror = createSelector(\n  [\n    getCurrentPageDisplayName,\n    getPageNameMapDescendantNodeDisplayNames,\n    getExecutionResult,\n  ],\n  (\n    currentPageDisplayName,\n    pageNameMapDescendantNodeDisplayNames,\n    executionResult,\n  ) => {\n    const currentPageWidgets =\n      pageNameMapDescendantNodeDisplayNames[currentPageDisplayName]\n    const result: Record<string, unknown> = {}\n    Object.keys(executionResult).forEach((key) => {\n      const currentSeed = executionResult[key]\n      if (\n        currentSeed != undefined &&\n        currentSeed.$type === \"WIDGET\" &&\n        !IGNORE_WIDGET_TYPES.has(executionResult[key]?.$widgetType) &&\n        currentPageWidgets.includes(key)\n      ) {\n        result[key] = klona(executionResult[key])\n      }\n      if (currentSeed && currentSeed.$type !== \"WIDGET\") {\n        result[key] = klona(executionResult[key])\n      }\n    })\n    return result\n  },\n)\n\nexport const getDependenciesMap = (state: RootState) => {\n  return state.currentApp.execution.dependencies\n}\n\nexport const getInDependenciesMap = (state: RootState) => {\n  return state.currentApp.execution.independencies\n}\n\nexport const getGlobalDataExecutionResult = createSelector(\n  [getExecutionResult],\n  (result) => {\n    return get(result, \"globalData\", {})\n  },\n)\n\nexport const getBuilderInfoExecutionResult = createSelector(\n  [getExecutionResult],\n  (result) => get(result, \"builderInfo\", {}),\n)\n\nexport const getCurrentUserInfoExecutionResult = createSelector(\n  [getExecutionResult],\n  (result) => get(result, \"currentUserInfo\", {}),\n)\n\nexport const getURLParamsExecutionResult = createSelector(\n  getExecutionResult,\n  (result) => {\n    return get(result, \"urlParams\", {})\n  },\n)\n\nexport const getLocalStorageExecutionResult = createSelector(\n  getExecutionResult,\n  (result) => {\n    return get(result, \"localStorage\", {})\n  },\n)\n\nexport const getPageInfosExecutionResult = createSelector(\n  getExecutionResult,\n  (result) => {\n    return get(result, \"pageInfos\", {})\n  },\n)\n\nexport const getCurrentPageInfoExecutionResult = createSelector(\n  getExecutionResult,\n  (result) => {\n    return get(result, \"currentPageInfo\", {})\n  },\n)\n\nexport const getGlobalInfoExecutionResult = createSelector(\n  [\n    getCurrentUserInfoExecutionResult,\n    getBuilderInfoExecutionResult,\n    getURLParamsExecutionResult,\n    getLocalStorageExecutionResult,\n    getPageInfosExecutionResult,\n    getCurrentPageInfoExecutionResult,\n    getGlobalDataExecutionResult,\n  ],\n  (\n    currentUserInfo,\n    builderInfo,\n    urlParams,\n    localStorage,\n    pageInfos,\n    currentPageInfo,\n    globalData,\n  ) => {\n    let result: Record<string, unknown> = recursiveDelete({\n      currentUserInfo,\n      builderInfo,\n      urlParams,\n      localStorage,\n      pageInfos,\n      currentPageInfo,\n    })\n    const ignoredGlobalData = recursiveDelete(globalData)\n    if (Object.keys(ignoredGlobalData).length > 0) {\n      result.globalData = ignoredGlobalData\n    }\n\n    return result\n  },\n)\n\nexport const getPageLoadingActions = createSelector(\n  [getActionExecutionResultArray],\n  (actionResult) => {\n    return actionResult.filter(\n      (action) => action.config?.advancedConfig.runtime === \"pageLoading\",\n    )\n  },\n)\n\nexport const getAppLoadedActions = createSelector(\n  [getActionExecutionResultArray],\n  (actions) => {\n    return actions.filter(\n      (action) => action.config?.advancedConfig.runtime === \"appLoaded\",\n    )\n  },\n)\n\nexport const getIntervalActions = createSelector(\n  [getActionExecutionResultArray],\n  (actions) => {\n    return actions.filter(\n      (action) => action?.config?.advancedConfig.isPeriodically,\n    )\n  },\n)\n\nexport const getCurrentPageWidgetExecutionResultArray = createSelector(\n  [\n    getCurrentPageDisplayName,\n    getPageNameMapDescendantNodeDisplayNames,\n    getWidgetExecutionResult,\n  ],\n  (\n    currentPageDisplayName,\n    pageNameMapDescendantNodeDisplayNames,\n    widgetExecutionResult,\n  ) => {\n    const descendantNodeDisplayNames =\n      pageNameMapDescendantNodeDisplayNames[currentPageDisplayName]\n    if (!Array.isArray(descendantNodeDisplayNames)) return []\n    const widgetExecutionResultArray: Record<string, any>[] = []\n    descendantNodeDisplayNames.forEach((displayName) => {\n      if (!widgetExecutionResult[displayName]) return\n      widgetExecutionResultArray.push({\n        ...widgetExecutionResult[displayName],\n        displayName,\n      })\n    })\n    return widgetExecutionResultArray\n  },\n)\n\nexport const getCurrentPageGeneralWidgetExecutionResultArray = createSelector(\n  [getCurrentPageWidgetExecutionResultArray],\n  (currentPageWidgetExecutionResult) => {\n    const widgetExecutionResultArray: Record<string, any>[] = []\n    currentPageWidgetExecutionResult.forEach((widget) => {\n      if (!IGNORE_WIDGET_TYPES.has(widget.$widgetType)) {\n        widgetExecutionResultArray.push(widget)\n      }\n    })\n    return widgetExecutionResultArray\n  },\n)\n\nexport const getCurrentPageModalWidgetExecutionResultArray = createSelector(\n  [getCurrentPageWidgetExecutionResultArray],\n  (currentPageWidgetExecutionResult) => {\n    const widgetExecutionResultArray: Record<string, any>[] = []\n    currentPageWidgetExecutionResult.forEach((widget) => {\n      if (widget.$widgetType === \"MODAL_WIDGET\") {\n        widgetExecutionResultArray.push(widget)\n      }\n    })\n    return widgetExecutionResultArray\n  },\n)\n\nconst getTargetSectionWidget = (\n  targetSectionName: string,\n  currentPageWidgets: NeedBuildNode[],\n  widgets: Record<string, WidgetLayoutInfo>,\n) => {\n  const targetSection = currentPageWidgets.find((widget) =>\n    widget.displayName.startsWith(targetSectionName),\n  )\n  const targetSectionMapHasNodeDisplayNames: Record<string, string[]> = {}\n  if (targetSection) {\n    switch (targetSectionName) {\n      case \"modalSection\": {\n        const childrenModalWidgets = targetSection.$childrenNode\n        childrenModalWidgets.forEach((displayName: string) => {\n          const viewWidget = widgets[displayName]\n          if (viewWidget) {\n            const descendantNodeDisplayNames =\n              getAllDescendantNodeDisplayNamesByExecution(viewWidget, widgets)\n            targetSectionMapHasNodeDisplayNames[displayName] =\n              descendantNodeDisplayNames\n          }\n        })\n\n        const result: NeedBuildNode[] = []\n        Object.values(targetSectionMapHasNodeDisplayNames).forEach(\n          (displayNames) => {\n            displayNames.forEach((displayName) => {\n              const widget = currentPageWidgets.find((widget) => {\n                return widget.displayName === displayName\n              })\n              if (widget) {\n                result.push(widget)\n              }\n            })\n          },\n        )\n        return result\n      }\n      default: {\n        const currentViewIndex = targetSection.currentViewIndex as number\n        const viewDisplayNames = targetSection.$childrenNode\n        const currentViewDisplayName = viewDisplayNames[currentViewIndex]\n\n        if (!currentViewDisplayName) return []\n        viewDisplayNames.forEach((displayName: string) => {\n          const viewWidget = widgets[displayName]\n          if (viewWidget) {\n            const descendantNodeDisplayNames =\n              getAllDescendantNodeDisplayNamesByExecution(viewWidget, widgets)\n            targetSectionMapHasNodeDisplayNames[displayName] =\n              descendantNodeDisplayNames\n          }\n        })\n        const currentSectionWidgets =\n          targetSectionMapHasNodeDisplayNames[currentViewDisplayName]\n        if (!currentSectionWidgets) return []\n        return currentPageWidgets.filter((widget) =>\n          currentSectionWidgets.includes(widget.displayName),\n        )\n      }\n    }\n  }\n\n  return []\n}\n\nexport const getCurrentPageBodyWidgetTree = createSelector(\n  [getCurrentPageWidgetExecutionResultArray, getClientWidgetLayoutInfo],\n  (currentPageWidgets, widgets) => {\n    return buildForest(\n      getTargetSectionWidget(\n        \"bodySection\",\n        currentPageWidgets as NeedBuildNode[],\n        widgets,\n      ),\n      widgets,\n    )\n  },\n)\n\nexport const getCurrentPageFooterWidgetTree = createSelector(\n  [getCurrentPageWidgetExecutionResultArray, getClientWidgetLayoutInfo],\n  (currentPageWidgets, widgets) => {\n    return buildForest(\n      getTargetSectionWidget(\n        \"footerSection\",\n        currentPageWidgets as NeedBuildNode[],\n        widgets,\n      ),\n      widgets,\n    )\n  },\n)\nexport const getCurrentPageLeftWidgetTree = createSelector(\n  [getCurrentPageWidgetExecutionResultArray, getClientWidgetLayoutInfo],\n  (currentPageWidgets, widgets) => {\n    return buildForest(\n      getTargetSectionWidget(\n        \"leftSection\",\n        currentPageWidgets as NeedBuildNode[],\n        widgets,\n      ),\n      widgets,\n    )\n  },\n)\nexport const getCurrentPageHeaderWidgetTree = createSelector(\n  [getCurrentPageWidgetExecutionResultArray, getClientWidgetLayoutInfo],\n  (currentPageWidgets, widgets) => {\n    return buildForest(\n      getTargetSectionWidget(\n        \"headerSection\",\n        currentPageWidgets as NeedBuildNode[],\n        widgets,\n      ),\n      widgets,\n    )\n  },\n)\nexport const getCurrentPageRightWidgetTree = createSelector(\n  [getCurrentPageWidgetExecutionResultArray, getClientWidgetLayoutInfo],\n  (currentPageWidgets, widgets) => {\n    return buildForest(\n      getTargetSectionWidget(\n        \"rightSection\",\n        currentPageWidgets as NeedBuildNode[],\n        widgets,\n      ),\n      widgets,\n    )\n  },\n)\nexport const getCurrentPageModalWidgetTree = createSelector(\n  [getCurrentPageWidgetExecutionResultArray, getClientWidgetLayoutInfo],\n  (currentPageWidgets, widgets) => {\n    return buildForest(\n      getTargetSectionWidget(\n        \"modalSection\",\n        currentPageWidgets as NeedBuildNode[],\n        widgets,\n      ),\n      widgets,\n    )\n  },\n)\n\nexport const getDraggingComponentIDs = createSelector(\n  [getEditorConfig],\n  (editorConfig) => editorConfig.draggingComponentIDs,\n)\n\nexport const getResizingComponentIDs = createSelector(\n  [getEditorConfig],\n  (editorConfig) => {\n    return editorConfig.resizingComponentIDs\n  },\n)\n\nexport const getIsDragging = createSelector(\n  [getDraggingComponentIDs],\n  (ids) => {\n    return ids.length > 0\n  },\n)\n\nexport const getIsResizing = createSelector(\n  [getResizingComponentIDs],\n  (ids) => {\n    return ids.length > 0\n  },\n)\n\nexport const getCurrentPageStyle = createSelector(\n  [getCurrentPageDisplayName, getExecutionResult],\n  (currentPageDisplayName, executionResult) => {\n    return get(executionResult, `${currentPageDisplayName}.style`, {})\n  },\n)\n\nexport const getCurrentPageExecutionResult = createSelector(\n  [getCurrentPageDisplayName, getExecutionResult],\n  (currentPageDisplayName, executionResult) => {\n    return get(executionResult, `${currentPageDisplayName}`, {})\n  },\n)\n\nexport const getCurrentPageBodySection = createSelector(\n  [getCurrentPageDisplayName, getExecutionResult],\n  (currentPageDisplayName, executionResult) => {\n    const currentPageNode = get(executionResult, currentPageDisplayName)\n    if (!currentPageNode) return undefined\n    const childDisplayName = currentPageNode.$childrenNode.find(\n      (displayName: string) => {\n        const node = get(executionResult, displayName)\n        return (\n          node &&\n          node?.$widgetType === \"SECTION_NODE\" &&\n          node?.displayName.startsWith(\"bodySection\")\n        )\n      },\n    )\n    if (!childDisplayName) return undefined\n    return get(executionResult, childDisplayName)\n  },\n)\n\nexport const getCurrentPageLeftSection = createSelector(\n  [getCurrentPageDisplayName, getExecutionResult],\n  (currentPageDisplayName, executionResult) => {\n    const currentPageNode = get(executionResult, currentPageDisplayName)\n    if (!currentPageNode) return undefined\n    const childDisplayName = currentPageNode.$childrenNode.find(\n      (displayName: string) => {\n        const node = get(executionResult, displayName)\n        return (\n          node &&\n          node?.$widgetType === \"SECTION_NODE\" &&\n          node?.displayName.startsWith(\"leftSection\")\n        )\n      },\n    )\n    if (!childDisplayName) return undefined\n    return get(executionResult, childDisplayName)\n  },\n)\n\nexport const getCurrentPageRightSection = createSelector(\n  [getCurrentPageDisplayName, getExecutionResult],\n  (currentPageDisplayName, executionResult) => {\n    const currentPageNode = get(executionResult, currentPageDisplayName)\n    if (!currentPageNode) return undefined\n    const childDisplayName = currentPageNode.$childrenNode.find(\n      (displayName: string) => {\n        const node = get(executionResult, displayName)\n        return (\n          node &&\n          node?.$widgetType === \"SECTION_NODE\" &&\n          node?.displayName.startsWith(\"rightSection\")\n        )\n      },\n    )\n    if (!childDisplayName) return undefined\n    return get(executionResult, childDisplayName)\n  },\n)\n\nexport const getCurrentPageHeaderSection = createSelector(\n  [getCurrentPageDisplayName, getExecutionResult],\n  (currentPageDisplayName, executionResult) => {\n    const currentPageNode = get(executionResult, currentPageDisplayName)\n    if (!currentPageNode) return undefined\n    const childDisplayName = currentPageNode.$childrenNode.find(\n      (displayName: string) => {\n        const node = get(executionResult, displayName)\n        return (\n          node &&\n          node?.$widgetType === \"SECTION_NODE\" &&\n          node?.displayName.startsWith(\"headerSection\")\n        )\n      },\n    )\n    if (!childDisplayName) return undefined\n    return get(executionResult, childDisplayName)\n  },\n)\n\nexport const getCurrentPageFooterSection = createSelector(\n  [getCurrentPageDisplayName, getExecutionResult],\n  (currentPageDisplayName, executionResult) => {\n    const currentPageNode = get(executionResult, currentPageDisplayName)\n    if (!currentPageNode) return undefined\n    const childDisplayName = currentPageNode.$childrenNode.find(\n      (displayName: string) => {\n        const node = get(executionResult, displayName)\n        return (\n          node &&\n          node?.$widgetType === \"SECTION_NODE\" &&\n          node?.displayName.startsWith(\"footerSection\")\n        )\n      },\n    )\n    if (!childDisplayName) return undefined\n    return get(executionResult, childDisplayName)\n  },\n)\n\nexport const getCurrentPageModalSection = createSelector(\n  [getCurrentPageDisplayName, getExecutionResult],\n  (currentPageDisplayName, executionResult) => {\n    const currentPageNode = get(executionResult, currentPageDisplayName)\n    if (!currentPageNode) return undefined\n    const childDisplayName = currentPageNode.$childrenNode.find(\n      (displayName: string) => {\n        const node = get(executionResult, displayName)\n        return (\n          node &&\n          node.$widgetType === \"MODAL_SECTION_NODE\" &&\n          node.displayName.startsWith(\"modalSection\")\n        )\n      },\n    )\n    if (!childDisplayName) return undefined\n    return get(executionResult, childDisplayName)\n  },\n)\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/executionTree/executionSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  clearLocalStorageInExecutionReducer,\n  resetExecutionResultReducer,\n  setDependenciesReducer,\n  setExecutionErrorReducer,\n  setExecutionResultReducer,\n  setGlobalStateInExecutionReducer,\n  setInGlobalStateInExecutionReducer,\n  setIndependenciesReducer,\n  setLocalStorageInExecutionReducer,\n  startExecutionReducer,\n  updateCurrentPagePathReducer,\n  updateExecutionByDisplayNameReducer,\n  updateExecutionByMultiDisplayNameReducer,\n  updateModalDisplayReducer,\n} from \"@/redux/currentApp/executionTree/executionReducer\"\nimport { executionInitialState } from \"@/redux/currentApp/executionTree/executionState\"\n\nconst executionSlice = createSlice({\n  name: \"execution\",\n  initialState: executionInitialState,\n  reducers: {\n    setDependenciesReducer,\n    setIndependenciesReducer,\n    setExecutionResultReducer,\n    setExecutionErrorReducer,\n    startExecutionReducer,\n    updateExecutionByDisplayNameReducer,\n    updateExecutionByMultiDisplayNameReducer,\n    updateModalDisplayReducer,\n    resetExecutionResultReducer,\n    setGlobalStateInExecutionReducer,\n    setInGlobalStateInExecutionReducer,\n    clearLocalStorageInExecutionReducer,\n    setLocalStorageInExecutionReducer,\n    updateCurrentPagePathReducer,\n  },\n})\n\nexport const executionActions = executionSlice.actions\nexport default executionSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/executionTree/executionState.ts",
    "content": "import { Diff } from \"deep-diff\"\n\nexport enum ExecutionErrorType {\n  EVALUATED = \"EVALUATED\",\n  LINT = \"LINT\",\n  VALIDATION = \"VALIDATION\",\n}\n\nexport interface ErrorShape {\n  errorType: ExecutionErrorType\n  errorMessage: string\n  errorLine?: number\n  errorColumn?: number\n  errorName?: string\n}\nexport type DependenciesState = Record<string, string[]>\n\nexport interface ExecutionState {\n  dependencies: DependenciesState\n  result: Record<string, any>\n  error: Record<string, ErrorShape[]>\n  independencies: DependenciesState\n}\n\nexport const executionInitialState: ExecutionState = {\n  dependencies: {},\n  result: {},\n  error: {},\n  independencies: {},\n}\n\nexport interface setExecutionResultPayload {\n  updates: Diff<Record<string, any>, Record<string, any>>[]\n}\n\nexport interface UpdateExecutionByDisplayNamePayload {\n  displayName: string\n  value: Record<string, any>\n}\n\nexport interface UpdateCurrentPagePathPayload {\n  pageDisplayName: string\n  subPagePath?: string\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/layoutInfo/layoutInfoListener.ts",
    "content": "import { ComponentMapNode } from \"@illa-public/public-types\"\nimport { UnknownAction, Unsubscribe, isAnyOf } from \"@reduxjs/toolkit\"\nimport { klona } from \"klona/json\"\nimport {\n  getNewPositionWithCrossing,\n  sortedRuleByYAndX,\n} from \"@/page/App/components/DotPanel/utils/crossingHelper\"\nimport {\n  getAllComponentDisplayNameMapLayoutInfo,\n  getComponentMap,\n  searchDSLByDisplayName,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { AppListenerEffectAPI, AppStartListening } from \"@/store\"\nimport { getClientWidgetLayoutInfo } from \"./layoutInfoSelector\"\nimport { layoutInfoActions } from \"./layoutInfoSlice\"\nimport {\n  BatchUpdateWidgetLayoutInfoPayload,\n  WidgetLayoutInfo,\n} from \"./layoutInfoState\"\n\nasync function handleUpdateReflowEffect(\n  action: ReturnType<typeof layoutInfoActions.updateWidgetLayoutInfoReducer>,\n  listenerApi: AppListenerEffectAPI,\n) {\n  const rootState = listenerApi.getState()\n  const widgetLayoutInfos = getClientWidgetLayoutInfo(rootState)\n  const components = getComponentMap(rootState)\n  let updateSlice: BatchUpdateWidgetLayoutInfoPayload[] = []\n\n  const { layoutInfo, displayName, parentNode } = action.payload\n\n  const originNodes = searchDSLByDisplayName(parentNode)\n\n  let originChildrenNode: ComponentMapNode[] = []\n\n  if (\n    originNodes &&\n    originNodes.childrenNode &&\n    originNodes.childrenNode.length > 0\n  ) {\n    originChildrenNode = originNodes.childrenNode.map(\n      (displayName) => components[displayName],\n    )\n  }\n\n  const mainNodeLayoutInfo = {\n    ...widgetLayoutInfos[displayName].layoutInfo,\n    h: layoutInfo.h ?? widgetLayoutInfos[displayName].layoutInfo.h,\n  }\n\n  if (originChildrenNode.length > 0) {\n    originChildrenNode\n      .filter((node) => node.displayName !== displayName)\n      .forEach((node) => {\n        const layoutInfo = widgetLayoutInfos[node.displayName].layoutInfo\n        updateSlice.push({\n          displayName: node.displayName,\n          layoutInfo: {\n            x: layoutInfo.x,\n            y: node.y,\n            w: layoutInfo.w,\n            h: layoutInfo.h,\n          },\n        })\n      })\n  }\n\n  const effectMap = getNewPositionWithCrossing(\n    {\n      ...mainNodeLayoutInfo,\n    },\n    parentNode,\n    [displayName],\n    Object.values(widgetLayoutInfos).filter(\n      (item) => item.parentNode === parentNode,\n    ),\n  )\n\n  if (effectMap && effectMap.size > 0) {\n    effectMap.forEach((widgetLayoutInfo) => {\n      const oldSliceIndex = updateSlice.findIndex(\n        (slice) => slice.displayName === widgetLayoutInfo.displayName,\n      )\n      if (oldSliceIndex !== -1) {\n        updateSlice.splice(oldSliceIndex, 1)\n      }\n      updateSlice.push({\n        displayName: widgetLayoutInfo.displayName,\n        layoutInfo: {\n          x: widgetLayoutInfo.layoutInfo.x,\n          y: widgetLayoutInfo.layoutInfo.y,\n          w: widgetLayoutInfo.layoutInfo.w,\n          h: widgetLayoutInfo.layoutInfo.h,\n        },\n      })\n    })\n  }\n\n  const currentLayoutInfos = klona(widgetLayoutInfos)\n\n  updateSlice.forEach((slice) => {\n    if (currentLayoutInfos[slice.displayName]) {\n      currentLayoutInfos[slice.displayName] = {\n        ...currentLayoutInfos[slice.displayName],\n        layoutInfo: {\n          ...currentLayoutInfos[slice.displayName].layoutInfo,\n          ...slice.layoutInfo!,\n        },\n      }\n    }\n  })\n\n  const currentLayoutInfosArray = Object.values(currentLayoutInfos)\n    .filter((info) => info.parentNode === parentNode)\n    .sort(sortedRuleByYAndX)\n\n  let effectName: string[] = []\n  currentLayoutInfosArray.forEach((item) => {\n    effectName.push(item.displayName)\n    const effectMap = getNewPositionWithCrossing(\n      item.layoutInfo,\n      parentNode,\n      effectName,\n      currentLayoutInfosArray,\n    )\n    if (effectMap && effectMap.size > 0) {\n      effectMap.forEach((widgetLayoutInfo) => {\n        const oldSliceIndex = updateSlice.findIndex(\n          (slice) => slice.displayName === widgetLayoutInfo.displayName,\n        )\n        if (oldSliceIndex !== -1) {\n          updateSlice.splice(oldSliceIndex, 1)\n        }\n        updateSlice.push({\n          displayName: widgetLayoutInfo.displayName,\n          layoutInfo: {\n            x: widgetLayoutInfo.layoutInfo.x,\n            y: widgetLayoutInfo.layoutInfo.y,\n            w: widgetLayoutInfo.layoutInfo.w,\n            h: widgetLayoutInfo.layoutInfo.h,\n          },\n        })\n      })\n    }\n  })\n\n  listenerApi.dispatch(\n    layoutInfoActions.batchUpdateWidgetLayoutInfoReducer(updateSlice),\n  )\n}\n\nconst updateWidgetPositionAdapter = (\n  action: ReturnType<\n    | typeof componentsActions.addComponentReducer\n    | typeof componentsActions.updateComponentLayoutInfoReducer\n    | typeof componentsActions.updateComponentPositionReducer\n    | typeof componentsActions.batchUpdateComponentLayoutInfoWhenReflowReducer\n  >,\n) => {\n  let effectDisplayNames: string[] = []\n\n  switch (action.type) {\n    case \"components/addComponentReducer\": {\n      const { payload } = action\n      payload.forEach((item) => {\n        effectDisplayNames.push(item.displayName)\n      })\n      break\n    }\n    case \"components/updateComponentLayoutInfoReducer\": {\n      const { payload } = action\n      const { displayName } = payload\n      effectDisplayNames.push(displayName)\n      break\n    }\n    case \"components/updateComponentPositionReducer\": {\n      const { payload } = action\n      payload.updateSlices.forEach((item) => {\n        effectDisplayNames.push(item.displayName)\n      })\n      break\n    }\n    case \"components/batchUpdateComponentLayoutInfoWhenReflowReducer\": {\n      const { payload } = action\n      payload.forEach((item) => {\n        effectDisplayNames.push(item.displayName)\n      })\n      break\n    }\n  }\n  return effectDisplayNames\n}\n\nfunction handleUpdateWidgetPositionInExecutionLayoutInfo(\n  action: UnknownAction,\n  listenerApi: AppListenerEffectAPI,\n) {\n  const rootState = listenerApi.getState()\n  let displayNameMapNode = getAllComponentDisplayNameMapLayoutInfo(rootState)\n  if (!displayNameMapNode) return\n  const executionLayoutInfos = getClientWidgetLayoutInfo(rootState)\n  let setWidgetLayoutInfoReducerActionPayload: Record<\n    string,\n    WidgetLayoutInfo\n  > = {}\n  let effectDisplayNames: string[] = []\n  if (\n    componentsActions.addComponentReducer.match(action) ||\n    componentsActions.updateComponentLayoutInfoReducer.match(action) ||\n    componentsActions.updateComponentPositionReducer.match(action) ||\n    componentsActions.batchUpdateComponentLayoutInfoWhenReflowReducer.match(\n      action,\n    )\n  ) {\n    effectDisplayNames = updateWidgetPositionAdapter(action)\n  }\n\n  Object.keys(displayNameMapNode).forEach((displayName) => {\n    if (\n      (displayNameMapNode as Record<string, WidgetLayoutInfo>)[displayName] &&\n      executionLayoutInfos[displayName] &&\n      effectDisplayNames.indexOf(displayName) === -1\n    ) {\n      setWidgetLayoutInfoReducerActionPayload[displayName] = {\n        ...(displayNameMapNode as Record<string, WidgetLayoutInfo>)[\n          displayName\n        ],\n        layoutInfo: {\n          ...(displayNameMapNode as Record<string, WidgetLayoutInfo>)[\n            displayName\n          ].layoutInfo,\n          y: executionLayoutInfos[displayName].layoutInfo.y,\n          h: executionLayoutInfos[displayName].layoutInfo.h,\n        },\n      }\n    } else {\n      setWidgetLayoutInfoReducerActionPayload[displayName] = {\n        ...(displayNameMapNode as Record<string, WidgetLayoutInfo>)[\n          displayName\n        ],\n      }\n    }\n  })\n  listenerApi.dispatch(\n    layoutInfoActions.setWidgetLayoutInfoReducer(\n      setWidgetLayoutInfoReducerActionPayload,\n    ),\n  )\n}\n\nexport function setupLayoutInfoListeners(\n  startListening: AppStartListening,\n): Unsubscribe {\n  const subscriptions = [\n    startListening({\n      actionCreator: layoutInfoActions.updateWidgetLayoutInfoReducer,\n      effect: handleUpdateReflowEffect,\n    }),\n    startListening({\n      matcher: isAnyOf(\n        componentsActions.deleteComponentNodeReducer,\n        componentsActions.addTargetPageSectionReducer,\n        componentsActions.deleteTargetPageSectionReducer,\n        componentsActions.addPageNodeWithSortOrderReducer,\n        componentsActions.deletePageNodeReducer,\n        componentsActions.addSectionViewReducer,\n        componentsActions.addSectionViewConfigByConfigReducer,\n        componentsActions.deleteSectionViewReducer,\n        componentsActions.addModalComponentReducer,\n        componentsActions.batchUpdateComponentLayoutInfoWhenReflowReducer,\n        componentsActions.addComponentReducer,\n        componentsActions.updateTargetPageLayoutReducer,\n        componentsActions.updateSectionViewPropsReducer,\n        componentsActions.updateComponentDisplayNameReducer,\n        componentsActions.updateComponentPositionReducer,\n        componentsActions.addSubPageReducer,\n        executionActions.startExecutionReducer,\n      ),\n      effect: handleUpdateWidgetPositionInExecutionLayoutInfo,\n    }),\n  ]\n\n  return () => {\n    subscriptions.forEach((unsubscribe) => unsubscribe())\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/layoutInfo/layoutInfoReducer.ts",
    "content": "import { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport {\n  BatchUpdateWidgetLayoutInfoPayload,\n  LayoutInfoState,\n  UpdateWidgetLayoutInfoPayload,\n} from \"./layoutInfoState\"\n\nexport const setWidgetLayoutInfoReducer: CaseReducer<\n  LayoutInfoState,\n  PayloadAction<LayoutInfoState[\"widgetsLayoutInfo\"]>\n> = (state, action) => {\n  state.widgetsLayoutInfo = action.payload\n}\n\nexport const updateWidgetLayoutInfoReducer: CaseReducer<\n  LayoutInfoState,\n  PayloadAction<UpdateWidgetLayoutInfoPayload>\n> = (state, action) => {\n  if (!state) return\n  const { displayName, layoutInfo } = action.payload\n  const widgetsLayoutInfo = state.widgetsLayoutInfo\n  const currentWidget = widgetsLayoutInfo[displayName]\n  if (!currentWidget || !layoutInfo || Object.keys(layoutInfo).length === 0) {\n    return\n  }\n  currentWidget.layoutInfo = {\n    ...currentWidget.layoutInfo,\n    ...layoutInfo,\n  }\n}\n\nexport const batchUpdateWidgetLayoutInfoReducer: CaseReducer<\n  LayoutInfoState,\n  PayloadAction<BatchUpdateWidgetLayoutInfoPayload[]>\n> = (state, action) => {\n  if (!state) return\n  action.payload.forEach((updateSlice) => {\n    const { displayName, layoutInfo } = updateSlice\n    const widgetsLayoutInfo = state.widgetsLayoutInfo\n    const currentWidget = widgetsLayoutInfo[displayName]\n    if (!currentWidget || !layoutInfo || Object.keys(layoutInfo).length === 0) {\n      return\n    }\n    currentWidget.layoutInfo = {\n      ...currentWidget.layoutInfo,\n      ...layoutInfo,\n    }\n  })\n}\n\nexport const updateWidgetLayoutInfoWhenChangeDisplayNameReducer: CaseReducer<\n  LayoutInfoState,\n  PayloadAction<{ oldDisplayName: string; newDisplayName: string }>\n> = (state, action) => {\n  const { oldDisplayName, newDisplayName } = action.payload\n  const widgetsLayoutInfo = state.widgetsLayoutInfo\n  const currentWidget = widgetsLayoutInfo[oldDisplayName]\n  if (!currentWidget) return\n  delete widgetsLayoutInfo[oldDisplayName]\n  widgetsLayoutInfo[newDisplayName] = currentWidget\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/layoutInfo/layoutInfoSelector.ts",
    "content": "import { createSelector } from \"@reduxjs/toolkit\"\nimport { getCurrentApp } from \"../selector\"\n\nexport const layoutInfo = createSelector(\n  [getCurrentApp],\n  (currentApp) => currentApp.layoutInfo,\n)\n\nexport const getClientWidgetLayoutInfo = createSelector(\n  [layoutInfo],\n  (layoutInfo) => layoutInfo.widgetsLayoutInfo,\n)\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/layoutInfo/layoutInfoSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  batchUpdateWidgetLayoutInfoReducer,\n  setWidgetLayoutInfoReducer,\n  updateWidgetLayoutInfoReducer,\n  updateWidgetLayoutInfoWhenChangeDisplayNameReducer,\n} from \"./layoutInfoReducer\"\nimport { layoutInfoInitialState } from \"./layoutInfoState\"\n\nconst layoutInfoSlice = createSlice({\n  name: \"layoutInfo\",\n  initialState: layoutInfoInitialState,\n  reducers: {\n    setWidgetLayoutInfoReducer,\n    updateWidgetLayoutInfoReducer,\n    batchUpdateWidgetLayoutInfoReducer,\n    updateWidgetLayoutInfoWhenChangeDisplayNameReducer,\n  },\n})\n\nexport const layoutInfoActions = layoutInfoSlice.actions\nexport default layoutInfoSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/layoutInfo/layoutInfoState.ts",
    "content": "import { CONTAINER_TYPE } from \"@illa-public/public-types\"\nimport { LayoutInfo } from \"@/redux/currentApp/components/componentsPayload\"\n\nexport interface WidgetLayoutInfo {\n  displayName: string\n  widgetType: string\n  layoutInfo: LayoutInfo\n  parentNode: string\n  containerType: CONTAINER_TYPE\n  childrenNode: string[]\n}\n\nexport interface LayoutInfoState {\n  widgetsLayoutInfo: Record<string, WidgetLayoutInfo>\n}\n\nexport const layoutInfoInitialState: LayoutInfoState = {\n  widgetsLayoutInfo: {},\n}\n\nexport interface UpdateWidgetLayoutInfoPayload {\n  displayName: string\n  layoutInfo: Partial<LayoutInfo>\n  parentNode: string\n  effectRows?: number\n}\n\nexport interface BatchUpdateWidgetLayoutInfoPayload {\n  displayName: string\n  layoutInfo: Partial<LayoutInfo>\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/layoutInfo/utils.ts",
    "content": "import { WidgetLayoutInfo } from \"./layoutInfoState\"\n\nexport const getAllDescendantNodeDisplayNamesByExecution = (\n  node: WidgetLayoutInfo,\n  widgets: Record<string, WidgetLayoutInfo>,\n) => {\n  const queue = [node]\n  let res: string[] = []\n  while (queue.length > 0) {\n    const head = queue[queue.length - 1]\n    res.push(head.displayName)\n    queue.pop()\n    if (head.childrenNode && Array.isArray(head.childrenNode)) {\n      head.childrenNode.forEach((child) => {\n        if (widgets[child]) {\n          queue.push(widgets[child])\n        }\n      })\n    }\n  }\n  return res\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/selector.ts",
    "content": "import { RootState } from \"../../store\"\n\nexport const getCurrentApp = (state: RootState) => state.currentApp\n"
  },
  {
    "path": "apps/builder/src/redux/currentApp/slice.ts",
    "content": "import { combineReducers } from \"@reduxjs/toolkit\"\nimport actionReducer from \"./action/actionSlice\"\nimport appInfoReducer from \"./appInfo/appInfoSlice\"\nimport collaboratorsReducer from \"./collaborators/collaboratorsSlice\"\nimport componentsReducer from \"./components/componentsSlice\"\nimport cursorSlice from \"./cursor/cursorSlice\"\nimport dragShadowReducer from \"./dragShadow/dragShadowSlice\"\nimport executionReducer from \"./executionTree/executionSlice\"\nimport layoutInfoReducer from \"./layoutInfo/layoutInfoSlice\"\n\nexport const appReducer = combineReducers({\n  components: componentsReducer,\n  action: actionReducer,\n  appInfo: appInfoReducer,\n  collaborators: collaboratorsReducer,\n  execution: executionReducer,\n  cursor: cursorSlice,\n  dragShadow: dragShadowReducer,\n  layoutInfo: layoutInfoReducer,\n})\n"
  },
  {
    "path": "apps/builder/src/redux/currentAppHistory/currentAppHistoryReducer.ts",
    "content": "import { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport { CurrentAppHistory } from \"@/redux/currentAppHistory/currentAppHistoryState\"\n\nexport const initCurrentAppHistoryReducer: CaseReducer<\n  CurrentAppHistory,\n  PayloadAction<CurrentAppHistory>\n> = (state, action) => {\n  const { payload } = action\n  return { ...state, ...payload }\n}\n\nexport const updateCurrentAppHistoryReducer: CaseReducer<\n  CurrentAppHistory,\n  PayloadAction<CurrentAppHistory>\n> = (state, action) => {\n  const { payload } = action\n\n  return {\n    ...state,\n    ...payload,\n    snapshotList: state.snapshotList.concat(payload.snapshotList),\n  }\n}\n\n// update currentSnapshotID\nexport const updateCurrentSnapshotIDReducer: CaseReducer<\n  CurrentAppHistory,\n  PayloadAction<string>\n> = (state, action) => {\n  const { payload } = action\n  state.currentSnapshotID = payload\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentAppHistory/currentAppHistorySelector.ts",
    "content": "import { RootState } from \"@/store\"\n\nexport const getCurrentAppSnapshotList = (state: RootState) => {\n  return state.currentAppHistory.snapshotList\n}\n\nexport const getSnapshotListCurrentPage = (state: RootState) => {\n  return state.currentAppHistory.currentPage\n}\n\nexport const getSnapshotListHasMore = (state: RootState) => {\n  return state.currentAppHistory.hasMore\n}\n\nexport const getCurrentAppSnapshotID = (state: RootState) => {\n  return state.currentAppHistory.currentSnapshotID\n}\n"
  },
  {
    "path": "apps/builder/src/redux/currentAppHistory/currentAppHistorySlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  initCurrentAppHistoryReducer,\n  updateCurrentAppHistoryReducer,\n  updateCurrentSnapshotIDReducer,\n} from \"@/redux/currentAppHistory/currentAppHistoryReducer\"\nimport { CurrentAppHistoryInitialState } from \"@/redux/currentAppHistory/currentAppHistoryState\"\n\nconst currentAppHistorySlice = createSlice({\n  name: \"currentAppHistory\",\n  initialState: CurrentAppHistoryInitialState,\n  reducers: {\n    initCurrentAppHistoryReducer,\n    updateCurrentAppHistoryReducer,\n    updateCurrentSnapshotIDReducer,\n  },\n})\n\nexport const currentAppHistoryActions = currentAppHistorySlice.actions\nexport default currentAppHistorySlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/currentAppHistory/currentAppHistoryState.ts",
    "content": "import { Signal, Target } from \"@/api/ws/ILLA_PROTO\"\n\nexport enum SnapshotTriggerMode {\n  AUTOMATIC = 1,\n  MANUAL = 2,\n}\n\ninterface UserInfo {\n  userID: string\n  nickname: string\n  avatar: string\n  email: string\n}\n\nexport interface ModifyHistory {\n  operation: Signal\n  operationTarget: Target\n  operationTargetName: string\n  operationBroadcastType: string\n  operationBroadcastPayload: Record<any, any>\n  modifiedBy: UserInfo\n  modifiedAt: string\n  operationTargetModifiedAt: string\n}\n\nexport interface Snapshot {\n  teamID: string\n  appID: string\n  snapshotID: string\n  snapshotTriggerMode: SnapshotTriggerMode\n  modifyHistory: ModifyHistory[]\n  targetVersion: number\n  createdAt: string\n}\n\nexport interface SnapshotList {\n  snapshotList: Snapshot[]\n  totalPages: number\n}\n\nexport interface CurrentSnapshotList extends SnapshotList {\n  hasMore: boolean\n  currentPage: number\n}\n\nexport interface CurrentAppHistory extends CurrentSnapshotList {\n  currentSnapshotID?: string\n}\n\nexport const CurrentAppHistoryInitialState: CurrentAppHistory = {\n  snapshotList: [],\n  totalPages: 0,\n  currentPage: 0,\n  hasMore: false,\n}\n"
  },
  {
    "path": "apps/builder/src/redux/guide/guideReducer.ts",
    "content": "import { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport { Guide } from \"@/redux/guide/guideState\"\n\nexport const updateGuideInfoReducer: CaseReducer<\n  Guide,\n  PayloadAction<Guide>\n> = (state, action) => {\n  const { payload } = action\n  return payload\n}\n\nexport const updateCurrentStepReducer: CaseReducer<\n  Guide,\n  PayloadAction<number>\n> = (state, action) => {\n  const { payload } = action\n  state.currentStep = payload\n}\n\nexport const updateNextStepReducer: CaseReducer<Guide> = (state) => {\n  const { currentStep } = state\n  return {\n    ...state,\n    currentStep: currentStep + 1,\n  }\n}\n\nexport const updateInsideStepReducer: CaseReducer<Guide> = (state) => {\n  const { currentStep } = state\n  return {\n    ...state,\n    currentStep: currentStep + 0.1,\n  }\n}\n\nexport const updateGuideStatusReducer: CaseReducer<\n  Guide,\n  PayloadAction<boolean>\n> = (state, action) => {\n  if (!state) return\n  const { payload } = action\n  state.isOpen = payload\n}\n"
  },
  {
    "path": "apps/builder/src/redux/guide/guideSelector.ts",
    "content": "import { createSelector } from \"@reduxjs/toolkit\"\nimport { GUIDE_STEP } from \"@/config/guide/config\"\nimport { RootState } from \"@/store\"\n\nexport const getGuideInfo = (state: RootState) => {\n  return state.guide\n}\n\nexport const getCurrentStep = (state: RootState) => {\n  return state.guide.currentStep\n}\n\nexport const getGuideStatus = (state: RootState) => {\n  return state.guide.isOpen\n}\n\nexport const getCurrentStepInfo = createSelector(\n  [getCurrentStep],\n  (currentStep) => {\n    return GUIDE_STEP[currentStep]\n  },\n)\n"
  },
  {
    "path": "apps/builder/src/redux/guide/guideSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  updateCurrentStepReducer,\n  updateGuideInfoReducer,\n  updateGuideStatusReducer,\n  updateInsideStepReducer,\n  updateNextStepReducer,\n} from \"@/redux/guide/guideReducer\"\nimport { GuideInitialState } from \"@/redux/guide/guideState\"\n\nconst guideSlice = createSlice({\n  name: \"guide\",\n  initialState: GuideInitialState,\n  reducers: {\n    updateGuideInfoReducer,\n    updateCurrentStepReducer,\n    updateGuideStatusReducer,\n    updateInsideStepReducer,\n    updateNextStepReducer,\n  },\n})\n\nexport const guideActions = guideSlice.actions\nexport default guideSlice.reducer\n"
  },
  {
    "path": "apps/builder/src/redux/guide/guideState.ts",
    "content": "export interface Guide {\n  currentStep: number\n  isOpen: boolean\n}\n\nexport const GuideInitialState: Guide = {\n  currentStep: 0,\n  isOpen: false,\n}\n"
  },
  {
    "path": "apps/builder/src/redux/resource/resourceReducer.ts",
    "content": "import { Resource, ResourceContent } from \"@illa-public/public-types\"\nimport { CaseReducer, PayloadAction } from \"@reduxjs/toolkit\"\nimport { ResourceListState } from \"@/redux/resource/resourceState\"\n\nexport const updateResourceListReducer: CaseReducer<\n  ResourceListState,\n  PayloadAction<Resource<ResourceContent>[]>\n> = (_, action) => {\n  return action.payload\n}\n\nexport const addResourceItemReducer: CaseReducer<\n  ResourceListState,\n  PayloadAction<Resource<ResourceContent>>\n> = (state, action) => {\n  state = [action.payload, ...state]\n  return state\n}\n\nexport const updateResourceItemReducer: CaseReducer<\n  ResourceListState,\n  PayloadAction<Resource<ResourceContent>>\n> = (state, action) => {\n  const targetIndex = state.findIndex(\n    (i) => i.resourceID === action.payload.resourceID,\n  )\n  if (targetIndex != -1) {\n    state[targetIndex] = action.payload\n  }\n}\n\nexport const removeResourceItemReducer: CaseReducer<\n  ResourceListState,\n  PayloadAction<string>\n> = (state, action) => {\n  let index = state.findIndex((i) => {\n    return i.resourceID === action.payload\n  })\n  if (index !== -1) {\n    state.splice(index, 1)\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/redux/resource/resourceSelector.ts",
    "content": "import { Resource, ResourceContent } from \"@illa-public/public-types\"\nimport { createSelector } from \"@reduxjs/toolkit\"\nimport { RootState } from \"@/store\"\n\nexport const getAllResources = (state: RootState) => state.resource\n\nexport const getResourceIDMapResource = createSelector(\n  [getAllResources],\n  (allResource) => {\n    const resourceIDMapResource: Record<string, Resource<ResourceContent>> = {}\n    allResource.forEach((resource) => {\n      resourceIDMapResource[resource.resourceID] = resource\n    })\n    return resourceIDMapResource\n  },\n)\n"
  },
  {
    "path": "apps/builder/src/redux/resource/resourceSlice.ts",
    "content": "import { createSlice } from \"@reduxjs/toolkit\"\nimport {\n  addResourceItemReducer,\n  removeResourceItemReducer,\n  updateResourceItemReducer,\n  updateResourceListReducer,\n} from \"@/redux/resource/resourceReducer\"\nimport { resourceInitialState } from \"@/redux/resource/resourceState\"\n\nconst resourceSlice = createSlice({\n  name: \"resource\",\n  initialState: resourceInitialState,\n  reducers: {\n    updateResourceListReducer,\n    addResourceItemReducer,\n    updateResourceItemReducer,\n    removeResourceItemReducer,\n  },\n})\n\nexport default resourceSlice.reducer\nexport const resourceActions = resourceSlice.actions\n"
  },
  {
    "path": "apps/builder/src/redux/resource/resourceState.ts",
    "content": "import {\n  Resource,\n  ResourceContent,\n  ResourceType,\n} from \"@illa-public/public-types\"\n\nexport interface ResourceInitialConfig<T extends ResourceContent> {\n  resourceName: string\n  resourceType: ResourceType\n  content: T\n}\n\nexport type ResourceListState = Resource<ResourceContent>[]\nexport const resourceInitialState: ResourceListState = []\n"
  },
  {
    "path": "apps/builder/src/redux/resource/upstashResource.ts",
    "content": "export const DEFAULT_NAME = \"default\"\nexport const DATABASE_INDEX = 0\n"
  },
  {
    "path": "apps/builder/src/router/config/cloud.tsx",
    "content": "import { getILLACloudURL } from \"@illa-public/utils\"\nimport { lazy } from \"react\"\nimport { redirect } from \"react-router-dom\"\nimport { FullPageLoading } from \"@/components/FullPageLoading\"\nimport { agentLoader } from \"@/router/loader/agentLoader\"\nimport { agentRunLoader } from \"@/router/loader/agentRunLoader\"\nimport { historyLoader } from \"@/router/loader/historyLoader\"\nimport { RoutesObjectPro } from \"../interface\"\nimport { lazyLoad } from \"../utils/lazyLoad\"\nimport { publicRouterConfig, publicTeamChildrenRouter } from \"./public\"\n\nexport const cloudRouter: RoutesObjectPro[] = [\n  {\n    index: true,\n    loader: async () => {\n      return redirect(getILLACloudURL(window.customDomain))\n    },\n  },\n  {\n    path: \"/:teamIdentifier/appHistory/:appId\",\n    element: lazyLoad(\n      lazy(() => import(\"@/page/History\")),\n      <FullPageLoading />,\n    ),\n    needLogin: true,\n    loader: historyLoader,\n  },\n  {\n    path: \"/:ownerTeamIdentifier/ai-agent/:agentID/run\",\n    element: lazyLoad(\n      lazy(() => import(\"@/page/AI/AIAgentRun\")),\n      <FullPageLoading />,\n    ),\n    accessByMobile: true,\n    loader: agentRunLoader,\n  },\n  {\n    path: \"/:teamIdentifier/ai-agent/:agentID?\",\n    needLogin: true,\n    element: lazyLoad(\n      lazy(() => import(\"@/page/AI/AIAgent\")),\n      <FullPageLoading />,\n    ),\n    loader: agentLoader,\n  },\n  ...publicTeamChildrenRouter,\n  ...publicRouterConfig,\n]\n"
  },
  {
    "path": "apps/builder/src/router/config/public.tsx",
    "content": "import { lazy } from \"react\"\nimport { FullPageLoading } from \"@/components/FullPageLoading\"\nimport { ResourceCreate } from \"@/page/Resource/Create\"\nimport { ResourceEdit } from \"@/page/Resource/Edit\"\nimport { ResourceLayout } from \"@/page/Resource/layout\"\nimport { RoutesObjectPro } from \"@/router/interface\"\nimport { lazyLoad } from \"@/router/utils/lazyLoad\"\nimport { deployLoader } from \"../loader/deployLoader\"\nimport { getDashboardResourcesLoader } from \"../loader/resourceEditorLoader\"\n\nexport const publicTeamChildrenRouter: RoutesObjectPro[] = [\n  {\n    path: \"/:teamIdentifier/resource\",\n    element: <ResourceLayout />,\n    children: [\n      {\n        path: \"new/:resourceType\",\n        needLogin: true,\n        element: <ResourceCreate />,\n      },\n      {\n        path: \"edit/:resourceID\",\n        needLogin: true,\n        loader: getDashboardResourcesLoader,\n        element: <ResourceEdit />,\n      },\n    ] as RoutesObjectPro[],\n  },\n  {\n    path: \"/:teamIdentifier/app/:appId\",\n    element: lazyLoad(lazy(() => import(\"@/page/App\"))),\n    needLogin: true,\n    errorElement: lazyLoad(lazy(() => import(\"@/page/Status/404\"))),\n  },\n  {\n    path: \"/:teamIdentifier/deploy/app/:appId/:pageName?/:viewPath?\",\n    element: lazyLoad(\n      lazy(() => import(\"@/page/Deploy\")),\n      <FullPageLoading />,\n    ),\n    accessByMobile: true,\n    errorElement: lazyLoad(lazy(() => import(\"@/page/Status/404\"))),\n    loader: deployLoader,\n    shouldRevalidate: (args) => {\n      const { currentParams, nextParams } = args\n      return currentParams.appId !== nextParams.appId\n    },\n  },\n  {\n    path: \"/:teamIdentifier/guide\",\n    element: lazyLoad(lazy(() => import(\"@/page/Template/GuideApp\"))),\n    errorElement: lazyLoad(lazy(() => import(\"@/page/Status/404\"))),\n    needLogin: true,\n  },\n]\n\nexport const publicRouterConfig: RoutesObjectPro[] = [\n  {\n    path: \"/403\",\n    element: lazyLoad(lazy(() => import(\"@/page/Status/403\"))),\n    accessByMobile: true,\n  },\n  {\n    path: \"/500\",\n    element: lazyLoad(lazy(() => import(\"@/page/Status/500\"))),\n    accessByMobile: true,\n  },\n  {\n    path: \"/*\",\n    element: lazyLoad(lazy(() => import(\"@/page/Status/404\"))),\n    accessByMobile: true,\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/router/config/selfHost.tsx",
    "content": "import { getILLACloudURL } from \"@illa-public/utils\"\nimport { redirect } from \"react-router-dom\"\nimport { RoutesObjectPro } from \"../interface\"\nimport { publicRouterConfig, publicTeamChildrenRouter } from \"./public\"\n\nexport const selfRouter: RoutesObjectPro[] = [\n  {\n    index: true,\n    loader: async () => {\n      return redirect(getILLACloudURL())\n    },\n  },\n  ...publicTeamChildrenRouter,\n  ...publicRouterConfig,\n]\n"
  },
  {
    "path": "apps/builder/src/router/constant.ts",
    "content": "export const needSavedSearchParams = [\n  \"inviteToken\",\n  \"email\",\n  \"appID\",\n  \"teamIdentifier\",\n  \"token\",\n  \"redirectPage\",\n]\n"
  },
  {
    "path": "apps/builder/src/router/index.tsx",
    "content": "import { createBrowserRouter } from \"react-router-dom\"\nimport { LayoutAutoChange } from \"@/components/LayoutAutoChange\"\nimport { RoutesObjectPro } from \"@/router/interface\"\nimport { routerConfig } from \"@/router/routerConfig\"\nimport { beautifyURLLoader } from \"./loader/beautifyURLLoader\"\nimport { setTokenToLocalStorageLoader } from \"./loader/cloudAuthLoader\"\nimport { combineCloudAuthLoader } from \"./loader/index\"\n\nconst wrappedRouter = (\n  routesConfig: RoutesObjectPro[],\n  _isChildren?: boolean,\n) => {\n  return routesConfig.map((routeItem: RoutesObjectPro) => {\n    const {\n      element,\n      children,\n      needLogin,\n      loader: originLoader,\n      ...otherRouteProps\n    } = routeItem\n    const newRouteItem: RoutesObjectPro = {\n      ...otherRouteProps,\n    }\n    if (!newRouteItem.accessByMobile) {\n      newRouteItem.element = <LayoutAutoChange desktopPage={element} />\n    } else {\n      newRouteItem.element = <>{element}</>\n    }\n    newRouteItem.loader = async (args) => {\n      await setTokenToLocalStorageLoader(args)\n      const beautifyURLResponse = await beautifyURLLoader(args)\n      if (beautifyURLResponse) {\n        return beautifyURLResponse\n      }\n      let authLoaderResponse\n      if (needLogin) {\n        authLoaderResponse = await combineCloudAuthLoader(args)\n      }\n      if (authLoaderResponse) {\n        return authLoaderResponse\n      }\n      if (originLoader) {\n        return await originLoader(args)\n      }\n      return null\n    }\n    if (Array.isArray(children) && children.length) {\n      newRouteItem.children = wrappedRouter(children, true)\n    }\n\n    return newRouteItem\n  })\n}\n\nexport const ILLARoute = createBrowserRouter(wrappedRouter(routerConfig), {\n  basename: import.meta.env.ILLA_BASE_PATH ?? \"/\",\n})\n"
  },
  {
    "path": "apps/builder/src/router/interface.ts",
    "content": "import { RouteObject } from \"react-router-dom\"\n\nexport type RoutesObjectPro = RouteObject & {\n  /**\n   * @description need login, if use check role,can replace this\n   */\n  needLogin?: boolean\n  /**\n   * @description child route\n   */\n  children?: RoutesObjectPro[]\n  accessByMobile?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/router/loader/agentLoader.ts",
    "content": "import { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { LoaderFunction, defer } from \"react-router-dom\"\nimport { AgentInitial } from \"@/page/AI/AIAgent/interface\"\nimport { fetchAgentDetail } from \"@/services/agent\"\nimport store from \"@/store\"\n\nconst getAgentInitData = async (agentID?: string) => {\n  if (agentID) {\n    const agent = await fetchAgentDetail(agentID)\n    return {\n      agent: agent.data,\n    }\n  } else {\n    const currentTeamInfo = getCurrentTeamInfo(store.getState())!!\n    return {\n      agent: {\n        ...AgentInitial,\n        teamID: currentTeamInfo.id,\n        teamIdentifier: currentTeamInfo.identifier,\n        teamIcon: currentTeamInfo.icon,\n      },\n    }\n  }\n}\nexport const agentLoader: LoaderFunction = async (args) => {\n  const { agentID } = args.params\n  return defer({\n    data: getAgentInitData(agentID),\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/router/loader/agentRunLoader.ts",
    "content": "import { getAIAgentMarketplaceInfo } from \"@illa-public/market-agent\"\nimport { ILLAMixpanel } from \"@illa-public/mixpanel-utils\"\nimport { getCurrentTeamInfo, teamActions } from \"@illa-public/user-data\"\nimport { LoaderFunction, defer, redirect } from \"react-router-dom\"\nimport {\n  fetchAgentContributeState,\n  fetchAgentDetail,\n  fetchContributedAgentDetail,\n} from \"@/services/agent\"\nimport { fetchMyTeamsInfo } from \"@/services/team\"\nimport store from \"@/store\"\nimport { getUserInfoLoader } from \"./cloudAuthLoader\"\n\nconst fetchAgentFullData = async (\n  agentId: string,\n  ownerTeamIdentifier: string,\n  myTeamIdentifier: string,\n) => {\n  const teamInfo = getCurrentTeamInfo(store.getState())\n\n  if (!teamInfo) {\n    const info = await fetchMyTeamsInfo()\n    const currentTeamInfo = info.data.find(\n      (item) => item.identifier === myTeamIdentifier,\n    )\n    if (currentTeamInfo) {\n      store.dispatch(teamActions.updateCurrentIdReducer(currentTeamInfo.id))\n      ILLAMixpanel.setGroup(myTeamIdentifier)\n      store.dispatch(teamActions.updateTeamItemsReducer(info.data))\n    } else {\n      return redirect(\"/404\")\n    }\n  }\n\n  const isContribute = await fetchAgentContributeState(\n    agentId,\n    ownerTeamIdentifier,\n  )\n\n  let agent, marketplace\n\n  if (isContribute.data.isPublishedToMarketplace) {\n    agent = await fetchContributedAgentDetail(agentId, ownerTeamIdentifier)\n    marketplace = await getAIAgentMarketplaceInfo(agentId)\n    return {\n      agent: agent.data,\n      marketplace: marketplace.data,\n    }\n  } else {\n    agent = await fetchAgentDetail(agentId)\n    return {\n      agent: agent.data,\n      marketplace: undefined,\n    }\n  }\n}\n\nexport const agentRunLoader: LoaderFunction = async (args) => {\n  await getUserInfoLoader(args)\n  const { agentID, ownerTeamIdentifier } = args.params\n  const myTeamIdentifier = new URL(args.request.url).searchParams.get(\n    \"myTeamIdentifier\",\n  )\n\n  if (agentID && ownerTeamIdentifier && myTeamIdentifier) {\n    return defer({\n      data: fetchAgentFullData(agentID, ownerTeamIdentifier, myTeamIdentifier),\n    })\n  } else {\n    return redirect(\"/404\")\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/router/loader/beautifyURLLoader.ts",
    "content": "import { LoaderFunctionArgs } from \"react-router-dom\"\nimport { needSavedSearchParams } from \"../constant\"\nimport { removeIgnoredQS } from \"../utils/translateQS\"\n\nexport const beautifyURLLoader = async (args: LoaderFunctionArgs) => {\n  const { request } = args\n  const url = new URL(request.url)\n  const searchParams = url.searchParams\n\n  let canRedirect = false\n  for (let i = 0; i < needSavedSearchParams.length; i++) {\n    if (searchParams.has(needSavedSearchParams[i])) {\n      canRedirect = true\n      break\n    }\n  }\n\n  const qs = removeIgnoredQS(searchParams)\n\n  if (canRedirect) {\n    url.search = qs\n    window.history.replaceState(null, \"\", url.toString())\n  }\n  return null\n}\n"
  },
  {
    "path": "apps/builder/src/router/loader/cloudAuthLoader.ts",
    "content": "import { ILLAMixpanel } from \"@illa-public/mixpanel-utils\"\nimport {\n  currentUserActions,\n  getCurrentTeamInfo,\n  getCurrentUser,\n  getPlanUtils,\n  teamActions,\n} from \"@illa-public/user-data\"\nimport { canAccessManage } from \"@illa-public/user-role-utils\"\nimport {\n  getAuthToken,\n  getILLACloudURL,\n  isCloudVersion,\n  sendConfigEvent,\n  setAuthToken,\n} from \"@illa-public/utils\"\nimport { LoaderFunction, redirect } from \"react-router-dom\"\nimport i18n from \"@/i18n/config\"\nimport { fetchMyTeamsInfo } from \"@/services/team\"\nimport { fetchUserInfo } from \"@/services/users\"\nimport store from \"@/store\"\n\nexport const setTokenToLocalStorageLoader: LoaderFunction = async (args) => {\n  const url = new URL(args.request.url)\n  const searchParams = url.searchParams\n  const token = searchParams.get(\"token\")\n  if (token) {\n    setAuthToken(token)\n  }\n  return null\n}\n\nexport const getUserInfoLoader: LoaderFunction = async () => {\n  const authToken = getAuthToken()\n  const userInfo = getCurrentUser(store.getState())\n  const currentLng = window.localStorage.getItem(\"i18nextLng\")\n\n  if (userInfo.userID) {\n    const lng = userInfo.language\n    if (lng && currentLng !== lng) {\n      i18n.changeLanguage(lng)\n      window.location.reload()\n    }\n    return null\n  }\n  if (authToken) {\n    try {\n      const response = await fetchUserInfo()\n      sendConfigEvent(response?.data.userID)\n      const lng = response.data.language\n      if (lng && currentLng !== lng) {\n        i18n.changeLanguage(lng)\n        window.location.reload()\n      }\n      ILLAMixpanel.setUserID(response.data.userID)\n      const reportedUserInfo: Record<string, any> = {}\n      Object.entries(response.data).forEach(([key, value]) => {\n        reportedUserInfo[`illa_${key}`] = value\n      })\n      ILLAMixpanel.setUserProperties(reportedUserInfo)\n      store.dispatch(currentUserActions.updateCurrentUserReducer(response.data))\n      return null\n    } catch (e) {\n      ILLAMixpanel.reset()\n      return redirect(\"/403\")\n    }\n  }\n  return redirect(\"/403\")\n}\n\nexport const getTeamsInfoLoader: LoaderFunction = async (args) => {\n  const { params } = args\n  const { teamIdentifier } = params\n  const currentTeamInfoInDisk = getCurrentTeamInfo(store.getState())\n  if (currentTeamInfoInDisk?.id) {\n    return null\n  }\n  if (!teamIdentifier) {\n    return redirect(\"/403\")\n  }\n  const response = await fetchMyTeamsInfo()\n  const teamsInfo = response.data ?? []\n  let currentTeamInfo = teamsInfo.find(\n    (item) => item.identifier === teamIdentifier,\n  )\n  if (window.currentTeamIdentifier) {\n    currentTeamInfo = teamsInfo.find(\n      (item) => item.identifier === teamIdentifier,\n    )\n  }\n\n  if (currentTeamInfo) {\n    store.dispatch(teamActions.updateCurrentIdReducer(currentTeamInfo.id))\n    store.dispatch(teamActions.updateTeamItemsReducer(teamsInfo))\n    ILLAMixpanel.setGroup(currentTeamInfo.identifier)\n    if (\n      isCloudVersion &&\n      !canAccessManage(\n        currentTeamInfo.myRole,\n        getPlanUtils(currentTeamInfo),\n        currentTeamInfo.totalTeamLicense.teamLicenseAllPaid,\n      )\n    ) {\n      return redirect(\n        `${getILLACloudURL(window.customDomain)}/workspace/${\n          currentTeamInfo.identifier\n        }`,\n      )\n    }\n    return null\n  }\n  return redirect(\"/403\")\n}\n"
  },
  {
    "path": "apps/builder/src/router/loader/deployLoader.ts",
    "content": "import { currentUserActions } from \"@illa-public/user-data\"\nimport { sendConfigEvent } from \"@illa-public/utils\"\nimport { LoaderFunction, defer, redirect } from \"react-router-dom\"\nimport {\n  fetchAPPPublicStatus,\n  fetchPrivateAppInitData,\n  fetchPubicAppInitData,\n} from \"@/services/apps\"\nimport { fetchUserInfo, tryFetchUserInfo } from \"@/services/users\"\nimport store from \"@/store\"\nimport { getTeamsInfoLoader } from \"./cloudAuthLoader\"\n\nexport const deployLoader: LoaderFunction = async (args) => {\n  const { appId, teamIdentifier } = args.params\n  if (!appId || !teamIdentifier) {\n    return redirect(\"/404\")\n  }\n\n  try {\n    const publicStateResponse = await fetchAPPPublicStatus(\n      appId,\n      teamIdentifier,\n      args.request.signal,\n    )\n\n    const isPublic = publicStateResponse.data.isPublic\n    if (isPublic) {\n      const userInfo = await tryFetchUserInfo()\n      if (userInfo) {\n        store.dispatch(\n          currentUserActions.updateCurrentUserReducer(userInfo.data),\n        )\n      }\n      const appInfo = fetchPubicAppInitData(\n        appId,\n        \"-2\",\n        teamIdentifier,\n        args.request.signal,\n      )\n      return defer({\n        isPublic,\n        appInfo,\n      })\n    } else {\n      const teamInfoLoaderResponse = await getTeamsInfoLoader(args)\n      if (teamInfoLoaderResponse) {\n        return teamInfoLoaderResponse\n      }\n      const userInfo = await fetchUserInfo()\n      sendConfigEvent(userInfo?.data.userID)\n      store.dispatch(currentUserActions.updateCurrentUserReducer(userInfo.data))\n      const appInfo = fetchPrivateAppInitData(appId, \"-2\", args.request.signal)\n      return defer({\n        isPublic,\n        appInfo,\n      })\n    }\n  } catch (e) {\n    return redirect(\"/404\")\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/router/loader/historyLoader.ts",
    "content": "import { LoaderFunction, redirect } from \"react-router-dom\"\nimport { currentAppHistoryActions } from \"@/redux/currentAppHistory/currentAppHistorySlice\"\nimport { fetchSnapShotList } from \"@/services/history\"\nimport store from \"@/store\"\n\nconst INITIAL_PAGE = 1\nexport const historyLoader: LoaderFunction = async (args) => {\n  const { appId } = args.params\n  if (!appId) {\n    return redirect(\"/404\")\n  }\n  try {\n    const { data } = await fetchSnapShotList({\n      page: INITIAL_PAGE,\n      appID: appId,\n      signal: args.request.signal,\n    })\n    const currentSnapshotID = data.snapshotList[0].snapshotID\n    store.dispatch(\n      currentAppHistoryActions.initCurrentAppHistoryReducer({\n        ...data,\n        hasMore: data.totalPages !== INITIAL_PAGE,\n        currentPage: INITIAL_PAGE,\n        currentSnapshotID,\n      }),\n    )\n    return null\n  } catch (e) {\n    return redirect(\"/404\")\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/router/loader/index.ts",
    "content": "import { LoaderFunction, redirect } from \"react-router-dom\"\nimport { beautifyURLLoader } from \"./beautifyURLLoader\"\nimport { getTeamsInfoLoader, getUserInfoLoader } from \"./cloudAuthLoader\"\n\nexport const combineCloudAuthLoader: LoaderFunction = async (args) => {\n  try {\n    const userInfoResponse = await getUserInfoLoader(args)\n    const teamsInfoResponse = await getTeamsInfoLoader(args)\n    if (userInfoResponse || teamsInfoResponse) {\n      return userInfoResponse || teamsInfoResponse\n    }\n    return await beautifyURLLoader(args)\n  } catch (e) {\n    return redirect(\"/403\")\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/router/loader/resourceEditorLoader.ts",
    "content": "import { LoaderFunction, redirect } from \"react-router-dom\"\nimport { resourceActions } from \"@/redux/resource/resourceSlice\"\nimport { fetchResources } from \"@/services/resource\"\nimport store from \"@/store\"\n\nexport const getDashboardResourcesLoader: LoaderFunction = async ({\n  request,\n}) => {\n  try {\n    const response = await fetchResources(request.signal)\n    store.dispatch(resourceActions.updateResourceListReducer(response.data))\n    return null\n  } catch {\n    return redirect(\"/500\")\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/router/routerConfig.tsx",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport { RoutesObjectPro } from \"@/router/interface\"\nimport { cloudRouter } from \"./config/cloud\"\nimport { selfRouter } from \"./config/selfHost\"\n\nexport const routerConfig: RoutesObjectPro[] = isCloudVersion\n  ? cloudRouter\n  : selfRouter\n"
  },
  {
    "path": "apps/builder/src/router/utils/lazyLoad.tsx",
    "content": "import { LazyExoticComponent, ReactNode, Suspense } from \"react\"\n\nexport function lazyLoad(\n  Comp: LazyExoticComponent<any>,\n  fallback?: ReactNode,\n): ReactNode {\n  return (\n    <Suspense fallback={fallback}>\n      <Comp />\n    </Suspense>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/router/utils/translateQS.ts",
    "content": "import { needSavedSearchParams } from \"../constant\"\n\nexport const getQS = (searchParams: URLSearchParams) => {\n  const qs = searchParams.toString()\n  return qs ? `?${qs}` : \"\"\n}\n\nexport const removeIgnoredQS = (searchParams: URLSearchParams) => {\n  needSavedSearchParams.forEach((key) => {\n    searchParams.delete(key)\n  })\n  return getQS(searchParams)\n}\n"
  },
  {
    "path": "apps/builder/src/services/action.ts",
    "content": "import {\n  actionBasicRequest,\n  actionRequest,\n  builderRequest,\n  notNeedAuthAxios,\n} from \"@illa-public/illa-net\"\nimport { BUILDER_REQUEST_PREFIX } from \"@illa-public/illa-net/constant\"\nimport { ActionContent, ActionType } from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { AxiosRequestConfig, Method } from \"axios\"\nimport { getParamsFromIllaRoute } from \"@/utils/routerHelper\"\nimport { getCurrentTeamID, getCurrentTeamIdentifier } from \"../utils/team\"\n\ninterface IActionRunResultRequestData {\n  resourceID: string\n  actionType: ActionType\n  displayName: string\n  content: ActionContent\n}\n\nexport interface IActionRunResultResponseData<R = Record<string, any>[]> {\n  Rows: R\n  Extra: Record<string, any> | null\n  Success: boolean\n}\n\nexport const fetchActionRunResult = (\n  appID: string,\n  actionID: string,\n  data: IActionRunResultRequestData,\n  isPublic: boolean,\n  abortSignal?: AbortSignal,\n) => {\n  let url: string\n  let options: { teamIdentifier?: string; teamID?: string } = {}\n  if (isPublic) {\n    url = `/apps/${appID}/publicActions/${actionID}/run`\n    options.teamIdentifier = getCurrentTeamIdentifier()\n  } else {\n    url = `/apps/${appID}/actions/${actionID}/run`\n    options.teamID = getCurrentTeamID()\n  }\n  return actionRequest<IActionRunResultResponseData>(\n    { url, method: \"POST\", data, signal: abortSignal },\n    options,\n  )\n}\n\nexport const fetchS3ActionRunResult = (\n  url: string,\n  method: Method,\n  headers: AxiosRequestConfig[\"headers\"],\n  data?: unknown,\n) => {\n  return notNeedAuthAxios({\n    baseURL: url,\n    method,\n    headers,\n    data,\n  })\n}\n\nexport const fetchCreateAction = (\n  data: Omit<ActionItem<ActionContent>, \"actionID\">,\n) => {\n  const appId = getParamsFromIllaRoute(\"appId\") as string\n  const url = `/apps/${appId}/actions`\n  return builderRequest<\n    ActionItem<ActionContent>,\n    Omit<ActionItem<ActionContent>, \"actionID\">\n  >(\n    {\n      url,\n      method: \"POST\",\n      data,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\ninterface IDeleteActionResponse {\n  actionID: string\n}\n\nexport const fetchDeleteAction = (actionID: string) => {\n  const appId = getParamsFromIllaRoute(\"appId\") as string\n  const url = `/apps/${appId}/actions/${actionID}`\n  return builderRequest<IDeleteActionResponse>(\n    {\n      url,\n      method: \"DELETE\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchDownloadFileFromURL = (url: string) => {\n  return actionBasicRequest({\n    url,\n    method: \"GET\",\n  })\n}\n\nexport const fetchUpdateAction = (action: ActionItem<ActionContent>) => {\n  const appId = getParamsFromIllaRoute(\"appId\") as string\n  return builderRequest<ActionItem<ActionContent>>(\n    {\n      method: \"PUT\",\n      url: `/apps/${appId}/actions/${action.actionID}`,\n      data: action,\n    },\n    { teamID: getCurrentTeamID() },\n  )\n}\n\nexport const fetchBatchUpdateAction = (\n  actions: ActionItem<ActionContent>[],\n) => {\n  const appId = getParamsFromIllaRoute(\"appId\") as string\n  return builderRequest<{\n    actions: ActionItem<ActionContent>[]\n  }>(\n    {\n      method: \"PUT\",\n      url: `/apps/${appId}/actions/byBatch`,\n      data: {\n        actions: actions,\n      },\n    },\n    { teamID: getCurrentTeamID() },\n  )\n}\n\ninterface IGenerateSQLRequest {\n  description: string | undefined\n  resourceID: string | undefined\n  action: number\n}\n\ninterface IGenerateSQLResponse {\n  payload: string\n}\n\nexport const fetchGenerateSQL = async (\n  appID: string,\n  data: IGenerateSQLRequest,\n) => {\n  return actionRequest<IGenerateSQLResponse>(\n    {\n      url: `/apps/${appID}/internalActions/generateSQL`,\n      method: \"POST\",\n      data,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n    BUILDER_REQUEST_PREFIX,\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/services/agent.ts",
    "content": "import { agentRequest, marketplaceRequest } from \"@illa-public/illa-net\"\nimport { Agent, AgentRaw } from \"@illa-public/public-types\"\nimport { v4 } from \"uuid\"\nimport { base642Blob, getFileExtensionFromBase64 } from \"@/utils/file\"\nimport { upload } from \"@/utils/file\"\nimport { getCurrentTeamID } from \"@/utils/team\"\n\nexport interface TeamAgentListData {\n  aiAgentList: Agent[]\n  totalAIAgentCount: number\n  totalPages: number\n}\n\nexport const fetchTeamAgent = (signal?: AbortSignal) => {\n  return agentRequest<TeamAgentListData>(\n    {\n      url: `/aiAgent/list/sortBy/updatedAt`,\n      method: \"GET\",\n      signal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport interface ForkAgentResponse {\n  aiAgentID: string\n}\n\nexport const forkAIAgentToTeam = (aiAgentID: string) => {\n  const teamID = getCurrentTeamID()\n  return agentRequest<Agent>({\n    url: `/aiAgent/${aiAgentID}/forkTo/teams/${teamID}`,\n    method: \"POST\",\n  })\n}\n\nexport const starAIAgent = (aiAgentID: string) => {\n  return marketplaceRequest<{}>({\n    url: `/aiAgents/${aiAgentID}/star`,\n    method: \"POST\",\n  })\n}\n\nexport const unstarAIAgent = (aiAgentID: string) => {\n  return marketplaceRequest<{}>({\n    url: `/aiAgents/${aiAgentID}/star`,\n    method: \"DELETE\",\n  })\n}\n\nexport const deleteAIAgent = (aiAgentID: string) => {\n  return agentRequest<ForkAgentResponse>(\n    {\n      url: `/aiAgent/${aiAgentID}`,\n      method: \"DELETE\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const duplicateAIAgent = (aiAgentID: string) => {\n  return agentRequest<Agent>(\n    {\n      url: `/aiAgent/${aiAgentID}/duplicate`,\n      method: \"POST\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchAgentContributeState = (\n  aiAgentID: string,\n  ownerTeamIdentifier: string,\n) => {\n  return agentRequest<{\n    isPublishedToMarketplace: boolean\n  }>({\n    url: `/teams/byIdentifier/${ownerTeamIdentifier}/publicAIAgent/${aiAgentID}/isPublishedToMarketplace`,\n    method: \"GET\",\n  })\n}\n\nexport const fetchAgentDetail = (aiAgentID: string) => {\n  return agentRequest<Agent>(\n    {\n      url: `/aiAgent/${aiAgentID}`,\n      method: \"GET\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchContributedAgentDetail = (\n  aiAgentID: string,\n  ownerTeamIdentifier: string,\n) => {\n  return agentRequest<Agent>({\n    url: `/teams/byIdentifier/${ownerTeamIdentifier}/publicAIAgent/${aiAgentID}`,\n    method: \"GET\",\n  })\n}\n\nexport const putAgentDetail = (aiAgentID: string, agentRaw: AgentRaw) => {\n  return agentRequest<Agent, AgentRaw>(\n    {\n      url: `/aiAgent/${aiAgentID}`,\n      method: \"PUT\",\n      data: agentRaw,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const createAgent = (agentRaw: AgentRaw) => {\n  return agentRequest<Agent, AgentRaw>(\n    {\n      url: `/aiAgent`,\n      method: \"POST\",\n      data: agentRaw,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\n// send raw without variables\nexport const generateDescription = (prompt: string) => {\n  return agentRequest<\n    {\n      payload: string\n    },\n    {\n      prompt: string\n    }\n  >(\n    {\n      url: `/aiAgent/generatePromptDescription`,\n      method: \"POST\",\n      data: {\n        prompt: encodeURIComponent(prompt),\n      },\n      timeout: 600000,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const getAIAgentWsAddress = (\n  aiAgentID: string,\n  signal?: AbortSignal,\n) => {\n  return agentRequest<{\n    aiAgentConnectionAddress: string\n  }>(\n    {\n      url: `/aiAgent/${aiAgentID}/connectionAddress`,\n      method: \"GET\",\n      signal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const getAIAgentAnonymousAddress = (signal?: AbortSignal) => {\n  return agentRequest<{\n    aiAgentConnectionAddress: string\n  }>(\n    {\n      url: `/aiAgentAnonymous/connectionAddress`,\n      method: \"GET\",\n      signal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport interface UploadResponse {\n  uploadAddress: string\n}\n\nexport const uploadAgentIcon = async (base64: string) => {\n  const fileName = v4()\n  const type = getFileExtensionFromBase64(base64)\n  const address = await agentRequest<UploadResponse>(\n    {\n      url: `/aiAgent/icon/uploadAddress/fileName/${fileName}.${type}`,\n      method: \"GET\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n  const file = await base642Blob(base64)\n  return await upload(address.data.uploadAddress, file)\n}\n"
  },
  {
    "path": "apps/builder/src/services/apps.ts",
    "content": "import { fetchBatchCreateAction } from \"@illa-public/create-app\"\nimport { builderRequest } from \"@illa-public/illa-net\"\nimport { AppInfoShape, ComponentTreeNode } from \"@illa-public/public-types\"\nimport { DeployResp } from \"@/page/App/Module/PageNavBar/resp\"\nimport { CurrentAppResp } from \"@/page/App/resp/currentAppResp\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport { getComponentMap } from \"@/redux/currentApp/components/componentsSelector\"\nimport store from \"@/store\"\nimport { buildTreeByMapNode } from \"../utils/componentNode/flatTree\"\nimport { getCurrentTeamID } from \"../utils/team\"\n\ninterface IAPPPublicStatus {\n  isPublic: boolean\n}\n\nexport const fetchAPPPublicStatus = async (\n  appID: string,\n  teamIdentifier?: string,\n  signal?: AbortSignal,\n) => {\n  return builderRequest<IAPPPublicStatus>(\n    {\n      url: `/publicApps/${appID}/isPublic`,\n      method: \"GET\",\n      signal: signal,\n    },\n    {\n      teamIdentifier: teamIdentifier,\n    },\n  )\n}\n\nexport const fetchPubicAppInitData = (\n  appID: string,\n  versionID: string,\n  teamIdentifier?: string,\n  signal?: AbortSignal,\n) => {\n  return builderRequest<CurrentAppResp>(\n    {\n      url: `/publicApps/${appID}/versions/${versionID}`,\n      method: \"GET\",\n      signal: signal,\n    },\n    {\n      teamIdentifier: teamIdentifier,\n    },\n  )\n}\n\nexport const fetchPrivateAppInitData = async (\n  appID: string,\n  versionID: string,\n  signal?: AbortSignal,\n) => {\n  return await builderRequest<CurrentAppResp>(\n    {\n      url: `/apps/${appID}/versions/${versionID}`,\n      method: \"GET\",\n      signal: signal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchDeployApp = (appID: string, isPublic?: boolean) => {\n  return builderRequest<DeployResp>(\n    {\n      url: `/apps/${appID}/deploy`,\n      method: \"POST\",\n      data: {\n        public: isPublic,\n      },\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchChangeAppSetting = (\n  appID: string,\n  appName: string,\n  description?: string,\n) => {\n  return builderRequest(\n    {\n      url: `/apps/${appID}`,\n      method: \"PUT\",\n      data: {\n        appName,\n        config: {\n          description,\n        },\n      },\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\ninterface IAppCreateRequestData {\n  appName: string\n  initScheme: ComponentTreeNode\n}\n\nexport const fetchCreateApp = (data: IAppCreateRequestData) => {\n  return builderRequest<AppInfoShape>(\n    {\n      url: \"/apps\",\n      method: \"POST\",\n      data,\n    },\n    { teamID: getCurrentTeamID() },\n  )\n}\n\nexport const fetchDeleteApp = (appID: string) => {\n  return builderRequest<{ appID: string }>(\n    {\n      url: `/apps/${appID}`,\n      method: \"DELETE\",\n    },\n    { teamID: getCurrentTeamID() },\n  )\n}\n\nexport const updateAppPublicConfig = async (\n  isPublic: boolean,\n  appID: string,\n) => {\n  await builderRequest<{}>(\n    {\n      method: \"PATCH\",\n      url: `/apps/${appID}/config`,\n      data: {\n        public: isPublic,\n      },\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n  return true\n}\n\nexport const updateWaterMarkConfig = async (\n  waterMark: boolean,\n  appID: string,\n) => {\n  return builderRequest<AppInfoShape>(\n    {\n      method: \"PATCH\",\n      url: `/apps/${appID}/config`,\n      data: {\n        waterMark,\n      },\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const updateAppConfig = async (\n  appID: string,\n  config: {\n    public?: boolean\n    waterMark?: boolean\n    description?: string\n    appName?: string\n  },\n) => {\n  return builderRequest<AppInfoShape>(\n    {\n      method: \"PATCH\",\n      url: `/apps/${appID}/config`,\n      data: config,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const createApp = async (\n  appName: string,\n  initScheme: ComponentTreeNode,\n) => {\n  const requestData = { appName, initScheme }\n  const response = await fetchCreateApp(requestData)\n  return response.data.appId\n}\n\nexport const forkCurrentApp = async (appName: string) => {\n  const actions = getActionList(store.getState())\n  const componentsMap = getComponentMap(store.getState())\n  // fork app\n  // TODO: need check\n  const appId = await createApp(\n    appName,\n    buildTreeByMapNode(\"root\", componentsMap),\n  )\n  // fork actions\n  await fetchBatchCreateAction(getCurrentTeamID()!, appId, actions)\n  return appId\n}\n\nexport const fetchCopyApp = (appID: string, name: string) => {\n  return builderRequest<AppInfoShape>(\n    {\n      url: `/apps/${appID}/duplication`,\n      method: \"POST\",\n      data: {\n        appName: name,\n      },\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchForkApp = (appID: string) => {\n  const teamID = getCurrentTeamID()\n  return builderRequest<{ appId: string }>({\n    url: `/apps/${appID}/forkTo/teams/${teamID}`,\n    method: \"POST\",\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/services/drive.ts",
    "content": "import { driveRequest, publicDriveRequest } from \"@illa-public/illa-net\"\nimport {\n  DRIVE_FILE_TYPE,\n  DUPLICATION_HANDLER,\n  EXPIRATION_TYPE,\n  FILE_CATEGORY,\n  GCS_OBJECT_TYPE,\n  SORTED_TYPE,\n  UPLOAD_FILE_DUPLICATION_HANDLER,\n  UPLOAD_FILE_STATUS,\n} from \"@illa-public/public-types\"\nimport { stringify } from \"qs\"\nimport { getCurrentTeamID, getCurrentTeamIdentifier } from \"../utils/team\"\n\ninterface IFetchUploadFilesToAnonymousFolderRequest {\n  name: string\n  type: GCS_OBJECT_TYPE\n  contentType: string\n  size: number\n  duplicationHandler: UPLOAD_FILE_DUPLICATION_HANDLER\n}\n\ninterface IFetchUploadFilesToAnonymousFolderResponse {\n  id: string\n  name: string\n  folderID: string\n  type: GCS_OBJECT_TYPE\n  resumable: boolean\n  url: string\n}\n\nexport const fetchUploadFilesToAnonymous = async (\n  appID: string,\n  requestData: IFetchUploadFilesToAnonymousFolderRequest,\n  abortSignal?: AbortSignal,\n) => {\n  return await driveRequest<IFetchUploadFilesToAnonymousFolderResponse>(\n    {\n      url: `/apps/${appID}/files`,\n      method: \"POST\",\n      data: {\n        ...requestData,\n        resumable: true,\n      },\n      signal: abortSignal,\n    },\n    {\n      teamIdentifier: getCurrentTeamIdentifier(),\n    },\n  )\n}\n\nexport const fetchUploadFilesStatusAnonymous = async (\n  appID: string,\n  fileID: string,\n  status: UPLOAD_FILE_STATUS,\n) => {\n  return await driveRequest(\n    {\n      url: `/apps/${appID}/files/${fileID}/status`,\n      method: \"PUT\",\n      data: {\n        status,\n      },\n    },\n    {\n      teamIdentifier: getCurrentTeamIdentifier(),\n    },\n  )\n}\n\ninterface IFetchGetUploadFileURLRequest {\n  name: string\n  type: GCS_OBJECT_TYPE\n  contentType: string\n  size: number\n  folderID: string\n  duplicationHandler: UPLOAD_FILE_DUPLICATION_HANDLER\n}\n\ninterface IFetchUploadFileURLResponse {\n  id: string\n  name: string\n  folderID: string\n  type: GCS_OBJECT_TYPE\n  resumable: boolean\n  url: string\n}\n\nexport const fetchGetUploadFileURL = async (\n  requestData: IFetchGetUploadFileURLRequest,\n  abortSignal?: AbortSignal,\n) => {\n  return await driveRequest<IFetchUploadFileURLResponse>(\n    {\n      url: `/files`,\n      method: \"POST\",\n      data: {\n        ...requestData,\n        resumable: true,\n      },\n      signal: abortSignal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchUpdateFileStatus = async (\n  fileID: string,\n  status: UPLOAD_FILE_STATUS,\n) => {\n  return await driveRequest(\n    {\n      url: `/files/${fileID}/status`,\n      method: \"PUT\",\n      data: {\n        status,\n      },\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\ninterface IFetchDownloadURLByTinyURL {\n  name: string\n  contentType: string\n  size: number\n  downloadURL: string\n  createdAt: string\n  lastModifiedAt: string\n}\n\nexport const fetchDownloadURLByTinyURL = async (\n  tinyURL: string,\n  fileID: string,\n) => {\n  return await publicDriveRequest<IFetchDownloadURLByTinyURL>({\n    url: `/${tinyURL}/${fileID}`,\n    method: \"GET\",\n  })\n}\n\n// -------------------\nexport interface IILLAFileInfo {\n  id: string\n  name: string\n  type: GCS_OBJECT_TYPE\n  contentType: string\n  size: number\n  createdAt: string\n  lastModifiedAt: string\n  lastModifiedBy: string\n  owner: string\n}\n\nexport interface IFetchFileListRequestData {\n  path: string\n  page?: number\n  limit?: number\n  type: DRIVE_FILE_TYPE\n  search?: string\n  sortedBy?: string\n  sortedType?: SORTED_TYPE\n  fileCategory?: FILE_CATEGORY\n}\n\nexport interface IFetchFileListResponseData {\n  path: string\n  currentFolderID: string\n  files: IILLAFileInfo[]\n  total: number\n  pageSize: number\n  pageIndex: number\n}\n\nexport const fetchFileList = async (\n  requestData: IFetchFileListRequestData = {\n    path: \"/root\",\n    type: DRIVE_FILE_TYPE.MIX,\n  },\n  abortSignal?: AbortSignal,\n) => {\n  const qs = stringify(requestData)\n  return await driveRequest<IFetchFileListResponseData>(\n    {\n      url: \"/files?\" + qs,\n      method: \"GET\",\n      signal: abortSignal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\nexport const fetchAnonymousFileList = async (\n  appID: string,\n  requestData: IFetchFileListRequestData = {\n    path: \"/root\",\n    type: DRIVE_FILE_TYPE.MIX,\n  },\n  abortSignal?: AbortSignal,\n) => {\n  const qs = stringify(requestData)\n  return await driveRequest<IFetchFileListResponseData>(\n    {\n      url: `/apps/${appID}/files?${qs}`,\n      method: \"GET\",\n      signal: abortSignal,\n    },\n    {\n      teamIdentifier: getCurrentTeamIdentifier(),\n    },\n  )\n}\n\ninterface IFetchGenerateTinyURLRequestData {\n  ids: string[]\n  expirationType: EXPIRATION_TYPE\n  expiry?: string\n  hotlinkProtection: boolean\n}\n\ninterface IFetchGenerateTinyURLResponseData {\n  tinyURL: string\n  expirationType: EXPIRATION_TYPE\n  expiry?: string\n  hotlinkProtection: boolean\n  createdAt: string\n  createdBy: string\n  cdn: boolean\n}\n\nexport type IFetchGenerateBatchTinyURLResponse =\n  IFetchGenerateTinyURLResponseData & { fileID: string }\nexport const fetchBatchGenerateTinyUrl = async (\n  data: IFetchGenerateTinyURLRequestData,\n  abortSignal?: AbortSignal,\n) => {\n  return await driveRequest<IFetchGenerateBatchTinyURLResponse[]>(\n    {\n      url: \"/links/batch\",\n      method: \"POST\",\n      data,\n      signal: abortSignal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchGenerateTinyUrl = async (\n  data: IFetchGenerateTinyURLRequestData,\n  abortSignal?: AbortSignal,\n) => {\n  return await driveRequest<IFetchGenerateBatchTinyURLResponse>(\n    {\n      url: \"/links\",\n      method: \"POST\",\n      data,\n      signal: abortSignal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchBatchAnonymousGenerateTinyUrl = async (\n  appID: string,\n  data: IFetchGenerateTinyURLRequestData,\n  abortSignal?: AbortSignal,\n) => {\n  return await driveRequest<IFetchGenerateBatchTinyURLResponse[]>(\n    {\n      url: `/apps/${appID}/links/batch`,\n      method: \"POST\",\n      data,\n      signal: abortSignal,\n    },\n    {\n      teamIdentifier: getCurrentTeamIdentifier(),\n    },\n  )\n}\n\nexport interface IFetchAnonymousPermissionResponseData {\n  anonymous: boolean\n}\n\nexport const fetchAnonymousPermission = async () => {\n  return await driveRequest<IFetchAnonymousPermissionResponseData>(\n    {\n      url: `/setting/anonymous`,\n      method: \"GET\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchOpenAnonymousPermission = async () => {\n  return await driveRequest(\n    {\n      url: `/setting/anonymous`,\n      method: \"POST\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchCloseAnonymousPermission = async () => {\n  return await driveRequest(\n    {\n      url: `/setting/anonymous`,\n      method: \"DELETE\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\ninterface IFetchCheckFileExistRequestData {\n  folderID: string\n  name: string\n  type: GCS_OBJECT_TYPE\n}\n\ninterface IFetchCheckFileExistResponseData {\n  name: string\n  isDuplicated: boolean\n}\n\nexport const fetchCheckFileExist = async (\n  data: IFetchCheckFileExistRequestData[],\n  abortSignal?: AbortSignal,\n) => {\n  return await driveRequest<IFetchCheckFileExistResponseData[]>(\n    {\n      url: `/files/duplicate`,\n      method: \"POST\",\n      data,\n      signal: abortSignal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\ninterface IFetchFileDetailRequestData {\n  name: string\n  folderID: string\n  type: GCS_OBJECT_TYPE\n  size: number\n  resumable?: boolean\n  duplicationHandler: DUPLICATION_HANDLER\n  contentType: string\n}\n\ninterface IFetchFIleDetailResponseData {\n  id: string\n  name: string\n  type: GCS_OBJECT_TYPE\n  url: string\n  resumable: boolean\n}\n\nexport const fetchGCSUploadPresignedURL = async (\n  data: IFetchFileDetailRequestData,\n  abortSignal?: AbortSignal,\n) => {\n  try {\n    const response = await driveRequest<IFetchFIleDetailResponseData>(\n      {\n        url: \"/files\",\n        method: \"POST\",\n        data: {\n          resumable: true,\n          ...data,\n        },\n        signal: abortSignal,\n      },\n      { teamID: getCurrentTeamID() },\n    )\n    return Promise.resolve(response)\n  } catch (e) {\n    return Promise.reject(e)\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/services/history.ts",
    "content": "import { builderRequest, builderWSRequest } from \"@illa-public/illa-net\"\nimport { CurrentAppResp } from \"@/page/App/resp/currentAppResp\"\nimport { SnapshotList } from \"@/redux/currentAppHistory/currentAppHistoryState\"\nimport { getCurrentTeamID } from \"../utils/team\"\n\nexport const fetchSnapShotList = (params: {\n  appID: string\n  page: number\n  pageLimit?: number\n  signal?: AbortSignal\n}) => {\n  const { appID, page, pageLimit = 10, signal } = params\n  return builderRequest<SnapshotList>(\n    {\n      url: `/apps/${appID}/snapshotList/limit/${pageLimit}/page/${page}`,\n      method: \"GET\",\n      signal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchSnapShot = (\n  appID: string,\n  snapshotID: string,\n  signal?: AbortSignal,\n) => {\n  return builderRequest<CurrentAppResp>(\n    {\n      url: `/apps/${appID}/snapshot/${snapshotID}`,\n      method: \"GET\",\n      signal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const recoverSnapShot = (appID: string, snapshotID: string) => {\n  return builderRequest(\n    {\n      url: `/apps/${appID}/recoverSnapshot/${snapshotID}`,\n      method: \"POST\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\nexport const recoverSnapShotWS = (appID: string) => {\n  return builderWSRequest(\n    {\n      url: `/apps/${appID}/recoverSnapshot`,\n      method: \"POST\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\n// Take snapshot for current App\nexport const takeSnapShot = (appID: string) => {\n  return builderRequest(\n    {\n      url: `/apps/${appID}/takeSnapshot`,\n      method: \"POST\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/services/public.ts",
    "content": "import { builderRequest } from \"@illa-public/illa-net\"\nimport { getCurrentTeamID } from \"../utils/team\"\n\ninterface IFetchWsURLResponse {\n  wsURL: string\n}\n\nexport const fetchDashboardWsURL = async (abortSingle?: AbortSignal) => {\n  return await builderRequest<IFetchWsURLResponse>(\n    {\n      url: `/room/websocketConnection/dashboard`,\n      method: \"GET\",\n      signal: abortSingle,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchAppTextWsUrl = async (\n  roomID: string,\n  abortSingle?: AbortSignal,\n) => {\n  return await builderRequest<IFetchWsURLResponse>(\n    {\n      url: `/room/websocketConnection/app/${roomID}`,\n      method: \"GET\",\n      signal: abortSingle,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const fetchAppBinaryWsUrl = async (\n  roomID: string,\n  abortSingle?: AbortSignal,\n) => {\n  return await builderRequest<IFetchWsURLResponse>(\n    {\n      url: `/room/binaryWebsocketConnection/app/${roomID}`,\n      method: \"GET\",\n      signal: abortSingle,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/services/resource.ts",
    "content": "import { builderRequest } from \"@illa-public/illa-net\"\nimport { Resource, ResourceContent } from \"@illa-public/public-types\"\nimport { getCurrentTeamID } from \"../utils/team\"\n\nexport const fetchResources = (signal: AbortSignal) => {\n  return builderRequest<Resource<ResourceContent>[]>(\n    {\n      url: \"/resources\",\n      method: \"GET\",\n      signal: signal,\n    },\n    { teamID: getCurrentTeamID() },\n  )\n}\n\ninterface IResourceMeta {\n  Success: boolean\n  Schema: Record<string, unknown>\n}\n\nexport const fetchResourceMeta = async (resourceID: string) => {\n  return builderRequest<IResourceMeta>(\n    {\n      url: `/resources/${resourceID}/meta`,\n      method: \"GET\",\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n\nexport const getOAuthRefreshData = async (\n  resourceID: string,\n  signal: AbortSignal,\n) => {\n  return builderRequest<Resource<ResourceContent>>(\n    {\n      url: `/resources/${resourceID}/refresh`,\n      method: \"POST\",\n      signal,\n    },\n    {\n      teamID: getCurrentTeamID(),\n    },\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/services/setting.ts",
    "content": "import { authCloudRequest } from \"@illa-public/illa-net\"\nimport { CurrentUserInfo } from \"@illa-public/public-types\"\n\nexport const fetchChangeNickname = (nickname: string) => {\n  return authCloudRequest<{}>({\n    url: \"/users/nickname\",\n    method: \"PATCH\",\n    data: {\n      nickname,\n    },\n  })\n}\n\nexport const fetchChangeLanguage = (language: string) => {\n  return authCloudRequest<CurrentUserInfo>({\n    url: \"/users/language\",\n    method: \"PATCH\",\n    data: {\n      language,\n    },\n  })\n}\n\nexport const fetchChangePassword = (\n  currentPassword: string,\n  newPassword: string,\n) => {\n  return authCloudRequest({\n    url: \"/users/password\",\n    method: \"PATCH\",\n    data: {\n      currentPassword,\n      newPassword,\n    },\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/services/team.ts",
    "content": "import { authCloudRequest } from \"@illa-public/illa-net\"\nimport { TeamInfo } from \"@illa-public/public-types\"\n\nexport const fetchMyTeamsInfo = () => {\n  return authCloudRequest<TeamInfo[]>({\n    url: \"/teams/my\",\n    method: \"GET\",\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/services/users.ts",
    "content": "import {\n  authCloudRequest,\n  notNeedAuthCloudRequest,\n} from \"@illa-public/illa-net\"\nimport { CurrentUserInfo } from \"@illa-public/public-types\"\nimport { getAuthToken } from \"@illa-public/utils\"\n\nexport const fetchUserInfo = () => {\n  return authCloudRequest<CurrentUserInfo>({\n    url: \"/users\",\n  })\n}\n\nexport const tryFetchUserInfo = async () => {\n  const token = getAuthToken()\n\n  try {\n    return await notNeedAuthCloudRequest<CurrentUserInfo>({\n      url: \"/users\",\n      headers: {\n        Authorization: token,\n      },\n    })\n  } catch (e) {\n    return undefined\n  }\n}\n\nexport const updateTutorialViewed = async (isTutorialViewed: boolean) => {\n  await authCloudRequest({\n    url: \"/users/tutorialViewed\",\n    method: \"PATCH\",\n    data: {\n      isTutorialViewed,\n    },\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/store.ts",
    "content": "import { currentUserReducer, teamReducer } from \"@illa-public/user-data\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport {\n  ListenerEffectAPI,\n  TypedStartListening,\n  configureStore,\n  createListenerMiddleware,\n} from \"@reduxjs/toolkit\"\nimport { guideAsync } from \"@/middleware/guideAsync\"\nimport { reduxAsync } from \"@/middleware/reduxAsync\"\nimport aiAgent from \"@/redux/aiAgent/dashboardTeamAIAgentSlice\"\nimport builderInfoReducer from \"@/redux/builderInfo/builderInfoSlice\"\nimport configReducer from \"@/redux/config/configSlice\"\nimport currentAppHistoryReducer from \"@/redux/currentAppHistory/currentAppHistorySlice\"\nimport guideReducer from \"@/redux/guide/guideSlice\"\nimport resourceReducer from \"@/redux/resource/resourceSlice\"\nimport { mixpanelReport } from \"./middleware/mixpanelReport\"\nimport { UndoRedo } from \"./middleware/undoRedo\"\nimport { appReducer } from \"./redux/currentApp/slice\"\n\nconst listenerMiddleware = createListenerMiddleware()\n\nconst middlewares = [reduxAsync, UndoRedo, guideAsync]\n\nif (isCloudVersion) {\n  middlewares.unshift(mixpanelReport)\n}\n\nconst store = configureStore({\n  reducer: {\n    config: configReducer,\n    currentApp: appReducer,\n    currentAppHistory: currentAppHistoryReducer,\n    builderInfo: builderInfoReducer,\n    resource: resourceReducer,\n    guide: guideReducer,\n    currentUser: currentUserReducer,\n    team: teamReducer,\n    aiAgent: aiAgent,\n  },\n  devTools: import.meta.env.ILLA_APP_ENV === \"development\",\n  middleware: (getDefaultMiddleware) =>\n    getDefaultMiddleware({\n      serializableCheck: {\n        ignoredActions: [\"execution/setExecutionResultReducer\"],\n      },\n    })\n      .prepend(listenerMiddleware.middleware)\n      .concat(middlewares),\n})\n\nexport default store\nexport type RootState = ReturnType<typeof store.getState>\n\nexport type AppDispatch = typeof store.dispatch\n\nexport type AppStartListening = TypedStartListening<RootState, AppDispatch>\n\nexport type AppListenerEffectAPI = ListenerEffectAPI<RootState, AppDispatch>\n\nexport const startAppListening =\n  listenerMiddleware.startListening as AppStartListening\n"
  },
  {
    "path": "apps/builder/src/style.tsx",
    "content": "import { css } from \"@emotion/react\"\n\nconst FONT_SIZE = (100 / 780) * 100\n\nexport const mobileAdaptationStyle = css`\n  html {\n    // when vw doesn't work\n    font-size: 41px;\n    // vw works\n    font-size: ${FONT_SIZE}vw;\n    @media screen and (orientation: landscape) {\n      font-size: ${FONT_SIZE}vh;\n    }\n    @media screen and (max-width: 320px) {\n      font-size: 41px;\n    }\n    @media screen and (min-width: 780px) {\n      font-size: 16px;\n    }\n    --dvh: 1dvh;\n  }\n`\n\nexport const globalStyle = css`\n  html,\n  body,\n  #root {\n    height: 100%;\n    width: 100%;\n  }\n  body {\n    margin: 0;\n    padding: 0;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n    font-family: Inter, -apple-system, BlinkMacSystemFont, PingFang SC,\n      Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif;\n  }\n\n  * {\n    outline: none !important;\n  }\n\n  /*\n  *  Use a more-intuitive box-sizing model.\n  */\n\n  *,\n  *::before,\n  *::after {\n    box-sizing: border-box;\n  }\n`\n\nexport const LEFT_PANEL_WIDTH = 280\nexport const RIGHT_PANEL_WIDTH = 320\nexport const MIDDLE_PANEL_WIDTH = 300\nexport const NAVBAR_HEIGHT = 48\n"
  },
  {
    "path": "apps/builder/src/types/environment.d.ts",
    "content": "declare global {\n  namespace NodeJS {\n    interface ProcessEnv {\n      readonly ILLA_API_BASE_URL: string\n      readonly ILLA_INSTANCE_ID: string\n      readonly ILLA_SENTRY_ENV: string\n      readonly ILLA_SENTRY_SERVER_API: string\n      readonly ILLA_APP_VERSION: string\n      readonly ILLA_APP_ENV: string\n      readonly ILLA_GOOGLE_MAP_KEY: string\n    }\n  }\n}\n\nexport {}\n"
  },
  {
    "path": "apps/builder/src/types/global.d.ts",
    "content": "interface Window {\n  customDomain?: string\n  currentTeamIdentifier?: string\n}\n"
  },
  {
    "path": "apps/builder/src/types/richText.d.ts",
    "content": "declare module \"@editorjs/*\" {\n  export default class editorPlugin {\n    constructor(config)\n    render()\n    normalizeData(data)\n    setLevel(level): void\n    merge(data): void\n    validate(blockData): boolean\n    save(toolsContent)\n    static get conversionConfig(): { export: string; import: string }\n    static get sanitize()\n    static get isReadOnlySupported(): boolean\n    get data()\n    set data(data)\n    getTag(): HTMLElement\n    get currentLevel()\n    get defaultLevel()\n    get levels()\n    static get toolbox(): {\n      icon: string\n      title: string\n    }\n  }\n}\n\ndeclare module \"editorjs-md-parser\" {\n  export const MDfromBlocks: (blocks: any) => Promise<any>\n}\n"
  },
  {
    "path": "apps/builder/src/utils/InspectHelper/selectWidgetHelper.ts",
    "content": "import { JSToString, stringToJS } from \"@/utils/evaluateDynamicString/utils\"\n\nexport const realInputValue = (\n  attrValue: string | undefined,\n  widgetDisplayName: string,\n) => {\n  if (attrValue === \"\" || attrValue == undefined) return \"\"\n  const value = `${attrValue.substring(\n    `{{${widgetDisplayName}.dataSources.map((item) => ( `.length,\n    attrValue.length - 4,\n  )}`\n\n  return JSToString(value)\n}\n\nexport const getNeedComputedValue = (\n  value: string,\n  widgetDisplayName: string,\n) => {\n  const stringToCanEvaluate = stringToJS(value)\n  if (stringToCanEvaluate === \"\") {\n    return stringToCanEvaluate\n  }\n  return `{{${widgetDisplayName}.dataSources.map((item) => ( ${stringToCanEvaluate}))}}`\n}\n"
  },
  {
    "path": "apps/builder/src/utils/action/driveActions.ts",
    "content": "import { ILLA_DRIVE_ROOT_PATH } from \"@illa-public/public-configs\"\nimport {\n  EXPIRATION_TYPE,\n  ILLADriveAction,\n  ILLADriveActionTypeContent,\n  ILLADriveListAllContent,\n  ILLADriveListFoldersContent,\n  ILLADriveUpdateStatusAction,\n  ILLADriveUploadMultipleContent,\n  ILLADriveUploadOneContent,\n  ILLA_DRIVE_ACTION_REQUEST_TYPE,\n  ILLA_DRIVE_FILTER_TYPE,\n  ILLA_DRIVE_UPLOAD_FILE_TYPE,\n  UPLOAD_FILE_STATUS,\n} from \"@illa-public/public-types\"\nimport { AxiosResponse } from \"axios\"\nimport { FILE_ITEM_DETAIL_STATUS_IN_UI } from \"@/page/App/Module/UploadDetail/components/DetailList/interface\"\nimport { updateFileDetailStore } from \"@/page/App/Module/UploadDetail/store\"\nimport { IActionRunResultResponseData } from \"@/services/action\"\nimport { dataURLtoFile } from \"@/widgetLibrary/UploadWidget/util\"\nimport {\n  handleDownloadFromDriveResource,\n  handleFileToDriveResource,\n} from \"../drive/upload/getSingedURL\"\nimport { getContentTypeByFileExtension, getFileName } from \"../file\"\nimport { isBase64Simple } from \"../url/base64\"\nimport { fetchCommonActionResult } from \"./runAction\"\n\nconst getFileInfo = (\n  fileName: string,\n  fileData: string,\n  fileType: ILLA_DRIVE_UPLOAD_FILE_TYPE,\n) => {\n  const isBase64 = isBase64Simple(fileData)\n  const fileDownloadName = getFileName((fileName ?? \"\").trim(), fileType)\n  const contentType = getContentTypeByFileExtension(\n    fileDownloadName.split(\".\")[1],\n  )\n  let tmpData = fileData\n  if (!isBase64) {\n    tmpData = `data:${contentType};base64,${fileData}`\n  }\n\n  const needUploadFile = dataURLtoFile(tmpData, fileDownloadName)\n  return {\n    fileDownloadName,\n    needUploadFile,\n  }\n}\n\nconst getPathForSignedUrl = (path: string) => {\n  if (path === \"/root\") {\n    return \"\"\n  } else {\n    return path.replace(\"/root\", \"\")\n  }\n}\n\nconst removeSuffixPath = (path: string): string => {\n  const regex = /^\\/?(.*?)\\/?$/\n  return path?.match(regex)?.[1] || path\n}\n\nconst scheduler = async (task: (() => Promise<any>)[]) => {\n  return new Promise((resolve, reject) => {\n    const run = async () => {\n      if (task.length === 0) {\n        return resolve(undefined)\n      }\n      task\n        .shift()?.()\n        .then(() => {\n          run()\n        })\n        .catch((e) => {\n          reject(e)\n        })\n    }\n    run()\n  })\n}\n\nconst handleDetail = (\n  name: string,\n  path: string,\n  contentType: ILLA_DRIVE_UPLOAD_FILE_TYPE,\n  needUploadFile: File,\n  queryID: string,\n) => {\n  const abortController = new AbortController()\n  const uploadParams = {\n    folder: getPathForSignedUrl(path),\n    allowAnonymous: false,\n    replace: false,\n  }\n  updateFileDetailStore.addFileDetailInfo({\n    loaded: 0,\n    total: 0,\n    status: FILE_ITEM_DETAIL_STATUS_IN_UI.WAITING,\n    fileName: name,\n    contentType: contentType,\n    queryID: queryID,\n    abortController,\n    saveToILLADriveParams: {\n      fileData: needUploadFile,\n      ...uploadParams,\n    },\n  })\n  return abortController\n}\n\nconst handleUploadOne = async (\n  fileID: string,\n  uploadURL: string,\n  needUploadFile: File,\n  queryID: string,\n  abortController: AbortController,\n) => {\n  const res = await handleFileToDriveResource(\n    queryID,\n    fileID,\n    uploadURL,\n    needUploadFile,\n    abortController.signal,\n  )\n  return res\n}\n\nexport const transformDriveData = (\n  contents: ILLADriveAction<ILLADriveActionTypeContent>,\n) => {\n  const operation = contents.operation\n  switch (operation) {\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.LIST: {\n      const commandArgs = contents.commandArgs as ILLADriveListAllContent\n      return {\n        ...commandArgs,\n        operation,\n        path: `/${removeSuffixPath(commandArgs.path) || ILLA_DRIVE_ROOT_PATH}`,\n        search:\n          commandArgs.filterType === ILLA_DRIVE_FILTER_TYPE.BY_NAME\n            ? commandArgs.search\n            : undefined,\n        fileID:\n          commandArgs.filterType === ILLA_DRIVE_FILTER_TYPE.BY_ID\n            ? commandArgs.fileID\n            : undefined,\n        expiry:\n          commandArgs.expirationType === EXPIRATION_TYPE.CUSTOM\n            ? `${commandArgs.expiry ?? 300}s`\n            : undefined,\n      }\n    }\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.LIST_FOLDERS: {\n      const commandArgs = contents.commandArgs as ILLADriveListFoldersContent\n      return {\n        ...commandArgs,\n        operation,\n        path: `/${removeSuffixPath(commandArgs.path) || ILLA_DRIVE_ROOT_PATH}`,\n        search:\n          commandArgs.filterType === ILLA_DRIVE_FILTER_TYPE.BY_NAME\n            ? commandArgs.search\n            : undefined,\n        folderID:\n          commandArgs.filterType === ILLA_DRIVE_FILTER_TYPE.BY_ID\n            ? commandArgs.folderID\n            : undefined,\n      }\n    }\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD: {\n      const commandArgs = contents.commandArgs as ILLADriveUploadOneContent\n      const { fileDownloadName, needUploadFile } = getFileInfo(\n        commandArgs.fileName,\n        commandArgs.fileData,\n        commandArgs.fileType,\n      )\n      return {\n        operation,\n        path: `/${removeSuffixPath(commandArgs.path) || ILLA_DRIVE_ROOT_PATH}`,\n        overwriteDuplicate: commandArgs.overwriteDuplicate,\n        fileName: fileDownloadName,\n        fileSize: needUploadFile.size,\n        contentType: needUploadFile.type,\n        needUploadFile: needUploadFile,\n      }\n    }\n\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD_MULTIPLE:\n      const commandArgs = contents.commandArgs as ILLADriveUploadMultipleContent\n      const files: Record<string, string | number | File>[] = []\n      let minLength = Math.min(\n        commandArgs.fileDataArray.length,\n        commandArgs.fileNameArray.length,\n        commandArgs.fileTypeArray.length,\n      )\n\n      for (let i = 0; i < minLength; i++) {\n        let fileType = commandArgs.fileTypeArray[\n          i\n        ] as ILLA_DRIVE_UPLOAD_FILE_TYPE\n        if (!Object.values(ILLA_DRIVE_UPLOAD_FILE_TYPE).includes(fileType)) {\n          fileType = ILLA_DRIVE_UPLOAD_FILE_TYPE.AUTO\n        }\n        const { fileDownloadName, needUploadFile } = getFileInfo(\n          commandArgs.fileNameArray[i],\n          commandArgs.fileDataArray[i],\n          fileType,\n        )\n        files.push({\n          fileName: fileDownloadName,\n          fileSize: needUploadFile.size,\n          contentType: needUploadFile.type,\n          needUploadFile,\n        })\n      }\n\n      return {\n        operation,\n        path: `/${removeSuffixPath(commandArgs.path) || ILLA_DRIVE_ROOT_PATH}`,\n        overwriteDuplicate: commandArgs.overwriteDuplicate,\n        files,\n      }\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_ONE:\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_MULTIPLE:\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.DELETE_ONE:\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.DELETE_MULTIPLE:\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPDATE: {\n      return {\n        operation,\n        ...contents.commandArgs,\n      }\n    }\n  }\n}\n\ninterface IUploadRes {\n  fileID: string\n  status: UPLOAD_FILE_STATUS\n}\nexport const fetchILLADriveClientResult = async (\n  isPublic: boolean,\n  resourceID: string,\n  displayName: string,\n  appId: string,\n  actionID: string,\n  actionContent: Record<string, any>,\n  response: AxiosResponse<\n    IActionRunResultResponseData<Record<string, any>[]>,\n    unknown\n  >,\n) => {\n  try {\n    const { operation } = actionContent || {}\n    if (!Object.values(ILLA_DRIVE_ACTION_REQUEST_TYPE).includes(operation)) {\n      return Promise.reject(\"no method\")\n    }\n    let result = response\n    switch (operation) {\n      case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD: {\n        const uploadInfo = response.data.Rows[0]\n        const queryID = `${uploadInfo.name}_${new Date().getTime()}`\n        try {\n          const abortController = handleDetail(\n            uploadInfo.name,\n            actionContent.path,\n            actionContent.contentType,\n            actionContent.needUploadFile,\n            queryID,\n          )\n          const res = await handleUploadOne(\n            uploadInfo.id,\n            uploadInfo.url,\n            actionContent.needUploadFile,\n            queryID,\n            abortController,\n          )\n          if (res && res.status === UPLOAD_FILE_STATUS.COMPLETE) {\n            const content: ILLADriveUpdateStatusAction = {\n              operation: ILLA_DRIVE_ACTION_REQUEST_TYPE.UPDATE_FILE_STATUS,\n              fileID: res.fileID,\n              status: res.status,\n            }\n            result = await fetchCommonActionResult(\n              isPublic,\n              resourceID,\n              \"illadrive\",\n              displayName,\n              appId,\n              actionID,\n              content,\n            )\n          } else {\n            result = {\n              ...result,\n              data: {\n                Rows: [],\n                Extra: null,\n                Success: false,\n              },\n            }\n          }\n          updateFileDetailStore.updateFileDetailInfo(queryID, {\n            status: result.data.Success\n              ? FILE_ITEM_DETAIL_STATUS_IN_UI.SUCCESS\n              : FILE_ITEM_DETAIL_STATUS_IN_UI.ERROR,\n          })\n        } catch (e) {\n          updateFileDetailStore.updateFileDetailInfo(queryID, {\n            status: FILE_ITEM_DETAIL_STATUS_IN_UI.ERROR,\n          })\n          throw e\n        }\n        break\n      }\n      case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD_MULTIPLE: {\n        if (!response.data.Rows.length) {\n          throw new Error(\"error\")\n        }\n        const uploadCallbackFns: (() => Promise<void>)[] = []\n        const updateStatusCallbackFns: ((\n          res: IUploadRes | undefined,\n        ) => Promise<void>)[] = []\n        const uploadRes: (IUploadRes | undefined)[] = []\n        const queryIDs: string[] = []\n        const updateStatusData: Record<string, any>[] = []\n        response.data.Rows.forEach((uploadInfo, index) => {\n          const queryID = `${uploadInfo.name}_${new Date().getTime()}`\n          queryIDs.push(queryID)\n          const { files = [] } = actionContent\n          const abortController = handleDetail(\n            uploadInfo.name,\n            actionContent.path,\n            files[index]?.contentType,\n            files[index]?.needUploadFile,\n            queryID,\n          )\n          const fn = async () => {\n            const res = await handleUploadOne(\n              uploadInfo.id,\n              uploadInfo.url,\n              files[index]?.needUploadFile,\n              queryID,\n              abortController,\n            )\n            if (res && res.status !== UPLOAD_FILE_STATUS.FAILED) {\n              uploadRes.push(res)\n            }\n          }\n          const updateStatus = async (res: IUploadRes | undefined) => {\n            const content: ILLADriveUpdateStatusAction = {\n              operation: ILLA_DRIVE_ACTION_REQUEST_TYPE.UPDATE_FILE_STATUS,\n              fileID: res!.fileID,\n              status: res!.status,\n            }\n            const updateStatusRes = await fetchCommonActionResult(\n              isPublic,\n              resourceID,\n              \"illadrive\",\n              displayName,\n              appId,\n              actionID,\n              content,\n            )\n            updateStatusData.push(updateStatusRes?.data?.Rows[0])\n          }\n          uploadCallbackFns.push(fn)\n          updateStatusCallbackFns.push(updateStatus)\n        })\n        try {\n          await scheduler(uploadCallbackFns)\n          const updateStatus = async () => {\n            return new Promise((resolve, reject) => {\n              const run = async () => {\n                if (updateStatusCallbackFns.length === 0) {\n                  return resolve(undefined)\n                }\n                updateStatusCallbackFns\n                  .shift()?.(uploadRes.shift())\n                  .then(() => {\n                    run()\n                  })\n                  .catch((e) => {\n                    return reject(e)\n                  })\n              }\n              run()\n            })\n          }\n          await updateStatus()\n          queryIDs.forEach((queryID) => {\n            updateFileDetailStore.updateFileDetailInfo(queryID, {\n              status: FILE_ITEM_DETAIL_STATUS_IN_UI.SUCCESS,\n            })\n          })\n          result = {\n            ...result,\n            data: {\n              Rows: updateStatusData,\n              Extra: null,\n              Success: true,\n            },\n          }\n        } catch (e) {\n          queryIDs.forEach((queryID) => {\n            updateFileDetailStore.updateFileDetailInfo(queryID, {\n              status: FILE_ITEM_DETAIL_STATUS_IN_UI.ERROR,\n            })\n          })\n          throw e\n        }\n        break\n      }\n      case ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_ONE: {\n        let downloadInfo = response.data.Rows[0] as {\n          name: string\n          downloadURL: string\n        }\n        await handleDownloadFromDriveResource([downloadInfo])\n        result = {\n          ...result,\n          data: {\n            Rows: [],\n            Extra: null,\n            Success: true,\n          },\n        }\n        break\n      }\n      case ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_MULTIPLE: {\n        let downloadInfo = response.data.Rows as {\n          name: string\n          downloadURL: string\n        }[]\n        await handleDownloadFromDriveResource(downloadInfo, true)\n        result = {\n          ...result,\n          data: {\n            Rows: [],\n            Extra: null,\n            Success: true,\n          },\n        }\n        break\n      }\n      default:\n        return response\n    }\n    return result\n  } catch (e) {\n    throw e\n  }\n}\n\nexport const transformDriveResFormat = (\n  response: AxiosResponse,\n  actionContent: ILLADriveAction<ILLADriveActionTypeContent>,\n) => {\n  const { operation } = actionContent\n  switch (operation) {\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD_MULTIPLE: {\n      return {\n        data: response.data.Rows,\n      }\n    }\n    case ILLA_DRIVE_ACTION_REQUEST_TYPE.LIST: {\n      const files = response.data.Rows?.[0]?.Files || []\n      return {\n        data: files,\n      }\n    }\n    default: {\n      return {\n        data: response.data.Rows?.[0],\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/action/fetchS3ClientResult.ts",
    "content": "import { S3ActionRequestType, S3_CONTENT_TYPE } from \"@illa-public/public-types\"\nimport { isFile } from \"@illa-public/utils\"\nimport { AxiosResponse } from \"axios\"\nimport { createWriteStream } from \"streamsaver\"\nimport { fetchS3ActionRunResult } from \"@/services/action\"\nimport { downloadSingleFile, getFileName } from \"@/utils/file\"\nimport { isBase64Simple } from \"@/utils/url/base64\"\nimport { dataURLtoFile } from \"@/widgetLibrary/UploadWidget/util\"\n\nconst getFileInfo = (fileName: string, fileData: string, fileType: string) => {\n  const isBase64 = isBase64Simple(fileData)\n  if (!isBase64) return fileData\n  const fileDownloadName = getFileName((fileName ?? \"\").trim(), fileType)\n  return dataURLtoFile(fileData, fileDownloadName)\n}\n\nconst isFileType = (contentType: string) => {\n  return contentType === S3_CONTENT_TYPE.BINARY || isFile(contentType)\n}\nconst isSerializedText = (contentType: string) => {\n  return [\n    S3_CONTENT_TYPE.CSV,\n    S3_CONTENT_TYPE.JSON,\n    S3_CONTENT_TYPE.STRING,\n  ].includes(contentType as S3_CONTENT_TYPE)\n}\nconst fileToDataURL = async (blob: Blob) => {\n  return new Promise((resolve, reject) => {\n    let reader = new FileReader()\n    reader.readAsDataURL(blob)\n    reader.onload = () => resolve(reader.result)\n    reader.onerror = (error) => reject(error)\n  })\n}\n\nexport const fetchS3ClientResult = async (\n  presignData: Record<string, any>[],\n  actionContent: Record<string, any>,\n) => {\n  const urlInfos = presignData as { key: string; url: string; acl?: string }[]\n  try {\n    if (!urlInfos.length) {\n      return Promise.reject(\"presignedURL is undefined\")\n    }\n    const headers = {\n      \"Content-Encoding\": \"compress\",\n    }\n    let result\n    const { commands } = actionContent\n    switch (commands) {\n      case S3ActionRequestType.READ_ONE: {\n        const readURL = urlInfos[0].url\n        const response = await fetchS3ActionRunResult(readURL, \"GET\", headers)\n        const contentType = response?.headers[\"content-type\"]\n        const data: Record<string, string | boolean> = {\n          key: urlInfos[0]?.key,\n          contentType,\n          isJson: contentType === S3_CONTENT_TYPE.JSON,\n        }\n        if (actionContent.commandArgs?.signedURL) {\n          data.signedURL = readURL\n        } else {\n          data.url = readURL\n        }\n        if (isSerializedText(contentType)) {\n          data.body = response.data\n        } else if (isFileType(contentType)) {\n          const fileResponse = await fetch(readURL)\n          let base64: unknown = \"\"\n          if (fileResponse) {\n            const blob = await fileResponse.blob()\n            base64 = await fileToDataURL(blob)\n            data.body = `${base64}`\n          }\n        } else {\n          data.body = response.data\n        }\n        response.data = data\n        result = response\n        break\n      }\n      case S3ActionRequestType.DOWNLOAD_ONE: {\n        const url = urlInfos[0].url\n        let downloadCommandArgs = actionContent.commandArgs\n        const downloadResponse = await fetchS3ActionRunResult(\n          url,\n          \"GET\",\n          headers,\n        )\n        const contentType =\n          downloadResponse.headers[\"content-type\"].split(\";\")[0] ?? \"\"\n        let data = downloadResponse.data\n        if (contentType === S3_CONTENT_TYPE.JSON) {\n          data = JSON.stringify(data)\n        } else if (isSerializedText(contentType)) {\n          data = `${data}`\n        } else if (isFileType(contentType)) {\n          const fileResponse = await fetch(url)\n          if (window.WritableStream && fileResponse.body?.pipeTo) {\n            const fileStream = createWriteStream(downloadCommandArgs.objectKey)\n            await fileResponse.body.pipeTo(fileStream)\n            downloadResponse.data = fileResponse.url\n            result = downloadResponse\n            return result\n          }\n        }\n        downloadSingleFile(\n          contentType,\n          downloadCommandArgs.objectKey,\n          data || \"\",\n        )\n        result = downloadResponse\n        break\n      }\n      case S3ActionRequestType.UPLOAD: {\n        let uploadCommandArgs = actionContent.commandArgs\n        const { objectKey, contentType, objectData } = uploadCommandArgs || {}\n        const uploadUrl = urlInfos[0].url\n        const uploadResponse = await fetchS3ActionRunResult(\n          uploadUrl,\n          \"PUT\",\n          {\n            ...headers,\n            \"x-amz-acl\": urlInfos[0].acl ?? \"public-read\",\n            \"Content-Type\": contentType ?? S3_CONTENT_TYPE.STRING,\n          },\n          isFileType(contentType)\n            ? getFileInfo(objectKey, objectData, contentType)\n            : objectData,\n        )\n        result = uploadResponse\n        break\n      }\n      case S3ActionRequestType.UPLOAD_MULTIPLE: {\n        const multipleCommandArgs = actionContent.commandArgs\n        const { objectDataList, objectKeyList, contentType } =\n          multipleCommandArgs\n        let requests: Promise<AxiosResponse<BlobPart, unknown>>[] = []\n        const isFile = isFileType(contentType)\n        urlInfos.forEach((data, index) => {\n          requests.push(\n            fetchS3ActionRunResult(\n              data.url,\n              \"PUT\",\n              {\n                ...headers,\n                \"x-amz-acl\": data.acl ?? \"public-read\",\n                \"Content-Type\": contentType ?? S3_CONTENT_TYPE.STRING,\n              },\n              isFile\n                ? getFileInfo(\n                    objectKeyList[index],\n                    objectDataList[index],\n                    contentType,\n                  )\n                : objectDataList[index],\n            ),\n          )\n        })\n        const uploadMultipleCommandResponse = await Promise.allSettled(requests)\n        for (let i = 0; i < uploadMultipleCommandResponse.length; i++) {\n          let res = uploadMultipleCommandResponse[i]\n          if (res.status === \"fulfilled\") {\n            result = res.value\n          } else {\n            result = res.reason\n            break\n          }\n        }\n        break\n      }\n      default: {\n        throw new Error(\"not has method\")\n      }\n    }\n    return result\n  } catch (e) {\n    throw e\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/action/premiumActionHandler.ts",
    "content": "import { ActionType } from \"@illa-public/public-types\"\nimport { createUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { isSubscribeForUseDrive } from \"@illa-public/upgrade-modal/utils\"\nimport { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport store from \"@/store\"\n\nexport const PREMIUM_ACTIONS = [\"illadrive\"]\n\nexport const isNeedPreventForPremium = (actionType: ActionType): boolean => {\n  const isProductionMode = getIsILLAProductMode(store.getState())\n  if (isProductionMode) {\n    return false\n  }\n  if (isCloudVersion && PREMIUM_ACTIONS.includes(actionType)) {\n    const teamInfo = getCurrentTeamInfo(store.getState())!\n    const upgradeModal = createUpgradeModal()\n    if (!isSubscribeForUseDrive(teamInfo)) {\n      upgradeModal({\n        modalType: \"upgrade\",\n        from: \"drive_run_action\",\n      })\n      return true\n    }\n  }\n  return false\n}\n"
  },
  {
    "path": "apps/builder/src/utils/action/runAction.ts",
    "content": "import { isILLAAPiError } from \"@illa-public/illa-net\"\nimport {\n  ActionContent,\n  ActionType,\n  MysqlLikeAction,\n  RestAPIAction,\n  RestAPIBodyContent,\n  SMPTAction,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { createMessage } from \"@illa-design/react\"\nimport { GUIDE_DEFAULT_ACTION_ID } from \"@/config/guide\"\nimport i18n from \"@/i18n/config\"\nimport { isFileOversize } from \"@/page/App/components/Actions/ActionPanel/utils/calculateFileSize\"\nimport {\n  getIsILLAGuideMode,\n  getIsILLAProductMode,\n} from \"@/redux/config/configSelector\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport { Events } from \"@/redux/currentApp/action/actionState\"\nimport { getAppId } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { fetchActionRunResult } from \"@/services/action\"\nimport store from \"@/store\"\nimport { transformDataFormat } from \"@/utils/action/transformDataFormat\"\nimport { ILLAEditorRuntimePropsCollectorInstance } from \"@/utils/executionTreeHelper/runtimePropsCollector\"\nimport {\n  isClientS3ActionContent,\n  isDriveActionContent,\n} from \"@/utils/typeHelper\"\nimport { fetchILLADriveClientResult } from \"./driveActions\"\nimport { fetchS3ClientResult } from \"./fetchS3ClientResult\"\nimport { isNeedPreventForPremium } from \"./premiumActionHandler\"\nimport { runActionErrorForColla } from \"./runActionErrorForColla\"\nimport { runAllEventHandler } from \"./runActionEventHandler\"\nimport { runTransformer } from \"./runActionTransformer\"\nimport { transResponse } from \"./transResponse\"\n\nconst message = createMessage()\n\nconst checkCanSendRequest = (\n  actionType: ActionType,\n  actionContent: ActionContent,\n) => {\n  if (actionType !== \"smtp\") {\n    return true\n  }\n  const { attachment } = actionContent as SMPTAction\n  const result = !!attachment && isFileOversize(attachment, \"smtp\")\n  if (result) {\n    message.error({\n      content: i18n.t(\"editor.action.panel.error.max_file\"),\n    })\n  }\n  return !result\n}\n\nexport const fetchCommonActionResult = async (\n  isPublic: boolean,\n  resourceID: string,\n  actionType: ActionType,\n  displayName: string,\n  appId: string,\n  actionID: string,\n  actionContent: ActionContent,\n  actionContext: Record<string, unknown> = {},\n  abortSignal?: AbortSignal,\n) => {\n  const canSendRequest = checkCanSendRequest(actionType, actionContent)\n  const needPreventPremiumAction = isNeedPreventForPremium(actionType)\n  if (!canSendRequest || needPreventPremiumAction) {\n    return Promise.reject(false)\n  }\n\n  const requestBody = {\n    resourceID,\n    actionType,\n    displayName,\n    content: actionContent,\n    context: actionContext,\n  }\n  return await fetchActionRunResult(\n    appId,\n    actionID,\n    requestBody,\n    isPublic,\n    abortSignal,\n  )\n}\n\nexport const fetchActionResult = async (\n  actionType: ActionType,\n  isProductionMode: boolean,\n  isPublic: boolean,\n  resourceID: string,\n  displayName: string,\n  appId: string,\n  currentActionId: string,\n  actionContent: ActionContent,\n  $context: Record<string, unknown>,\n  abortSignal: AbortSignal | undefined,\n) => {\n  let response = await fetchCommonActionResult(\n    !isProductionMode ? false : isPublic,\n    (resourceID as string) || \"\",\n    actionType as ActionType,\n    displayName,\n    appId,\n    currentActionId,\n    actionContent,\n    $context,\n    abortSignal,\n  )\n\n  if (isClientS3ActionContent(actionType, actionContent)) {\n    response = await fetchS3ClientResult(response.data.Rows, actionContent)\n  } else if (isDriveActionContent(actionType, actionContent)) {\n    response = await fetchILLADriveClientResult(\n      !isProductionMode ? false : isPublic,\n      (resourceID as string) || \"\",\n      displayName,\n      appId,\n      currentActionId,\n      actionContent,\n      response,\n    )\n  }\n  return transResponse(actionType, actionContent, response)\n}\n\nexport interface IExecutionActions extends ActionItem<ActionContent> {\n  $actionID: string\n  $resourceID: string\n  $context: Record<string, unknown>\n}\n\nexport const runActionWithExecutionResult = async (\n  action: IExecutionActions,\n  needRunEventHandler: boolean = true,\n  abortSignal?: AbortSignal,\n) => {\n  const { displayName } = action as ActionItem<\n    MysqlLikeAction | RestAPIAction<RestAPIBodyContent>\n  >\n  const {\n    content,\n    $actionID,\n    $resourceID,\n    actionType,\n    transformer,\n    $context,\n    config,\n  } = action\n  const originActionList = getActionList(store.getState())\n  const originAction = originActionList.find(\n    (item) => item.displayName === displayName,\n  )\n  if (!content || !originAction) return Promise.reject(false)\n  const rootState = store.getState()\n  const appId = getAppId(rootState)\n  const isGuideMode = getIsILLAGuideMode(rootState)\n  const isProductionMode = getIsILLAProductMode(rootState)\n  const {\n    successEvent: _successEvent = [],\n    failedEvent: _failedEvent = [],\n    ...restContent\n  } = content as ActionContent & Events\n\n  const mockConfig = config?.mockConfig!\n  const {\n    successEvent: originSuccessEvent = [],\n    failedEvent: originFailedEvent = [],\n    $dynamicAttrPaths = [],\n  } = originAction.content as ActionContent &\n    Events & { $dynamicAttrPaths: string[] }\n  const actionContent = transformDataFormat(\n    actionType as ActionType,\n    restContent,\n  ) as ActionContent\n\n  store.dispatch(\n    executionActions.updateExecutionByDisplayNameReducer({\n      displayName: displayName,\n      value: {\n        isRunning: true,\n        startTime: new Date().getTime(),\n        endTime: new Date().getTime(),\n      },\n    }),\n  )\n\n  const currentActionId = (\n    isGuideMode ? GUIDE_DEFAULT_ACTION_ID : $actionID\n  ) as string\n\n  try {\n    let illaInnerTransformedResponse\n\n    const mockEnabled = isProductionMode\n      ? mockConfig.enabled && mockConfig.enableForReleasedApp\n      : mockConfig.enabled\n\n    if (mockEnabled) {\n      illaInnerTransformedResponse = {\n        data: mockConfig.mockData,\n      }\n    } else {\n      illaInnerTransformedResponse = await fetchActionResult(\n        actionType,\n        isProductionMode,\n        config?.public ?? false,\n        ($resourceID as string) || \"\",\n        displayName,\n        appId,\n        currentActionId,\n        actionContent,\n        $context,\n        abortSignal,\n      )\n    }\n\n    let userTransformedData = runTransformer(\n      transformer,\n      illaInnerTransformedResponse.data ?? \"\",\n    )\n\n    store.dispatch(\n      executionActions.updateExecutionByDisplayNameReducer({\n        displayName: displayName,\n        value: {\n          ...illaInnerTransformedResponse,\n          data: userTransformedData,\n          runResult: undefined,\n          isRunning: false,\n          endTime: new Date().getTime(),\n        },\n      }),\n    )\n\n    if (needRunEventHandler) {\n      runAllEventHandler(originSuccessEvent, $dynamicAttrPaths)\n    }\n    return Promise.resolve(userTransformedData)\n  } catch (e) {\n    let runResult = {\n      error: true,\n      message: \"An unknown error\",\n    }\n    if (isILLAAPiError(e)) {\n      runResult.message = e.data?.errorMessage || \"An unknown error\"\n      try {\n        if (e.data?.errorMessage.startsWith(\"run action error: \")) {\n          const arr = e.data?.errorMessage.split(\"run action error: \")\n          if (arr.length > 1) {\n            const error = JSON.parse(arr[1])\n            const errResponse = {\n              ...e,\n              data: error,\n            }\n            runActionErrorForColla(actionType, actionContent, errResponse)\n          }\n        }\n      } catch (e) {}\n    }\n\n    store.dispatch(\n      executionActions.updateExecutionByDisplayNameReducer({\n        displayName: displayName,\n        value: {\n          data: undefined,\n          runResult: runResult,\n          isRunning: false,\n          endTime: new Date().getTime(),\n        },\n      }),\n    )\n    if (needRunEventHandler)\n      runAllEventHandler(originFailedEvent, $dynamicAttrPaths)\n\n    return Promise.reject(runResult)\n  }\n}\n\nexport const runOriginAction = async (action: ActionItem<ActionContent>) => {\n  const { displayName } = action\n  const finalContext =\n    ILLAEditorRuntimePropsCollectorInstance.getGlobalCalcContext()\n  const realAction = (finalContext as Record<string, unknown>)[\n    displayName\n  ] as IExecutionActions\n  return await runActionWithExecutionResult(realAction)\n}\n\nexport const runActionWithDelay = (\n  action: IExecutionActions,\n  abortSignal?: AbortSignal,\n) => {\n  const { config } = action\n  if (!config || !config.advancedConfig) {\n    runActionWithExecutionResult(action, true, abortSignal)\n    return\n  }\n  const { advancedConfig } = config\n  const { delayWhenLoaded } = advancedConfig\n  return new Promise((resolve, reject) => {\n    const timeoutID = window.setTimeout(\n      async () => {\n        window.clearTimeout(timeoutID)\n\n        try {\n          const result = await runActionWithExecutionResult(\n            action,\n            true,\n            abortSignal,\n          )\n          return resolve(result)\n        } catch (e) {\n          console.log(\"e\", e)\n          return reject(e)\n        }\n      },\n      delayWhenLoaded as unknown as number,\n    )\n  })\n}\n\nconst actionIDMapTimerID: Record<string, number> = {}\n\nexport const registerActionPeriod = (action: IExecutionActions) => {\n  const { config } = action\n  if (\n    !config ||\n    !config.advancedConfig ||\n    !config.advancedConfig.isPeriodically ||\n    (config.advancedConfig.periodInterval as unknown as number) <= 0\n  ) {\n    removeActionPeriod(action.$actionID)\n    return\n  }\n  removeActionPeriod(action.$actionID)\n  const timeID = window.setInterval(\n    () => {\n      runActionWithExecutionResult(action)\n    },\n    (config.advancedConfig.periodInterval as unknown as number) * 1000,\n  )\n  actionIDMapTimerID[action.$actionID] = timeID\n}\n\nexport const removeActionPeriod = (actionID: string) => {\n  if (actionIDMapTimerID[actionID]) {\n    window.clearInterval(actionIDMapTimerID[actionID])\n  }\n}\n\nexport const removeAllActionPeriod = () => {\n  Object.values(actionIDMapTimerID).forEach((id) => {\n    window.clearInterval(id)\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/utils/action/runActionErrorForColla.ts",
    "content": "import {\n  ActionContent,\n  ActionType,\n  ILLA_DRIVE_ACTION_REQUEST_TYPE,\n} from \"@illa-public/public-types\"\nimport {\n  CollarModalType,\n  handleCollaPurchaseError,\n} from \"@illa-public/upgrade-modal\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport store from \"@/store\"\nimport { isDriveActionContent } from \"../typeHelper\"\n\nconst getReportElementByProduction = (isProduction: boolean, el: string) => {\n  let prefix = isProduction ? \"deploy_\" : \"builder_editor_\"\n  return `${prefix}${el}`\n}\n\nexport const runActionErrorForColla = (\n  actionType: ActionType,\n  actionContent: ActionContent,\n  error: unknown,\n) => {\n  const rootState = store.getState()\n  const isProductionMode = getIsILLAProductMode(rootState)\n  if (actionType === \"aiagent\") {\n    return handleCollaPurchaseError(\n      error,\n      CollarModalType.TOKEN,\n      getReportElementByProduction(\n        isProductionMode,\n        \"token_not_enough_resource\",\n      ),\n    )\n  }\n  if (isDriveActionContent(actionType, actionContent)) {\n    if (\n      actionContent.operation ===\n        ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_MULTIPLE ||\n      actionContent.operation === ILLA_DRIVE_ACTION_REQUEST_TYPE.DOWNLOAD_ONE\n    ) {\n      return handleCollaPurchaseError(\n        error,\n        CollarModalType.TRAFFIC,\n        getReportElementByProduction(\n          isProductionMode,\n          \"traffic_not_enough_resource\",\n        ),\n      )\n    } else if (\n      actionContent.operation === ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD ||\n      actionContent.operation === ILLA_DRIVE_ACTION_REQUEST_TYPE.UPLOAD_MULTIPLE\n    ) {\n      return handleCollaPurchaseError(\n        error,\n        CollarModalType.STORAGE,\n        getReportElementByProduction(\n          isProductionMode,\n          \"storage_not_enough_resource\",\n        ),\n      )\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/action/runActionEventHandler.ts",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { klona } from \"klona/json\"\nimport { get, set, toPath } from \"lodash-es\"\nimport { evaluateDynamicString } from \"../evaluateDynamicString\"\nimport { runEventHandler } from \"../eventHandlerHelper\"\nimport { ILLAEditorRuntimePropsCollectorInstance } from \"../executionTreeHelper/runtimePropsCollector\"\n\nexport const runAllEventHandler = (\n  events: any[] = [],\n  dynamicAttrPaths: string[] = [],\n) => {\n  const finalContext =\n    ILLAEditorRuntimePropsCollectorInstance.getGlobalCalcContext()\n  const needRunEvents = klona(events).map((originEvent) => {\n    return {\n      ...originEvent,\n      originEnable: originEvent.enabled,\n    }\n  })\n  dynamicAttrPaths.forEach((path) => {\n    const realPath = convertPathToString(toPath(path).slice(1))\n    try {\n      const dynamicString = get(needRunEvents, realPath, \"\")\n      if (dynamicString) {\n        const calcValue = evaluateDynamicString(\n          `events${realPath}`,\n          dynamicString,\n          finalContext,\n        )\n        set(needRunEvents, realPath, calcValue)\n      }\n    } catch (e) {\n      console.log(e)\n    }\n  })\n  needRunEvents.forEach((scriptObj) => {\n    runEventHandler(scriptObj, finalContext)\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/utils/action/runActionTransformer.ts",
    "content": "import { Transformer } from \"@illa-public/public-types\"\nimport { evaluateDynamicString } from \"../evaluateDynamicString\"\nimport { wrapFunctionCode } from \"../evaluateDynamicString/utils\"\nimport { ILLAEditorRuntimePropsCollectorInstance } from \"../executionTreeHelper/runtimePropsCollector\"\n\nexport function runTransformer(transformer: Transformer, rawData: any) {\n  let calcResult: any = rawData\n  if (transformer?.enable) {\n    const evaluateTransform = wrapFunctionCode(transformer.rawData)\n    const canEvalString = `{{${evaluateTransform}()}}`\n    const finalContext =\n      ILLAEditorRuntimePropsCollectorInstance.getGlobalCalcContext({\n        data: rawData,\n      })\n    try {\n      calcResult = evaluateDynamicString(\"events\", canEvalString, finalContext)\n    } catch (e) {\n      console.log(e)\n    }\n  }\n  return calcResult\n}\n"
  },
  {
    "path": "apps/builder/src/utils/action/transResponse.ts",
    "content": "import {\n  ActionContent,\n  ILLADriveAction,\n  ILLADriveActionTypeContent,\n} from \"@illa-public/public-types\"\nimport { ActionType } from \"@illa-public/public-types\"\nimport { AxiosResponse } from \"axios\"\nimport { isClientS3ActionContent } from \"@/utils/typeHelper\"\nimport { transformDriveResFormat } from \"./driveActions\"\n\nconst transMaybeFileResponse = (\n  header: Record<string, unknown>,\n  raw: string,\n) => {\n  const contentType =\n    (header[\"Content-Type\"] as string)?.split(\";\")[0] ?? \"text/plain\"\n  if (\n    contentType.includes(\"video/\") ||\n    contentType.includes(\"audio/\") ||\n    contentType.includes(\"image/\") ||\n    contentType.includes(\"application/pdf\")\n  ) {\n    return {\n      responseHeaders: header,\n      data: raw,\n      fileData: {\n        base64binary: raw,\n        dataURI: `data:${contentType};base64,${raw}`,\n        fileType: contentType,\n      },\n    }\n  }\n  let realData = raw\n  try {\n    const bytes = new Uint8Array(\n      atob(raw)\n        .split(\"\")\n        .map((char) => char.charCodeAt(0)),\n    )\n    realData = new TextDecoder().decode(bytes)\n  } catch {\n    return {\n      responseHeaders: header,\n      data: raw,\n    }\n  }\n\n  try {\n    const parsedValue = JSON.parse(realData)\n    return {\n      responseHeaders: header,\n      data: parsedValue,\n      rawData: realData,\n    }\n  } catch (e) {\n    return {\n      rawData: realData,\n      responseHeaders: header,\n      data: realData,\n    }\n  }\n}\n\nconst transClientS3Response = (response: AxiosResponse) => {\n  if (response.config.method === \"get\") {\n    return {\n      responseHeaders: response.headers,\n      data: response.data,\n    }\n  }\n  if (response.status >= 200 && response.status < 300) {\n    return {\n      responseHeaders: response.headers,\n      data: \"ok\",\n    }\n  }\n  if (response.status >= 400 && response.status < 600) {\n    return {\n      responseHeaders: response.headers,\n      data: \"failed\",\n    }\n  }\n  return {\n    responseHeaders: response.headers,\n    data: \"unknown\",\n  }\n}\n\nconst transLikeRestApiResponse = (response: AxiosResponse) => {\n  const resData = response.data\n  if (resData && resData.Extra && resData.Extra.raw) {\n    const responseHeaders = resData.Extra.headers\n    const raw = resData.Extra.raw\n    let header: Record<string, unknown> = {}\n    Object.keys(responseHeaders).forEach((key) => {\n      header[key] = responseHeaders[key][0]\n    })\n    if (resData.Extra.statusCode) {\n      header[\"statusCode\"] = resData.Extra.statusCode\n    }\n    if (resData.Extra.statusText) {\n      header[\"statusText\"] = resData.Extra.statusText\n    }\n    return transMaybeFileResponse(header, raw)\n  }\n  return resData\n}\n\nexport const transResponse = (\n  actionType: ActionType,\n  actionContent: ActionContent,\n  response: AxiosResponse,\n) => {\n  switch (actionType) {\n    case \"s3\": {\n      const isClientS3 = isClientS3ActionContent(actionType, actionContent)\n      if (isClientS3) {\n        return transClientS3Response(response)\n      } else {\n        return {\n          data: response.data.Rows,\n        }\n      }\n    }\n    case \"restapi\":\n    case \"huggingface\":\n    case \"hfendpoint\": {\n      return transLikeRestApiResponse(response)\n    }\n    case \"graphql\": {\n      return {\n        data: response.data.Rows?.[0],\n      }\n    }\n    case \"illadrive\": {\n      return transformDriveResFormat(\n        response,\n        actionContent as ILLADriveAction<ILLADriveActionTypeContent>,\n      )\n    }\n    default: {\n      return {\n        data: response.data.Rows,\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/action/transformDataFormat.ts",
    "content": "import {\n  CouchDBActionStructParamsDataTransferType,\n  DynamoActionStructParamsDataTransferType,\n  GoogleSheetDataTypeTransform,\n  HuggingFaceBooleanTypes,\n  HuggingFaceBooleanValueMap,\n} from \"@illa-public/public-configs\"\nimport {\n  ActionType,\n  AirtableAction,\n  AirtableActionConfigType,\n  AirtableCreateRecord,\n  AirtableDeleteMultipleRecords,\n  AirtableDeleteRecord,\n  AirtableListRecord,\n  AirtableUpdateMultipleRecords,\n  AirtableUpdateRecord,\n  FirebaseAuthActionTypeValue,\n  FirebaseServiceTypeValue,\n  FirebaseStoreActionTypeValue,\n  ILLADriveAction,\n  ILLADriveActionTypeContent,\n} from \"@illa-public/public-types\"\nimport { Params } from \"@illa-public/public-types\"\nimport { isNumber, isString } from \"@illa-design/react\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport { transformDriveData } from \"./driveActions\"\n\nconst getAppwriteFilterValue = (value: string) => {\n  const val = value.trim().replace(/^\\[|\\]$/g, \"\")\n  return `[${val.split(\",\").map((v) => `\"${v.trim()}\"`)}]`\n}\n\nexport const transformDataFormat = (\n  actionType: ActionType,\n  contents: Record<string, any>,\n) => {\n  switch (actionType) {\n    case \"smtp\": {\n      const { attachment } = contents\n      if (Array.isArray(attachment)) {\n        return {\n          ...contents,\n          attachment: attachment.map((value) => ({\n            ...value,\n            data: btoa(encodeURIComponent(value.data || \"\")),\n          })),\n        }\n      } else if (attachment) {\n        return {\n          ...contents,\n          attachment: [btoa(encodeURIComponent(attachment || \"\"))],\n        }\n      }\n      return contents\n    }\n    case \"restapi\": {\n      if (contents.bodyType === \"raw\" && contents.body?.content) {\n        return {\n          ...contents,\n          body: {\n            ...contents.body,\n            content: JSON.stringify(contents.body.content),\n          },\n        }\n      }\n      return contents\n    }\n    case \"firebase\":\n      const { service, operation } = contents\n      if (\n        service === FirebaseServiceTypeValue.AUTH &&\n        operation === FirebaseAuthActionTypeValue.LIST_USERS\n      ) {\n        const { number = \"\", ...others } = contents.options\n        return {\n          ...contents,\n          options: {\n            ...others,\n            ...(number !== \"\" && { number }),\n          },\n        }\n      }\n      if (\n        service === FirebaseServiceTypeValue.FIRESTORE &&\n        (operation === FirebaseStoreActionTypeValue.QUERY_FIREBASE ||\n          operation === FirebaseStoreActionTypeValue.QUERY_COLLECTION_GROUP)\n      ) {\n        const { limit = \"\", ...others } = contents.options\n        return {\n          ...contents,\n          options: {\n            ...others,\n            ...(limit !== \"\" && { limit }),\n          },\n        }\n      }\n      return contents\n    case \"graphql\": {\n      return {\n        ...contents,\n        query: (contents?.query ?? \"\").replace(/\\n/g, \"\"),\n      }\n    }\n    case \"huggingface\":\n    case \"hfendpoint\":\n      const isEndpoint = actionType === \"hfendpoint\"\n      const { modelID, detailParams, ...otherParams } = contents\n      const { type, content } = otherParams.inputs || {}\n      let newInputs = { type, content }\n      if (type === \"json\") {\n        if (isString(content)) {\n          try {\n            newInputs = {\n              type,\n              content: JSON.parse(content),\n            }\n          } catch (e) {\n            console.log(e)\n          }\n        }\n      }\n      const keys = Object.keys(detailParams)\n      const realDetailParams = keys.map((key: string) => {\n        const currentValue = detailParams[key]\n        return {\n          key,\n          value: currentValue\n            ? HuggingFaceBooleanTypes.includes(key)\n              ? HuggingFaceBooleanValueMap[\n                  currentValue as keyof typeof HuggingFaceBooleanValueMap\n                ] ?? currentValue\n              : parseFloat(currentValue)\n            : \"\",\n        }\n      })\n      return {\n        ...(!isEndpoint && { modelID }),\n        params: {\n          withDetailParams: otherParams.withDetailParams,\n          inputs: newInputs,\n          detailParams: realDetailParams,\n        },\n      }\n    case \"dynamodb\":\n      const { structParams } = contents\n      let newStructParams = { ...structParams }\n      Object.keys(DynamoActionStructParamsDataTransferType).forEach((key) => {\n        const value = DynamoActionStructParamsDataTransferType[key]\n        if (structParams[key] === \"\") {\n          newStructParams[key] = value\n        }\n      })\n      return {\n        ...contents,\n        structParams: newStructParams,\n      }\n    case \"couchdb\":\n      const { opts } = contents\n      let newOpts = { ...opts }\n      Object.keys(CouchDBActionStructParamsDataTransferType).forEach((key) => {\n        const value = CouchDBActionStructParamsDataTransferType[key]\n        if (newOpts[key] === \"\") {\n          newOpts[key] = value\n        }\n      })\n      return {\n        ...contents,\n        opts: newOpts,\n      }\n    case \"appwrite\":\n      const { method: appwriteMethod, opts: appwriteOpts } = contents\n      if (appwriteMethod === \"list\") {\n        const { orderBy = [], filter = [], limit = 100 } = appwriteOpts\n        return {\n          ...contents,\n          opts: {\n            ...appwriteOpts,\n            orderBy: orderBy.map(({ key, ...others }: Params) => ({\n              ...others,\n              attribute: key,\n            })),\n            filter: filter.map(({ key, value, ...others }: Params) => ({\n              ...others,\n              value: getAppwriteFilterValue(value),\n              attribute: key,\n            })),\n            limit: isNumber(limit) ? limit : 100,\n          },\n        }\n      }\n      const { data, ...other } = appwriteOpts\n      const showData = ![\"get\", \"delete\"].includes(appwriteMethod)\n      return {\n        ...contents,\n        opts: {\n          ...other,\n          ...(showData && { data: isObject(data) ? data : {} }),\n        },\n      }\n    case \"googlesheets\": {\n      const { opts: googleOpts } = contents\n      const googleSheetsTransformKeys = Object.keys(\n        GoogleSheetDataTypeTransform,\n      )\n      const newGoogleSheetOpts = { ...googleOpts }\n      googleSheetsTransformKeys.forEach((key) => {\n        const value =\n          GoogleSheetDataTypeTransform[\n            key as keyof typeof GoogleSheetDataTypeTransform\n          ]\n        if (newGoogleSheetOpts[key] === \"\") {\n          newGoogleSheetOpts[key] = value\n        }\n      })\n      return {\n        ...contents,\n        opts: newGoogleSheetOpts,\n      }\n    }\n    case \"airtable\": {\n      const { method } = contents as AirtableAction<AirtableActionConfigType>\n      switch (method) {\n        case \"list\":\n          const listConfig = contents.config as AirtableListRecord\n          return {\n            ...contents,\n            config: {\n              ...listConfig,\n              fields: listConfig.fields === \"\" ? [] : listConfig.fields,\n              maxRecords:\n                listConfig.maxRecords === \"\" ? -1 : listConfig.maxRecords,\n              pageSize: listConfig.pageSize === \"\" ? -1 : listConfig.pageSize,\n              sort: listConfig.sort === \"\" ? [] : listConfig.sort,\n            },\n          }\n        case \"delete\":\n          const deleteConfig = contents.config as AirtableDeleteRecord\n          return {\n            ...contents,\n            config: {\n              ...deleteConfig,\n              recordID:\n                deleteConfig.recordID === \"\" ? \"\" : deleteConfig.recordID,\n            },\n          }\n        case \"create\":\n          const createConfig = contents.config as AirtableCreateRecord\n          return {\n            ...contents,\n            config: {\n              ...createConfig,\n              records: createConfig.records === \"\" ? [] : createConfig.records,\n            },\n          }\n        case \"update\":\n          const updateConfig = contents.config as AirtableUpdateRecord\n          return {\n            ...contents,\n            config: {\n              ...updateConfig,\n              record: updateConfig.record === \"\" ? {} : updateConfig.record,\n            },\n          }\n        case \"bulkUpdate\":\n          const bulkUpdateConfig =\n            contents.config as AirtableUpdateMultipleRecords\n          return {\n            ...contents,\n            config: {\n              ...bulkUpdateConfig,\n              records:\n                bulkUpdateConfig.records === \"\" ? [] : bulkUpdateConfig.records,\n            },\n          }\n        case \"bulkDelete\":\n          const bulkDeleteConfig =\n            contents.config as AirtableDeleteMultipleRecords\n          return {\n            ...contents,\n            config: {\n              ...bulkDeleteConfig,\n              recordIDs:\n                bulkDeleteConfig.recordIDs === \"\"\n                  ? []\n                  : bulkDeleteConfig.recordIDs,\n            },\n          }\n      }\n    }\n    case \"aiagent\": {\n      return {\n        agentType: contents.virtualResource?.agentType ?? contents.agentType,\n        model: contents.virtualResource?.model ?? contents.model,\n        input: contents.input,\n        modelConfig: {\n          maxTokens: (\n            contents.virtualResource?.modelConfig ?? contents.modelConfig\n          ).maxTokens,\n          stream: false,\n        },\n        variables: contents.variables,\n        virtualResource: contents.virtualResource,\n      }\n    }\n    case \"illadrive\": {\n      return transformDriveData(\n        contents as ILLADriveAction<ILLADriveActionTypeContent>,\n      )\n    }\n    default:\n      return contents\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/billing/errorHandler.ts",
    "content": "import { ERROR_FLAG, isILLAAPiError } from \"@illa-public/illa-net\"\nimport { getILLACloudURL, isCloudVersion } from \"@illa-public/utils\"\nimport { matchPath } from \"react-router-dom\"\n\nexport const commonBillingErrorHandler = (error: unknown) => {\n  if (isILLAAPiError(error) && isCloudVersion) {\n    switch (error.data.errorFlag) {\n      case ERROR_FLAG.ERROR_FLAG_ACCESS_DENIED:\n        break\n      case ERROR_FLAG.ERROR_FLAG_CAN_NOT_TEST_RESOURCE_CONNECTION:\n        const match = matchPath(\"/:teamIdentifier/*\", location.pathname)\n        const teamIdentifier = match?.params?.teamIdentifier\n        window.location.href = teamIdentifier\n          ? `${getILLACloudURL(\n              window.customDomain,\n            )}/workspace/${teamIdentifier}`\n          : getILLACloudURL(window.customDomain)\n        break\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/calculateMemoryUsage.ts",
    "content": "export const LIMIT_MEMORY = 10 * 1024 * 1024 // 1MB = 1024 * 1024 bytes\nexport const estimateMemoryUsage = (data: unknown): number => {\n  const type = typeof data\n\n  switch (type) {\n    case \"number\":\n      return 8 // 8 bytes for a JavaScript number\n    case \"string\":\n      return (data as string).length * 2 // 2 bytes per character in a JavaScript string\n    case \"boolean\":\n      return 4 // 4 bytes for a JavaScript boolean\n    case \"undefined\":\n      return 0 // undefined doesn't occupy memory\n    case \"object\":\n      if (data === null) {\n        return 0 // null doesn't occupy memory\n      } else if (Array.isArray(data)) {\n        let size = 0\n        for (let i = 0; i < (data as unknown[]).length; i++) {\n          size += estimateMemoryUsage((data as unknown[])[i])\n        }\n        return size\n      } else {\n        let size = 0\n        for (const key in data as Record<string, unknown>) {\n          if ((data as Record<string, unknown>).hasOwnProperty(key)) {\n            size += estimateMemoryUsage((data as Record<string, unknown>)[key])\n          }\n        }\n        return size\n      }\n    default:\n      return 0\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/changeDisplayNameHelper.ts",
    "content": "import {\n  convertPathToString,\n  hasDynamicStringSnippet,\n} from \"@illa-public/dynamic-string\"\nimport {\n  ActionContent,\n  ActionItem,\n  ComponentMapNode,\n} from \"@illa-public/public-types\"\nimport { get, toPath } from \"lodash-es\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport { actionActions } from \"@/redux/currentApp/action/actionSlice\"\nimport {\n  Events,\n  UpdateActionSlicePropsPayload,\n} from \"@/redux/currentApp/action/actionState\"\nimport { UpdateComponentSlicePropsPayload } from \"@/redux/currentApp/components/componentsPayload\"\nimport { getComponentMap } from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport {\n  getInDependenciesMap,\n  getRawTree,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport store, { AppListenerEffectAPI } from \"@/store\"\nimport { EVENT_ACTION_TYPE } from \"./eventHandlerHelper\"\nimport { isAction, isWidget } from \"./executionTreeHelper/utils\"\n\nconst changeDisplayNameHelper = (\n  independenciesMap: Record<string, string[]>,\n  seeds: Record<string, any>,\n  oldDisplayName: string,\n  newDisplayName: string,\n  type: \"displayName\" | \"globalDataKey\" = \"displayName\",\n) => {\n  const updateWidgetSlice: UpdateComponentSlicePropsPayload[] = []\n  const updateActionSlice: UpdateActionSlicePropsPayload[] = []\n  Object.keys(independenciesMap).forEach((inDepPath) => {\n    const paths = toPath(inDepPath)\n    if (\n      (type === \"displayName\" && oldDisplayName === paths[0]) ||\n      (type === \"globalDataKey\" && oldDisplayName === paths[1])\n    ) {\n      const usedPaths = independenciesMap[inDepPath]\n      usedPaths.forEach((usedPath) => {\n        const usedPathArray = toPath(usedPath)\n        const displayName =\n          usedPathArray[0] === oldDisplayName\n            ? newDisplayName\n            : usedPathArray[0]\n        const finalUsedPathArray = [...usedPathArray]\n        finalUsedPathArray.splice(0, 1, displayName)\n        const finalUsedPath = convertPathToString(finalUsedPathArray)\n        const maybeDynamicStringValue = get(seeds, finalUsedPath)\n        if (hasDynamicStringSnippet(maybeDynamicStringValue)) {\n          const newDynamicStringValue = maybeDynamicStringValue.replace(\n            oldDisplayName,\n            newDisplayName,\n          )\n          const propsPath = convertPathToString(usedPathArray.slice(1))\n          const seed = seeds[displayName]\n          if (isAction(seed)) {\n            updateActionSlice.push({\n              displayName: displayName,\n              actionID: seed.$actionID,\n              propsSlice: {\n                [propsPath]: newDynamicStringValue,\n              },\n            })\n          }\n          if (isWidget(seed)) {\n            updateWidgetSlice.push({\n              displayName: displayName,\n              propsSlice: {\n                [propsPath]: newDynamicStringValue,\n              },\n            })\n          }\n        }\n      })\n    }\n  })\n\n  return { updateWidgetSlice, updateActionSlice }\n}\n\nconst changeEventUsedDisplayNameHelper = (\n  events: Record<string, unknown>[],\n  oldDisplayName: string,\n  newDisplayName: string,\n  prefix: string,\n) => {\n  const propsSlice: {\n    [x: string]: unknown\n  } = {}\n  events.forEach((event, index) => {\n    if (event.widgetID === oldDisplayName) {\n      const path = convertPathToString([prefix, index, \"widgetID\"])\n      propsSlice[path] = newDisplayName\n    }\n\n    if (event.queryID === oldDisplayName) {\n      const path = convertPathToString([prefix, index, \"queryID\"])\n      propsSlice[path] = newDisplayName\n    }\n\n    if (event.stateDisplayName === oldDisplayName) {\n      const path = convertPathToString([prefix, index, \"stateDisplayName\"])\n      propsSlice[path] = newDisplayName\n    }\n\n    if (event.actionType === EVENT_ACTION_TYPE.SET_ROUTER) {\n      if (event.pagePath === oldDisplayName) {\n        const path = convertPathToString([prefix, index, \"pagePath\"])\n        propsSlice[path] = newDisplayName\n      }\n      if (event.viewPath === oldDisplayName) {\n        const path = convertPathToString([prefix, index, \"viewPath\"])\n        propsSlice[path] = newDisplayName\n      }\n    }\n  })\n  return propsSlice\n}\n\nconst changeEventHandlerReferenceHelper = (\n  oldDisplayName: string,\n  newDisplayName: string,\n  actionLists: ActionItem<ActionContent>[],\n  componentMaps: Record<string, ComponentMapNode>,\n) => {\n  const updateWidgetSlice: UpdateComponentSlicePropsPayload[] = []\n  const updateActionSlice: UpdateActionSlicePropsPayload[] = []\n\n  actionLists.forEach((action) => {\n    const { content } = action\n    const { successEvent, failedEvent } = content as ActionContent & Events\n    if (Array.isArray(successEvent)) {\n      const prefix = \"content.successEvent\"\n      const propsSlice = changeEventUsedDisplayNameHelper(\n        successEvent,\n        oldDisplayName,\n        newDisplayName,\n        prefix,\n      )\n      updateActionSlice.push({\n        displayName: action.displayName,\n        actionID: action.actionID,\n        propsSlice: propsSlice,\n      })\n    }\n\n    if (Array.isArray(failedEvent)) {\n      const prefix = \"content.failedEvent\"\n\n      const propsSlice = changeEventUsedDisplayNameHelper(\n        failedEvent,\n        oldDisplayName,\n        newDisplayName,\n        prefix,\n      )\n      updateActionSlice.push({\n        displayName: action.displayName,\n        actionID: action.actionID,\n        propsSlice: propsSlice,\n      })\n    }\n  })\n\n  Object.values(componentMaps).forEach((componentMap) => {\n    const { props } = componentMap\n    if (Array.isArray(props?.events)) {\n      const prefix = \"events\"\n      const propsSlice = changeEventUsedDisplayNameHelper(\n        props.events,\n        oldDisplayName,\n        newDisplayName,\n        prefix,\n      )\n      updateWidgetSlice.push({\n        displayName: componentMap.displayName,\n        propsSlice: propsSlice,\n      })\n    }\n  })\n  return { updateWidgetSlice, updateActionSlice }\n}\n\nconst mergeUpdateSlice = (\n  updateWidgetSlice: UpdateComponentSlicePropsPayload[],\n  updateActionSlice: UpdateActionSlicePropsPayload[],\n) => {\n  const updateWidgetSliceMap: Record<string, UpdateComponentSlicePropsPayload> =\n    {}\n\n  updateWidgetSlice.forEach((item) => {\n    const { displayName } = item\n    if (updateWidgetSliceMap[displayName]) {\n      updateWidgetSliceMap[displayName].propsSlice = {\n        ...updateWidgetSliceMap[displayName].propsSlice,\n        ...item.propsSlice,\n      }\n    } else {\n      updateWidgetSliceMap[displayName] = item\n    }\n  })\n\n  const updateActionSliceMap: Record<string, UpdateActionSlicePropsPayload> = {}\n\n  updateActionSlice.forEach((item) => {\n    const { displayName } = item\n    if (updateActionSliceMap[displayName]) {\n      updateActionSliceMap[displayName].propsSlice = {\n        ...updateActionSliceMap[displayName].propsSlice,\n        ...item.propsSlice,\n      }\n    } else {\n      updateActionSliceMap[displayName] = item\n    }\n  })\n\n  return {\n    updateWidgetSlice: Object.values(updateWidgetSliceMap),\n    updateActionSlice: Object.values(updateActionSliceMap),\n  }\n}\n\nexport const mixedChangeDisplayNameHelper = (\n  listenerApi: AppListenerEffectAPI,\n  oldDisplayName: string,\n  newDisplayName: string,\n  type: \"displayName\" | \"globalDataKey\" = \"displayName\",\n) => {\n  const rootState = listenerApi.getState()\n  const independenciesMap = getInDependenciesMap(rootState)\n  const seeds = getRawTree(rootState)\n  const { updateActionSlice, updateWidgetSlice } = changeDisplayNameHelper(\n    independenciesMap,\n    seeds,\n    oldDisplayName,\n    newDisplayName,\n    type,\n  )\n  const {\n    updateActionSlice: updateActionEventSlice,\n    updateWidgetSlice: updateWidgetEventSlice,\n  } = changeEventHandlerReferenceHelper(\n    oldDisplayName,\n    newDisplayName,\n    getActionList(rootState),\n    getComponentMap(rootState),\n  )\n\n  const contactedUpdateActionSlices = updateActionSlice.concat(\n    ...updateActionEventSlice,\n  )\n  const contactedUpdateWidgetSlice = updateWidgetSlice.concat(\n    ...updateWidgetEventSlice,\n  )\n\n  const {\n    updateActionSlice: mergedActionSlice,\n    updateWidgetSlice: mergedWidgetSlice,\n  } = mergeUpdateSlice(contactedUpdateWidgetSlice, contactedUpdateActionSlices)\n  listenerApi.dispatch(\n    componentsActions.batchUpdateMultiComponentSlicePropsReducer(\n      mergedWidgetSlice,\n    ),\n  )\n  listenerApi.dispatch(\n    actionActions.batchUpdateMultiActionSlicePropsReducer(mergedActionSlice),\n  )\n}\n\nexport const copyWidgetDisplayNameHelper = (\n  oldDisplayName: string,\n  newDisplayName: string,\n) => {\n  const rootState = store.getState()\n  const independenciesMap = getInDependenciesMap(rootState)\n  const seeds = getRawTree(rootState)\n  const updatePathsMapValue: Record<string, unknown> = {}\n  Object.keys(independenciesMap).forEach((inDepPath) => {\n    const usedPaths = independenciesMap[inDepPath]\n    usedPaths.forEach((usedPath) => {\n      const usedPathArray = toPath(usedPath)\n      const displayName = usedPathArray[0]\n      if (displayName !== oldDisplayName) {\n        return\n      }\n      const finalUsedPathArray = [...usedPathArray]\n      const finalUsedPath = convertPathToString(finalUsedPathArray)\n      const maybeDynamicStringValue = get(seeds, finalUsedPath)\n      if (hasDynamicStringSnippet(maybeDynamicStringValue)) {\n        const newDynamicStringValue = maybeDynamicStringValue.replace(\n          oldDisplayName,\n          newDisplayName,\n        )\n        const propsPath = convertPathToString(usedPathArray.slice(1))\n        updatePathsMapValue[propsPath] = newDynamicStringValue\n      }\n    })\n  })\n\n  return updatePathsMapValue\n}\n"
  },
  {
    "path": "apps/builder/src/utils/componentNode/buildTree.ts",
    "content": "import { WidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\n\nexport interface NeedBuildNode {\n  displayName: string\n  $parentNode: string\n  $childrenNode: string[]\n  [key: string]: unknown\n}\n\ninterface BuildedNode {\n  displayName: string\n  $parentNode: string\n  $childrenNode: BuildedNode[]\n  [key: string]: unknown\n}\n\nexport function buildForest(\n  nodes: NeedBuildNode[],\n  layoutInfos: Record<string, WidgetLayoutInfo>,\n): BuildedNode[] {\n  const builtNodes: { [key: string]: BuildedNode } = {}\n  const calcContext: Record<string, NeedBuildNode> = {}\n  const needBuildNode = nodes.map((node) => {\n    const mixedNode = {\n      ...node,\n      $parentNode: layoutInfos[node.displayName].parentNode,\n      $childrenNode: layoutInfos[node.displayName].childrenNode,\n    }\n    calcContext[node.displayName] = mixedNode\n    return mixedNode\n  })\n\n  function buildNode(node: NeedBuildNode): BuildedNode {\n    if (builtNodes[node.displayName]) {\n      return builtNodes[node.displayName]\n    }\n\n    const children: BuildedNode[] = (node.$childrenNode || []).map(\n      (childName) => {\n        const childNode = calcContext[childName]\n        return buildNode(childNode)\n      },\n    )\n\n    const builtNode: BuildedNode = {\n      ...node,\n      displayName: node.displayName,\n      $parentNode: node.$parentNode,\n      $childrenNode: children.sort((nodeA, nodeB) => {\n        const displayNameA = nodeA.displayName\n        const displayNameB = nodeB.displayName\n        const layoutInfoA = layoutInfos[displayNameA]\n        const layoutInfoB = layoutInfos[displayNameB]\n        if (!layoutInfoA || !layoutInfoB) {\n          return 0\n        }\n        if (layoutInfoA.layoutInfo.y === layoutInfoB.layoutInfo.y) {\n          return layoutInfoA.layoutInfo.x - layoutInfoB.layoutInfo.x\n        }\n        return layoutInfoA.layoutInfo.y - layoutInfoB.layoutInfo.y\n      }),\n    }\n\n    builtNodes[node.displayName] = builtNode\n\n    return builtNode\n  }\n\n  const forest: BuildedNode[] = needBuildNode\n    .filter((node) => !calcContext[node.$parentNode])\n    .sort((nodeA, nodeB) => {\n      const displayNameA = nodeA.displayName\n      const displayNameB = nodeB.displayName\n      const layoutInfoA = layoutInfos[displayNameA]\n      const layoutInfoB = layoutInfos[displayNameB]\n      if (!layoutInfoA || !layoutInfoB) {\n        return 0\n      }\n      if (layoutInfoA.layoutInfo.y === layoutInfoB.layoutInfo.y) {\n        return layoutInfoA.layoutInfo.x - layoutInfoB.layoutInfo.x\n      }\n      return layoutInfoA.layoutInfo.y - layoutInfoB.layoutInfo.y\n    })\n    .map((rootNode) => buildNode(rootNode))\n\n  return forest\n}\n"
  },
  {
    "path": "apps/builder/src/utils/componentNode/changeDisplayNameHelper.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\n\nexport const changeDisplayNameHelperWhenUndoRedo = (\n  node: ComponentTreeNode,\n) => {\n  const newDisplayName = DisplayNameGenerator.updateOrGenerateDisplayName(\n    node.displayName,\n  )\n\n  node.displayName = newDisplayName\n\n  const childrenNode =\n    node.childrenNode?.map((item) => {\n      item.parentNode = newDisplayName\n      return changeDisplayNameHelperWhenUndoRedo(item)\n    }) ?? []\n\n  node.childrenNode = childrenNode\n\n  return node\n}\n"
  },
  {
    "path": "apps/builder/src/utils/componentNode/copyHelper.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport {\n  clamWidgetShape,\n  combineWidgetInfos,\n} from \"@/page/App/components/DotPanel/utils/getDragShadow\"\n\nexport const getComponentLayoutInfosWithRelativeCombineShape = (\n  componentNodes: ComponentTreeNode[],\n) => {\n  const combineShape = combineWidgetInfos(componentNodes)\n\n  return componentNodes.map((node) => {\n    return {\n      ...node,\n      x: node.x - combineShape.x,\n      y: node.y - combineShape.y,\n    }\n  })\n}\n\nexport const getComponentNodeResultByRelativeCombineShape = (\n  componentNodes: ComponentTreeNode[],\n  columnNumber: number,\n) => {\n  const relativeInfos =\n    getComponentLayoutInfosWithRelativeCombineShape(componentNodes)\n\n  const square = combineWidgetInfos(componentNodes)\n\n  const clamSquare = clamWidgetShape(\n    square,\n    columnNumber,\n    componentNodes.length > 1,\n  )\n\n  const canUsedClamSSquareW = componentNodes.length <= 1\n\n  return relativeInfos\n    .map((info) => ({\n      ...info,\n      x: info.x + clamSquare.x,\n      y: info.y + clamSquare.y,\n      w: canUsedClamSSquareW ? clamSquare.w : info.w,\n    }))\n    .map((node) => {\n      const clamSquareShape = clamWidgetShape(\n        node,\n        columnNumber,\n        componentNodes.length > 1,\n      )\n      return {\n        ...node,\n        x: clamSquareShape.x,\n        y: clamSquareShape.y,\n        w: clamSquareShape.w,\n      }\n    })\n}\n"
  },
  {
    "path": "apps/builder/src/utils/componentNode/flatTree.ts",
    "content": "import { ComponentMapNode, ComponentTreeNode } from \"@illa-public/public-types\"\nimport { getComponentMap } from \"@/redux/currentApp/components/componentsSelector\"\nimport store from \"@/store\"\n\nexport const flatTreeToMap = (componentNode: ComponentTreeNode) => {\n  const map: Record<string, ComponentMapNode> = {}\n  const flatTree = (node: ComponentTreeNode) => {\n    map[node.displayName] = {\n      ...node,\n      childrenNode: Array.isArray(node.childrenNode)\n        ? node.childrenNode.map((childNode) => childNode.displayName)\n        : [],\n    }\n    if (!Array.isArray(node.childrenNode)) {\n      node.childrenNode = []\n    }\n    node.childrenNode.forEach((childNode) => {\n      flatTree(childNode)\n    })\n  }\n  flatTree(componentNode)\n  return map\n}\n\nexport const transTreeToMap = (componentNode: ComponentTreeNode) => {\n  const map = flatTreeToMap(componentNode)\n  return map[componentNode.displayName]\n}\n\nexport function buildTreeByMapNode(\n  rootNodeDisplayName: string = \"root\",\n  nodes: Record<string, ComponentMapNode> = getComponentMap(store.getState()),\n) {\n  const builtNodes: { [key: string]: ComponentTreeNode } = {}\n\n  function buildNode(node: ComponentMapNode): ComponentTreeNode {\n    if (builtNodes[node.displayName]) {\n      return builtNodes[node.displayName]\n    }\n\n    const children: ComponentTreeNode[] = (node.childrenNode || []).map(\n      (childName) => {\n        const childNode = nodes[childName]\n        return buildNode(childNode)\n      },\n    )\n\n    const builtNode: ComponentTreeNode = {\n      ...node,\n      childrenNode: children,\n    }\n\n    builtNodes[node.displayName] = builtNode\n\n    return builtNode\n  }\n\n  const rootNode = nodes[rootNodeDisplayName]\n\n  return buildNode(rootNode)\n}\n"
  },
  {
    "path": "apps/builder/src/utils/componentNode/index.ts",
    "content": "import {\n  convertPathToString,\n  hasDynamicStringSnippet,\n} from \"@illa-public/dynamic-string\"\nimport deepDiff, { Diff } from \"deep-diff\"\nimport { klona } from \"klona/json\"\nimport { set } from \"lodash-es\"\nimport { getWidgetOrActionDynamicAttrPaths } from \"@/utils/evaluateDynamicString/utils\"\nimport { isObject } from \"@/utils/typeHelper\"\n\nenum DynamicAttrPathActions {\n  ADD = \"ADD\",\n  REMOVE = \"REMOVE\",\n  NONE = \"NONE\",\n}\n\ninterface DynamicAttrPathUpdateShape {\n  attrPath: string\n  action: DynamicAttrPathActions\n}\n\nconst generateDynamicAttrPaths = (\n  current: string[],\n  update: DynamicAttrPathUpdateShape,\n): string[] => {\n  if (update.action === DynamicAttrPathActions.ADD) {\n    current.push(update.attrPath)\n  } else if (update.action === DynamicAttrPathActions.REMOVE) {\n    current = current.filter((path) => path !== update.attrPath)\n  }\n  return current\n}\n\nconst getNewEffectByUpdateSlice = (\n  path: string,\n  rValue: unknown,\n): DynamicAttrPathUpdateShape | DynamicAttrPathUpdateShape[] => {\n  if (isObject(rValue)) {\n    return Object.keys(rValue as Record<string, unknown>)\n      .map((key: string) => {\n        const subPath = `${path}.${key}`\n        return getNewEffectByUpdateSlice(\n          subPath,\n          (rValue as Record<string, unknown>)[key],\n        )\n      })\n      .flat()\n  }\n  if (Array.isArray(rValue)) {\n    return (rValue as unknown[])\n      .map((item: unknown, index: number) => {\n        const subPath = convertPathToString([path, `${index}`])\n        return getNewEffectByUpdateSlice(subPath, item)\n      })\n      .flat()\n  }\n  const isRDynamic = hasDynamicStringSnippet(rValue as string)\n  return {\n    attrPath: path,\n    action: isRDynamic\n      ? DynamicAttrPathActions.ADD\n      : DynamicAttrPathActions.NONE,\n  }\n}\n\nconst getUpdateSlicePathAndEffect = (\n  diff: Diff<Record<string, unknown>, Record<string, unknown>>,\n): DynamicAttrPathUpdateShape | DynamicAttrPathUpdateShape[] => {\n  const path = convertPathToString((diff?.path ?? []) as string[])\n  switch (diff.kind) {\n    case \"N\": {\n      const { rhs } = diff\n      if (!isObject(rhs) && !Array.isArray(rhs)) {\n        let stringRValue: any = isObject(rhs) ? JSON.stringify(rhs) : rhs\n        const isRDynamic = hasDynamicStringSnippet(stringRValue)\n\n        return {\n          attrPath: path,\n          action: isRDynamic\n            ? DynamicAttrPathActions.ADD\n            : DynamicAttrPathActions.NONE,\n        }\n      } else {\n        return getNewEffectByUpdateSlice(path, rhs)\n      }\n    }\n    case \"D\": {\n      const { lhs } = diff\n      let stringLValue: any = isObject(lhs) ? JSON.stringify(lhs) : lhs\n      return {\n        attrPath: path,\n        action: stringLValue\n          ? DynamicAttrPathActions.REMOVE\n          : DynamicAttrPathActions.NONE,\n      }\n    }\n    case \"E\": {\n      const { lhs, rhs } = diff\n      let stringRValue: any = isObject(rhs) ? JSON.stringify(rhs) : rhs\n      let stringLValue: any = isObject(lhs) ? JSON.stringify(lhs) : lhs\n\n      const isRDynamic = hasDynamicStringSnippet(stringRValue)\n      const isLDynamic = hasDynamicStringSnippet(stringLValue)\n      if (isRDynamic && !isLDynamic) {\n        return {\n          attrPath: path,\n          action: DynamicAttrPathActions.ADD,\n        }\n      }\n      if (!isRDynamic && isLDynamic) {\n        return {\n          attrPath: path,\n          action: DynamicAttrPathActions.REMOVE,\n        }\n      }\n      return {\n        attrPath: path,\n        action: DynamicAttrPathActions.NONE,\n      }\n    }\n    case \"A\": {\n      return getUpdateSlicePathAndEffect({\n        ...diff.item,\n        path: [...(diff.path as string[]), diff.index],\n      }) as DynamicAttrPathUpdateShape\n    }\n  }\n}\n\nexport const getNewWidgetPropsByUpdateSlice = (\n  updateSlice: Record<string, unknown>,\n  oldWidgetProps: Record<string, unknown>,\n) => {\n  let newWidgetProps = klona(oldWidgetProps)\n  Object.keys(updateSlice).forEach((attrPath) => {\n    set(newWidgetProps, attrPath, updateSlice[attrPath])\n  })\n\n  const diffs = deepDiff(oldWidgetProps, newWidgetProps)\n  if (!Array.isArray(diffs)) return oldWidgetProps\n  const dynamicAttrPathUpdates: DynamicAttrPathUpdateShape[] = diffs\n    .map((diff) => getUpdateSlicePathAndEffect(diff))\n    .flat()\n  const currentDynamicAttrPaths =\n    getWidgetOrActionDynamicAttrPaths(oldWidgetProps)\n\n  const dynamicAttrPaths = dynamicAttrPathUpdates.reduce(\n    generateDynamicAttrPaths,\n    currentDynamicAttrPaths,\n  )\n\n  newWidgetProps.$dynamicAttrPaths = dynamicAttrPaths\n  return newWidgetProps\n}\n"
  },
  {
    "path": "apps/builder/src/utils/componentNode/search.ts",
    "content": "import {\n  DEFAULT_ASIDE_COLUMNS_NUMBER,\n  DEFAULT_BODY_COLUMNS_NUMBER,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { searchDSLByDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { WidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\nimport store from \"@/store\"\nimport { RawTreeShape } from \"../executionTreeHelper/interface\"\n\nexport const searchForefatherSectionNodeDisplayName = (\n  currentDisplayName: string,\n): string | null => {\n  const rootState = store.getState()\n  const widgetsLayoutInfo = getClientWidgetLayoutInfo(rootState)\n  const currentLayoutInfo = widgetsLayoutInfo[currentDisplayName]\n  if (currentLayoutInfo && currentLayoutInfo.widgetType !== \"SECTION_NODE\") {\n    if (currentLayoutInfo.parentNode === \"root\") {\n      return null\n    }\n    return searchForefatherSectionNodeDisplayName(currentLayoutInfo.parentNode)\n  } else {\n    return currentLayoutInfo ? currentLayoutInfo.displayName : null\n  }\n}\n\nexport const getCurrentSectionColumnNumberByChildDisplayName = (\n  displayName: string,\n): number => {\n  const rootState = store.getState()\n  const currentSectionDisplayName =\n    searchForefatherSectionNodeDisplayName(displayName)\n  if (!currentSectionDisplayName) {\n    return DEFAULT_BODY_COLUMNS_NUMBER\n  }\n\n  const executionResult = getExecutionResult(rootState)\n\n  const pageDisplayName =\n    executionResult[currentSectionDisplayName]?.$parentPageName\n\n  if (!pageDisplayName) {\n    return DEFAULT_BODY_COLUMNS_NUMBER\n  }\n\n  const currentNode = searchDSLByDisplayName(currentSectionDisplayName)\n\n  const pageProps = executionResult[pageDisplayName]\n  switch (currentNode.showName) {\n    case \"bodySection\": {\n      return pageProps?.bodyColumns || DEFAULT_BODY_COLUMNS_NUMBER\n    }\n    case \"headerSection\": {\n      return pageProps?.headerColumns || DEFAULT_BODY_COLUMNS_NUMBER\n    }\n    case \"leftSection\": {\n      return pageProps?.leftColumns || DEFAULT_ASIDE_COLUMNS_NUMBER\n    }\n    case \"rightSection\": {\n      return pageProps?.rightColumns || DEFAULT_ASIDE_COLUMNS_NUMBER\n    }\n    case \"footerSection\": {\n      return pageProps?.footerColumns || DEFAULT_BODY_COLUMNS_NUMBER\n    }\n    case \"modalSection\": {\n      return pageProps?.bodyColumns || DEFAULT_BODY_COLUMNS_NUMBER\n    }\n    default: {\n      return DEFAULT_BODY_COLUMNS_NUMBER\n    }\n  }\n}\n\nexport function searchParent(\n  displayName: string,\n  widgetLayoutInfo: Record<string, WidgetLayoutInfo>,\n): string[] {\n  const parent = widgetLayoutInfo[displayName]?.parentNode\n  if (parent) {\n    return [parent, ...searchParent(parent, widgetLayoutInfo)]\n  }\n  return []\n}\n\nexport const autoChangeContainersIndexWhenClick = (\n  currentDisplayName: string,\n) => {\n  const rootState = store.getState()\n  const widgetsLayoutInfo = getClientWidgetLayoutInfo(rootState)\n  const canvasForeFatherDisplayNames = searchParent(\n    currentDisplayName,\n    widgetsLayoutInfo,\n  ).filter(\n    (displayName) => widgetsLayoutInfo[displayName]?.widgetType === \"CANVAS\",\n  )\n  const containerDisplayNames = canvasForeFatherDisplayNames\n    .map((displayName) => ({\n      displayName,\n      parentDisplayName: widgetsLayoutInfo[displayName]?.parentNode,\n    }))\n    .filter(\n      ({ parentDisplayName }) =>\n        widgetsLayoutInfo[parentDisplayName]?.widgetType === \"CONTAINER_WIDGET\",\n    )\n    .map(({ displayName, parentDisplayName }) => {\n      const childrenNode =\n        widgetsLayoutInfo[parentDisplayName]?.childrenNode ?? []\n      const currentIndex = childrenNode.indexOf(displayName)\n      return {\n        displayName: parentDisplayName,\n        value: {\n          currentIndex,\n        },\n      }\n    })\n\n  store.dispatch(\n    executionActions.updateExecutionByMultiDisplayNameReducer(\n      containerDisplayNames,\n    ),\n  )\n\n  return canvasForeFatherDisplayNames\n}\n\nexport const autoChangeWhenClickOnCanvas = (canvasDisplayName: string) => {\n  const rootState = store.getState()\n  const widgetsLayoutInfo = getClientWidgetLayoutInfo(rootState)\n  const parentContainerDisplayName =\n    widgetsLayoutInfo[canvasDisplayName]?.parentNode\n  const indexOfCanvas =\n    widgetsLayoutInfo[parentContainerDisplayName]?.childrenNode.indexOf(\n      canvasDisplayName,\n    )\n  const firstChildDisplayName =\n    widgetsLayoutInfo[canvasDisplayName]?.childrenNode?.length > 0\n      ? widgetsLayoutInfo[canvasDisplayName]?.childrenNode[0]\n      : \"\"\n  if (firstChildDisplayName)\n    store.dispatch(\n      executionActions.updateExecutionByMultiDisplayNameReducer([\n        {\n          displayName: parentContainerDisplayName,\n          value: { currentIndex: indexOfCanvas },\n        },\n      ]),\n    )\n  return firstChildDisplayName\n}\n\nexport const isWidgetInGridListOrList = (\n  tree: RawTreeShape,\n  currentDisplayName: string,\n) => {\n  const search = (currentDisplayName: string): boolean => {\n    const currentWidget = tree[currentDisplayName]\n    const parentDisplayName = currentWidget.$parentNode\n    const parentNode = parentDisplayName ? tree[parentDisplayName] : null\n    if (!parentNode) {\n      return false\n    }\n    if (\n      parentNode.$widgetType === \"GRID_LIST_WIDGET\" ||\n      parentNode.$widgetType === \"LIST_WIDGET\"\n    ) {\n      return true\n    } else {\n      return search(parentDisplayName)\n    }\n  }\n  return search(currentDisplayName)\n}\n"
  },
  {
    "path": "apps/builder/src/utils/copyManager.ts",
    "content": "import { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport {\n  ActionContent,\n  ComponentMapNode,\n  ComponentTreeNode,\n} from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport i18n from \"i18next\"\nimport { klona } from \"klona\"\nimport { set } from \"lodash-es\"\nimport { createMessage } from \"@illa-design/react\"\nimport { onCopyActionItem } from \"@/page/App/components/Actions/api\"\nimport { DEFAULT_BODY_COLUMNS_NUMBER } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { illaSnapshot } from \"@/page/App/components/DotPanel/constant/snapshotNew\"\nimport { canCrossDifferenceColumnNumber } from \"@/page/App/components/DotPanel/utils/getDragShadow\"\nimport { searchDSLByDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getExecution } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport store from \"@/store\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { getActionMixedList } from \"../redux/currentApp/action/actionSelector\"\nimport { getClientWidgetLayoutInfo } from \"../redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { copyWidgetDisplayNameHelper } from \"./changeDisplayNameHelper\"\nimport { getComponentNodeResultByRelativeCombineShape } from \"./componentNode/copyHelper\"\nimport { buildTreeByMapNode } from \"./componentNode/flatTree\"\nimport { getCurrentSectionColumnNumberByChildDisplayName } from \"./componentNode/search\"\nimport { trackInEditor } from \"./mixpanelHelper\"\n\nconst message = createMessage()\n\nconst doPaste = (\n  originCopyComponents: ComponentTreeNode[],\n  oldColumnNumber: number = DEFAULT_BODY_COLUMNS_NUMBER,\n  newColumnNumber: number = DEFAULT_BODY_COLUMNS_NUMBER,\n  sources: \"keyboard\" | \"duplicate\",\n) => {\n  if (\n    newColumnNumber !== oldColumnNumber &&\n    !canCrossDifferenceColumnNumber(originCopyComponents)\n  ) {\n    message.error({\n      content: i18n.t(\"frame.message.session.error\"),\n    })\n    return\n  }\n\n  const newComponents = getComponentNodeResultByRelativeCombineShape(\n    originCopyComponents,\n    newColumnNumber,\n  )\n\n  const types = newComponents.map((component) => component.type)\n\n  trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.DUPLICATE, {\n    element: \"component\",\n    parameter1: types,\n    parameter3: sources,\n  })\n  store.dispatch(componentsActions.addComponentReducer(newComponents))\n}\n\nexport class CopyManager {\n  static currentCopyComponentNodes: ComponentMapNode[] | null = null\n  static copiedColumnNumber: number = DEFAULT_BODY_COLUMNS_NUMBER\n\n  static currentCopyAction: ActionItem<ActionContent> | null = null\n\n  static copyActionByActionID(actionID: string) {\n    const actionList = getActionMixedList(store.getState())\n    const targetAction = actionList.find((item) => {\n      return item.actionID === actionID\n    })\n    if (targetAction) {\n      this.currentCopyAction = targetAction\n    } else {\n      this.currentCopyAction = null\n    }\n  }\n\n  static copyComponentNodeByDisplayName(displayNames: string[]) {\n    if (displayNames.length > 0) {\n      const widgetLayoutInfos = getClientWidgetLayoutInfo(store.getState())\n      illaSnapshot.setSnapshot(widgetLayoutInfos)\n      const copiedColumnNumber =\n        getCurrentSectionColumnNumberByChildDisplayName(displayNames[0])\n      this.currentCopyComponentNodes = displayNames.map((displayName) => {\n        return searchDSLByDisplayName(displayName)\n      })\n      this.copiedColumnNumber = copiedColumnNumber\n    }\n  }\n\n  static paste(sources: \"keyboard\" | \"duplicate\") {\n    const widgetLayoutInfos = getClientWidgetLayoutInfo(store.getState())\n    illaSnapshot.setSnapshot(widgetLayoutInfos)\n    switch (FocusManager.getFocus()) {\n      case \"data_action\":\n      case \"action\":\n        if (this.currentCopyAction != null) {\n          onCopyActionItem(this.currentCopyAction)\n        }\n        break\n      case \"data_component\":\n      case \"canvas\":\n        if (this.currentCopyComponentNodes != null) {\n          const clickPosition = FocusManager.getClickPosition()\n          const needCopyModalComponents = this.currentCopyComponentNodes\n            .filter((item) => item.type === \"MODAL_WIDGET\")\n            .map((needCopyComponent) => {\n              const targetNodeParentNode = searchDSLByDisplayName(\n                needCopyComponent.parentNode!,\n              )\n\n              return this.copyComponent(\n                buildTreeByMapNode(needCopyComponent.displayName),\n                targetNodeParentNode.displayName,\n                needCopyComponent.x,\n                needCopyComponent.y,\n              )\n            })\n          const needCopyOtherComponents = this.currentCopyComponentNodes\n            .filter((item) => item.type !== \"MODAL_WIDGET\")\n            .map((node) => {\n              const layoutInfo = widgetLayoutInfos[node.displayName]\n              return {\n                ...node,\n                x: layoutInfo.layoutInfo.x,\n                y: layoutInfo.layoutInfo.y,\n                w: layoutInfo.layoutInfo.w,\n                h: layoutInfo.layoutInfo.h,\n              }\n            })\n          const copyResult = [...needCopyModalComponents]\n          if (clickPosition) {\n            switch (clickPosition.type) {\n              case \"component\":\n                let targetNode = searchDSLByDisplayName(\n                  clickPosition.displayName,\n                )\n                if (targetNode) {\n                  const targetLayoutInfo =\n                    widgetLayoutInfos[targetNode.displayName]\n                  targetNode = {\n                    ...targetNode,\n                    x: targetLayoutInfo.layoutInfo.x,\n                    y: targetLayoutInfo.layoutInfo.y,\n                    w: targetLayoutInfo.layoutInfo.w,\n                    h: targetLayoutInfo.layoutInfo.h,\n                  }\n                }\n                if (targetNode && targetNode.parentNode) {\n                  const columnNumber =\n                    getCurrentSectionColumnNumberByChildDisplayName(\n                      targetNode.displayName,\n                    )\n                  switch (targetNode.type) {\n                    case \"FORM_WIDGET\":\n                    case \"MODAL_WIDGET\": {\n                      const targetParentNode = searchDSLByDisplayName(\n                        targetNode.childrenNode[1],\n                      )\n                      if (targetParentNode) {\n                        let prevY = 0\n                        copyResult.push(\n                          ...needCopyOtherComponents.map((node) => {\n                            const newNode = this.copyComponent(\n                              buildTreeByMapNode(node.displayName),\n                              targetParentNode.displayName,\n                              0,\n                              prevY,\n                            )\n                            prevY += node.h\n                            return newNode\n                          }),\n                        )\n                      }\n                      break\n                    }\n                    case \"CONTAINER_WIDGET\": {\n                      const executionTree = getExecution(\n                        store.getState(),\n                      ).result\n                      const { currentIndex } =\n                        executionTree[targetNode.displayName]\n                      const targetParentNode = searchDSLByDisplayName(\n                        targetNode.childrenNode[currentIndex],\n                      )\n                      if (targetParentNode) {\n                        let prevY = 0\n                        copyResult.push(\n                          ...needCopyOtherComponents.map((node) => {\n                            const newNode = this.copyComponent(\n                              buildTreeByMapNode(node.displayName),\n                              targetParentNode.displayName,\n                              0,\n                              prevY,\n                            )\n                            prevY += node.h\n                            return newNode\n                          }),\n                        )\n                      }\n                      break\n                    }\n                    case \"LIST_WIDGET\":\n                    case \"GRID_LIST_WIDGET\": {\n                      const targetParentNode = searchDSLByDisplayName(\n                        targetNode.childrenNode[0],\n                      )\n                      if (targetParentNode) {\n                        let prevY = 0\n                        copyResult.push(\n                          ...needCopyOtherComponents.map((node) => {\n                            const newNode = this.copyComponent(\n                              buildTreeByMapNode(node.displayName),\n                              targetParentNode.displayName,\n                              0,\n                              prevY,\n                            )\n                            prevY += node.h\n                            return newNode\n                          }),\n                        )\n                      }\n                      break\n                    }\n                    default: {\n                      const targetParentNode = searchDSLByDisplayName(\n                        targetNode.parentNode,\n                      )\n                      if (targetParentNode) {\n                        let leftTopX = Number.MAX_SAFE_INTEGER\n                        let leftTopY = Number.MAX_SAFE_INTEGER\n                        needCopyOtherComponents.forEach((node) => {\n                          leftTopX = Math.min(leftTopX, node.x)\n                          leftTopY = Math.min(leftTopY, node.y)\n                        })\n                        copyResult.push(\n                          ...needCopyOtherComponents.map((node) => {\n                            return this.copyComponent(\n                              buildTreeByMapNode(node.displayName),\n                              targetParentNode.displayName,\n                              targetNode!.x + node.x - leftTopX,\n                              targetNode!.y + targetNode!.h + node.y - leftTopY,\n                            )\n                          }),\n                        )\n                      }\n                    }\n                  }\n                  doPaste(\n                    copyResult,\n                    this.copiedColumnNumber,\n                    columnNumber,\n                    sources,\n                  )\n                } else {\n                  message.normal({\n                    content: i18n.t(\"frame.paste_no_aimed\"),\n                  })\n                }\n                break\n              case \"inner_container\":\n                if (clickPosition.clickPosition.length !== 2) {\n                  message.normal({\n                    content: i18n.t(\"frame.paste_no_aimed\"),\n                  })\n                  return\n                }\n                const containerNode = searchDSLByDisplayName(\n                  clickPosition.displayName,\n                )\n                if (containerNode) {\n                  const columnNumber =\n                    getCurrentSectionColumnNumberByChildDisplayName(\n                      containerNode.displayName,\n                    )\n                  let leftTopX = Number.MAX_SAFE_INTEGER\n                  let leftTopY = Number.MAX_SAFE_INTEGER\n\n                  this.currentCopyComponentNodes.forEach((node) => {\n                    leftTopX = Math.min(leftTopX, node.x)\n                    leftTopY = Math.min(leftTopY, node.y)\n                  })\n\n                  const originCopyComponents =\n                    this.currentCopyComponentNodes.map((node) => {\n                      const layoutInfo = widgetLayoutInfos[node.displayName]\n                      const needCopyComponent = {\n                        ...node,\n                        x: layoutInfo.layoutInfo.x,\n                        y: layoutInfo.layoutInfo.y,\n                        w: layoutInfo.layoutInfo.w,\n                        h: layoutInfo.layoutInfo.h,\n                      }\n                      if (needCopyComponent.type === \"MODAL_WIDGET\") {\n                        const targetNodeParentNode = searchDSLByDisplayName(\n                          needCopyComponent.parentNode!,\n                        )\n                        return this.copyComponent(\n                          buildTreeByMapNode(needCopyComponent.displayName),\n                          targetNodeParentNode.displayName,\n                          needCopyComponent.x,\n                          needCopyComponent.y,\n                        )\n                      }\n                      return this.copyComponent(\n                        buildTreeByMapNode(needCopyComponent.displayName),\n                        containerNode.displayName,\n                        clickPosition.clickPosition[0] +\n                          needCopyComponent.x -\n                          leftTopX,\n                        clickPosition.clickPosition[1] +\n                          needCopyComponent.y -\n                          leftTopY,\n                      )\n                    })\n\n                  doPaste(\n                    originCopyComponents,\n                    this.copiedColumnNumber,\n                    columnNumber,\n                    sources,\n                  )\n                } else {\n                  message.normal({\n                    content: i18n.t(\"frame.paste_no_aimed\"),\n                  })\n                }\n                break\n              case \"group\":\n                const targetParentNode = searchDSLByDisplayName(\n                  clickPosition.displayName,\n                )\n                if (targetParentNode) {\n                  const columnNumber =\n                    getCurrentSectionColumnNumberByChildDisplayName(\n                      targetParentNode.displayName,\n                    )\n                  let leftTopX = Number.MAX_SAFE_INTEGER\n                  let leftTopY = Number.MAX_SAFE_INTEGER\n                  this.currentCopyComponentNodes.forEach((node) => {\n                    leftTopX = Math.min(leftTopX, node.x)\n                    leftTopY = Math.min(leftTopY, node.y)\n                  })\n\n                  const originCopyComponents =\n                    this.currentCopyComponentNodes.map((node) => {\n                      const layoutInfo = widgetLayoutInfos[node.displayName]\n                      const needCopyComponent = {\n                        ...node,\n                        x: layoutInfo.layoutInfo.x,\n                        y: layoutInfo.layoutInfo.y,\n                        w: layoutInfo.layoutInfo.w,\n                        h: layoutInfo.layoutInfo.h,\n                      }\n                      if (needCopyComponent.type === \"MODAL_WIDGET\") {\n                        const targetNodeParentNode = searchDSLByDisplayName(\n                          needCopyComponent.parentNode!,\n                        )\n                        return this.copyComponent(\n                          buildTreeByMapNode(needCopyComponent.displayName),\n                          targetNodeParentNode.displayName,\n                          needCopyComponent.x,\n                          needCopyComponent.y,\n                        )\n                      }\n                      return this.copyComponent(\n                        buildTreeByMapNode(needCopyComponent.displayName),\n                        targetParentNode.displayName,\n                        clickPosition.clickPosition[0] +\n                          needCopyComponent.x -\n                          leftTopX,\n                        clickPosition.clickPosition[1] +\n                          clickPosition.clickPosition[3] +\n                          needCopyComponent.y -\n                          leftTopY,\n                      )\n                    })\n\n                  doPaste(\n                    originCopyComponents,\n                    this.copiedColumnNumber,\n                    columnNumber,\n                    sources,\n                  )\n                }\n            }\n          }\n        }\n        break\n      case \"none\":\n        break\n      case \"components_config\":\n        break\n      case \"page_config\":\n        break\n      case \"data_page\":\n        break\n      case \"data_global_state\":\n        break\n      case \"widget_picker\":\n        break\n    }\n  }\n\n  static copyComponent(\n    node: ComponentTreeNode,\n    newParentNodeDisplayName: string,\n    rawX: number,\n    rawY: number,\n  ): ComponentTreeNode {\n    const newDisplayName = DisplayNameGenerator.generateDisplayName(\n      node.type,\n      node.showName,\n    )\n\n    const updatePathsMapValue = copyWidgetDisplayNameHelper(\n      node.displayName,\n      newDisplayName,\n    )\n\n    const newNode = klona({\n      ...node,\n      props: node.props ?? {},\n      displayName: newDisplayName,\n      x: rawX,\n      y: rawY,\n      w: node.w,\n      h: node.h,\n      parentNode: newParentNodeDisplayName,\n    } as ComponentTreeNode)\n\n    Object.keys(updatePathsMapValue).forEach((key) => {\n      set(newNode, `props.${key}`, updatePathsMapValue[key])\n    })\n\n    if (Array.isArray(node.childrenNode)) {\n      newNode.childrenNode = node.childrenNode.map((n) =>\n        this.copyComponent(n, newNode.displayName, n.x, n.y),\n      )\n    }\n    return newNode\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/copyToClipboard.ts",
    "content": "import { COPY_STATUS, copyToClipboard as copy } from \"@illa-public/utils\"\nimport { createMessage } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\n\nconst message = createMessage()\n\nexport const copyToClipboard = (text: string) => {\n  const flag = copy(text)\n  if (flag === COPY_STATUS.EMPTY) {\n    message.info({\n      content: i18n.t(\"empty_copied_tips\"),\n    })\n  } else {\n    message.success({\n      content: i18n.t(\"copied\"),\n    })\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/drag/drag.ts",
    "content": "import { configActions } from \"@/redux/config/configSlice\"\nimport { WidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\nimport store from \"@/store\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { FocusManager } from \"../focusManager\"\n\nexport function startDragMultiNodes(dragWidgetInfos: WidgetLayoutInfo[]) {\n  store.dispatch(configActions.updateShowDot(true))\n  const displayNames = dragWidgetInfos.map((node) => node.displayName)\n  store.dispatch(configActions.setDraggingNodeIDsReducer(displayNames))\n}\n\nexport function endDragMultiNodes(\n  dragWidgetInfos: WidgetLayoutInfo[],\n  isDropOnCanvas: boolean,\n  isAddAction: boolean = false,\n) {\n  store.dispatch(configActions.updateShowDot(false))\n  const displayNames = dragWidgetInfos.map((node) => node.displayName)\n  store.dispatch(configActions.setDraggingNodeIDsReducer([]))\n\n  if (isDropOnCanvas) {\n    FocusManager.switchFocus(\"canvas\", {\n      displayName: displayNames[0],\n      type: \"component\",\n      clickPosition: [],\n    })\n    store.dispatch(configActions.updateSelectedComponent(displayNames))\n  }\n\n  if (isAddAction && !isDropOnCanvas) {\n    DisplayNameGenerator.removeDisplayName(dragWidgetInfos[0].displayName)\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/drive/upload/getSingedURL.ts",
    "content": "import { ERROR_FLAG } from \"@illa-public/illa-net\"\nimport { isILLAAPiError } from \"@illa-public/illa-net\"\nimport {\n  DRIVE_FILE_TYPE,\n  GCS_OBJECT_TYPE,\n  UPLOAD_FILE_DUPLICATION_HANDLER,\n  UPLOAD_FILE_STATUS,\n} from \"@illa-public/public-types\"\nimport axios from \"axios\"\nimport { Zip, ZipPassThrough } from \"fflate\"\nimport { createWriteStream } from \"streamsaver\"\nimport { createMessage } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { FILE_ITEM_DETAIL_STATUS_IN_UI } from \"@/page/App/Module/UploadDetail/components/DetailList/interface\"\nimport { updateFileDetailStore } from \"@/page/App/Module/UploadDetail/store\"\nimport { ILLARoute } from \"@/router\"\nimport {\n  fetchFileList,\n  fetchGetUploadFileURL,\n  fetchUpdateFileStatus,\n  fetchUploadFilesStatusAnonymous,\n  fetchUploadFilesToAnonymous,\n} from \"@/services/drive\"\n\nexport enum GET_SINGED_URL_ERROR_CODE {\n  NOT_HAS_ROOT_FOLDER = \"NOT_HAS_ROOT_FOLDER\",\n  UPLOAD_FAILED = \"UPLOAD_FAILED\",\n}\n\nconst message = createMessage()\n\nexport const getUploadToDriveSingedURL = async (\n  allowAnonymous: boolean,\n  folderPath: string,\n  fileInfo: {\n    fileName: string\n    size: number\n    contentType: string\n    replace: boolean\n  },\n  abortSignal?: AbortSignal,\n) => {\n  if (!allowAnonymous) {\n    try {\n      const fileList = await fetchFileList(\n        {\n          path: \"/root\",\n          type: DRIVE_FILE_TYPE.MIX,\n        },\n        abortSignal,\n      )\n      if (!fileList.data.currentFolderID)\n        throw new Error(GET_SINGED_URL_ERROR_CODE.UPLOAD_FAILED)\n      const singedURLResponse = await fetchGetUploadFileURL(\n        {\n          name: folderPath\n            ? `${folderPath}/${fileInfo.fileName}`\n            : fileInfo.fileName,\n          type: GCS_OBJECT_TYPE.FILE,\n          contentType: fileInfo.contentType,\n          size: fileInfo.size,\n          folderID: fileList.data.currentFolderID,\n          duplicationHandler: fileInfo.replace\n            ? UPLOAD_FILE_DUPLICATION_HANDLER.COVER\n            : UPLOAD_FILE_DUPLICATION_HANDLER.RENAME,\n        },\n        abortSignal,\n      )\n      return {\n        url: singedURLResponse.data.url,\n        fileID: singedURLResponse.data.id,\n        fileName: singedURLResponse.data.name,\n      }\n    } catch (e) {\n      if (isILLAAPiError(e)) {\n        return Promise.reject(e)\n      }\n      throw new Error(GET_SINGED_URL_ERROR_CODE.UPLOAD_FAILED)\n    }\n  } else {\n    try {\n      const appID = ILLARoute.state.matches[0].params.appId\n      if (typeof appID !== \"string\")\n        throw new Error(GET_SINGED_URL_ERROR_CODE.UPLOAD_FAILED)\n\n      const singedURLResponse = await fetchUploadFilesToAnonymous(\n        appID,\n        {\n          name: fileInfo.fileName,\n          type: GCS_OBJECT_TYPE.FILE,\n          contentType: fileInfo.contentType,\n          size: fileInfo.size,\n          duplicationHandler: fileInfo.replace\n            ? UPLOAD_FILE_DUPLICATION_HANDLER.COVER\n            : UPLOAD_FILE_DUPLICATION_HANDLER.RENAME,\n        },\n        abortSignal,\n      )\n      return {\n        url: singedURLResponse.data.url,\n        fileID: singedURLResponse.data.id,\n        fileName: singedURLResponse.data.name,\n      }\n    } catch (e) {\n      if (isILLAAPiError(e)) {\n        return Promise.reject(e)\n      }\n      throw new Error(GET_SINGED_URL_ERROR_CODE.UPLOAD_FAILED)\n    }\n  }\n}\n\nexport const updateFilesToDrive = async (\n  url: string,\n  uploadFile: File,\n  processCall?: (loaded: number) => void,\n  abortSignal?: AbortSignal,\n) => {\n  try {\n    const openUploadLink = await axios.post(url, null, {\n      headers: {\n        \"x-goog-resumable\": \"start\",\n        \"Content-Type\": uploadFile.type,\n      },\n      withCredentials: false,\n      signal: abortSignal,\n    })\n    if (openUploadLink.headers.location) {\n      await axios.put(openUploadLink.headers.location, uploadFile, {\n        headers: {\n          \"Content-Type\": uploadFile.type,\n        },\n        withCredentials: false,\n        signal: abortSignal,\n        onUploadProgress: (progressEvent) => {\n          if (processCall) processCall(progressEvent.loaded)\n        },\n      })\n      return Promise.resolve(UPLOAD_FILE_STATUS.COMPLETE)\n    }\n    return Promise.resolve(UPLOAD_FILE_STATUS.FAILED)\n  } catch (e) {\n    return Promise.resolve(UPLOAD_FILE_STATUS.FAILED)\n  }\n}\n\nexport const updateFilesToDriveStatus = async (\n  allowAnonymous: boolean,\n  fileID: string,\n  uploadFileStatus: UPLOAD_FILE_STATUS,\n) => {\n  if (!allowAnonymous) {\n    await fetchUpdateFileStatus(fileID, uploadFileStatus)\n  } else {\n    const appID = ILLARoute.state.matches[0].params.appId\n    if (typeof appID !== \"string\") return\n    await fetchUploadFilesStatusAnonymous(appID, fileID, uploadFileStatus)\n  }\n}\n\nexport const uploadFileToDrive = async (\n  queryID: string,\n  needUploadFile: File,\n  fileOptions: {\n    allowAnonymous: boolean\n    folder: string\n    replace: boolean\n  },\n  abortSignal: AbortSignal,\n) => {\n  const { allowAnonymous, folder, replace } = fileOptions\n  try {\n    updateFileDetailStore.updateFileDetailInfo(queryID, {\n      loaded: 0,\n      total: needUploadFile.size,\n      status: FILE_ITEM_DETAIL_STATUS_IN_UI.WAITING,\n    })\n    const uploadURLResponse = await getUploadToDriveSingedURL(\n      allowAnonymous,\n      folder,\n      {\n        fileName: needUploadFile.name,\n        size: needUploadFile.size,\n        contentType: needUploadFile.type,\n        replace,\n      },\n      abortSignal,\n    )\n\n    updateFileDetailStore.updateFileDetailInfo(queryID, {\n      loaded: 0,\n      total: needUploadFile.size,\n      status: FILE_ITEM_DETAIL_STATUS_IN_UI.PROCESSING,\n    })\n\n    const processCallback = (loaded: number) => {\n      updateFileDetailStore.updateFileDetailInfo(queryID!, {\n        loaded: loaded,\n        status: FILE_ITEM_DETAIL_STATUS_IN_UI.PROCESSING,\n      })\n    }\n    const uploadResult = await updateFilesToDrive(\n      uploadURLResponse.url,\n      needUploadFile,\n      processCallback,\n      abortSignal,\n    )\n    await updateFilesToDriveStatus(\n      allowAnonymous,\n      uploadURLResponse.fileID,\n      uploadResult,\n    )\n    if (uploadResult === UPLOAD_FILE_STATUS.COMPLETE) {\n      updateFileDetailStore.updateFileDetailInfo(queryID, {\n        status: FILE_ITEM_DETAIL_STATUS_IN_UI.SUCCESS,\n      })\n      message.success({\n        content: i18n.t(\"editor.inspect.setter_message.uploadsuc\"),\n      })\n      return {\n        id: uploadURLResponse.fileID,\n        name: uploadURLResponse.fileName,\n      }\n    } else {\n      updateFileDetailStore.updateFileDetailInfo(queryID, {\n        status: FILE_ITEM_DETAIL_STATUS_IN_UI.ERROR,\n      })\n      message.error({\n        content: i18n.t(\"editor.inspect.setter_message.uploadfail\"),\n      })\n    }\n  } catch (e) {\n    updateFileDetailStore.updateFileDetailInfo(queryID, {\n      status: FILE_ITEM_DETAIL_STATUS_IN_UI.ERROR,\n    })\n    message.error({\n      content: i18n.t(\"editor.inspect.setter_message.uploadfail\"),\n    })\n    throw e\n  }\n}\n\nexport const handleFileToDriveResource = async (\n  queryID: string,\n  fileID: string,\n  uploadURL: string,\n  file: File,\n  abortSignal: AbortSignal,\n) => {\n  try {\n    updateFileDetailStore.updateFileDetailInfo(queryID, {\n      loaded: 0,\n      total: file.size,\n      status: FILE_ITEM_DETAIL_STATUS_IN_UI.PROCESSING,\n    })\n\n    const processCallback = (loaded: number) => {\n      updateFileDetailStore.updateFileDetailInfo(queryID!, {\n        loaded: loaded,\n        status: FILE_ITEM_DETAIL_STATUS_IN_UI.PROCESSING,\n      })\n    }\n    const uploadResult = await updateFilesToDrive(\n      uploadURL,\n      file,\n      processCallback,\n      abortSignal,\n    )\n    return {\n      fileID,\n      status: uploadResult,\n    }\n  } catch (e) {\n    if (isILLAAPiError(e)) {\n      if (e.data.errorMessage === ERROR_FLAG.ERROR_FLAG_OUT_OF_USAGE_VOLUME) {\n        message.error({\n          content: i18n.t(\"editor.inspect.setter_message.noStorage\"),\n        })\n      }\n    }\n    message.error({\n      content: i18n.t(\"editor.inspect.setter_message.uploadfail\"),\n    })\n    throw e\n  }\n}\n\nexport const handleDownloadFromDriveResource = async (\n  downloadInfo: { name: string; downloadURL: string }[],\n  asZip?: boolean,\n) => {\n  if (!Array.isArray(downloadInfo) || downloadInfo.length === 0) {\n    return Promise.reject()\n  }\n  let promise = Promise.resolve()\n  const zip = new Zip()\n  const zipName = `illa_drive_download_${new Date().getTime()}.zip`\n  const zipReadableStream = new ReadableStream({\n    start(controller) {\n      zip.ondata = (error, data, final) => {\n        if (error) {\n          controller.error(error)\n        } else {\n          controller.enqueue(data)\n          if (final) {\n            controller.close()\n          }\n        }\n      }\n    },\n  })\n  if (asZip) {\n    const streamsaver = createWriteStream(zipName)\n    zipReadableStream.pipeTo(streamsaver)\n  }\n\n  for (let i = 0; i < downloadInfo.length; i++) {\n    const { name, downloadURL } = downloadInfo[i]\n    promise = promise.then(async () => {\n      try {\n        const fileResponse = await fetch(downloadURL)\n\n        if (!asZip && window.WritableStream && fileResponse.body?.pipeTo) {\n          const fileStream = createWriteStream(name)\n          return fileResponse.body.pipeTo(fileStream)\n        }\n        if (asZip) {\n          const zipStream = new ZipPassThrough(name)\n          zip.add(zipStream)\n          const fileReader = fileResponse.body?.getReader()\n          while (fileReader) {\n            const { value, done } = await fileReader.read()\n            if (done) {\n              zipStream.push(new Uint8Array(0), true)\n              return Promise.resolve()\n            }\n            zipStream.push(value)\n          }\n        }\n      } catch (e) {\n        return Promise.reject(e)\n      }\n    })\n  }\n  if (asZip) {\n    promise.then(() => {\n      zip.end()\n    })\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/evaluateDynamicString/codeSandbox.ts",
    "content": "import { klona } from \"klona\"\n\nconst blacklistSet = new Set([\n  \"top\",\n  \"window\",\n  \"self\",\n  \"globalThis\",\n  \"global\",\n  \"frames\",\n  \"parent\",\n  \"fetch\",\n  \"XMLHttpRequest\",\n  \"document\",\n  \"MutationObserver\",\n])\n\nconst globalVarNames = new Set<PropertyKey>([\n  \"window\",\n  \"globalThis\",\n  \"self\",\n  \"global\",\n])\n\nfunction runUsersCode(code: string) {\n  const finalCode = `with(this){\n    return (function() {\n      'use strict';\n      return (${code});\n    }).call(this);\n  }`\n  return new Function(finalCode)\n}\n\nfunction isDomElement(obj: any): boolean {\n  return obj instanceof Element || obj instanceof HTMLCollection\n}\n\nfunction getPropertyFromNativeWindow(prop: PropertyKey) {\n  const ret = Reflect.get(window, prop)\n  if (typeof ret === \"function\" && !ret.prototype) {\n    return ret.bind(window)\n  }\n  // get DOM element by id, serializing may cause error\n  if (isDomElement(ret)) {\n    return undefined\n  }\n  return ret\n}\n\nfunction createBlackHole(): any {\n  return new Proxy(\n    function () {\n      return createBlackHole()\n    },\n    {\n      get(t, p) {\n        if (p === \"toString\") {\n          return function () {\n            return \"\"\n          }\n        }\n        if (p === Symbol.toPrimitive) {\n          return function () {\n            return \"\"\n          }\n        }\n        return createBlackHole()\n      },\n    },\n  )\n}\n\nfunction createMockWindow(base?: object) {\n  const win: any = new Proxy(Object.assign({}, base), {\n    has() {\n      return true\n    },\n    set(target, p, newValue) {\n      return Reflect.set(target, p, newValue)\n    },\n    get(target, p) {\n      if (p in target) {\n        return Reflect.get(target, p)\n      }\n      if (globalVarNames.has(p)) {\n        return win\n      }\n      if (typeof p === \"string\" && blacklistSet.has(p)) {\n        return createBlackHole()\n      }\n      return getPropertyFromNativeWindow(p)\n    },\n  })\n  return win\n}\n\nfunction proxySandbox(context: any) {\n  const isProtectedVar = (key: PropertyKey) => {\n    return key in context || globalVarNames.has(key)\n  }\n  const mockWindow = createMockWindow(undefined)\n\n  return new Proxy(mockWindow, {\n    has() {\n      return true\n    },\n    get(target, p, receiver) {\n      if (p === Symbol.unscopables) {\n        return undefined\n      }\n\n      if (p === \"toJSON\") {\n        return target\n      }\n\n      if (globalVarNames.has(p)) {\n        return target\n      }\n\n      if (p in context) {\n        let value = Reflect.get(context, p, receiver)\n        if (typeof value === \"object\" && value !== null) {\n          Object.freeze(value)\n          Object.values(value).forEach(Object.freeze)\n        }\n        return value\n      }\n\n      return Reflect.get(target, p, receiver)\n    },\n\n    set(target, p, value, receiver) {\n      if (isProtectedVar(p)) {\n        throw new Error(p.toString() + \" can't be modified\")\n      }\n      return Reflect.set(target, p, value, receiver)\n    },\n\n    defineProperty(target, p, attributes) {\n      if (isProtectedVar(p)) {\n        throw new Error(\"can't define property:\" + p.toString())\n      }\n      return Reflect.defineProperty(target, p, attributes)\n    },\n\n    deleteProperty(target, p) {\n      if (isProtectedVar(p)) {\n        throw new Error(\"can't delete property:\" + p.toString())\n      }\n      return Reflect.deleteProperty(target, p)\n    },\n\n    setPrototypeOf() {\n      throw new Error(\"can't invoke setPrototypeOf\")\n    },\n  })\n}\n\nexport const evalScript = (script: string, dataTree: Record<string, any>) => {\n  const userCode = runUsersCode(script)\n  const sandbox = proxySandbox(dataTree)\n  const result = userCode.call(sandbox)\n  return klona(result)\n}\n"
  },
  {
    "path": "apps/builder/src/utils/evaluateDynamicString/dynamicConverter.ts",
    "content": "import {\n  getStringSnippets,\n  isDynamicStringSnippet,\n} from \"@illa-public/dynamic-string\"\nimport { klona } from \"klona\"\nimport { ILLAEditorRuntimePropsCollectorInstance } from \"../executionTreeHelper/runtimePropsCollector\"\nimport { evalScript } from \"./codeSandbox\"\nimport { substituteDynamicBindingWithValues } from \"./valueConverter\"\n\nexport const getSnippets = (\n  dynamicString: string,\n): { stringSnippets: string[]; jsSnippets: string[] } => {\n  if (!dynamicString || typeof dynamicString !== \"string\") {\n    return { stringSnippets: [], jsSnippets: [] }\n  }\n  const sanitisedString = dynamicString.trim()\n  let stringSnippets: string[], jsSnippets: string[]\n  stringSnippets = getStringSnippets(sanitisedString)\n  jsSnippets = stringSnippets.map((segment) => {\n    const length = segment.length\n    const matches = isDynamicStringSnippet(segment)\n    if (matches) {\n      return segment.substring(2, length - 2)\n    }\n    return \"\"\n  })\n\n  return { stringSnippets, jsSnippets }\n}\n\nexport const getDynamicValue = (\n  dynamicString: string,\n  dataTree: Record<string, any>,\n) => {\n  const { jsSnippets, stringSnippets } = getSnippets(dynamicString)\n  const cloneDeepDataTree = klona(dataTree)\n  const calcContext = {\n    ...cloneDeepDataTree,\n    ...ILLAEditorRuntimePropsCollectorInstance.getThirdPartyPackages(),\n  }\n  if (stringSnippets.length) {\n    let context: Record<string, unknown> = {}\n    const values = jsSnippets.map((jsSnippet, index) => {\n      if (jsSnippet) {\n        const value = evalScript(jsSnippet, calcContext)\n        context[jsSnippet] = value\n        return value\n      } else {\n        return stringSnippets[index]\n      }\n    })\n    if (stringSnippets.length === 1) {\n      return {\n        result: values[0],\n        context,\n      }\n    }\n    return {\n      result: substituteDynamicBindingWithValues(\n        dynamicString,\n        stringSnippets,\n        values,\n      ),\n      context,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/evaluateDynamicString/index.ts",
    "content": "import { hasDynamicStringSnippet } from \"@illa-public/dynamic-string\"\nimport { isRunScriptAttr } from \"../executionTreeHelper/executionTreeFactory\"\nimport { getDynamicValue } from \"./dynamicConverter\"\nimport { isWrapperCode, realInputValueWithScript } from \"./valueConverter\"\n\nexport const evaluateDynamicString = (\n  keyInDataTree: string,\n  dynamicString: string,\n  dataTree: Record<string, any>,\n) => {\n  const requiresEval = hasDynamicStringSnippet(dynamicString)\n  let evalResult\n  if (requiresEval) {\n    if (isRunScriptAttr(keyInDataTree) && isWrapperCode(dynamicString)) {\n      evalResult = realInputValueWithScript(dynamicString, true)\n    } else {\n      try {\n        const result = getDynamicValue(dynamicString, dataTree)\n        evalResult = result?.result\n      } catch (error) {\n        evalResult = undefined\n        throw error\n      }\n    }\n  } else {\n    evalResult = dynamicString\n  }\n  return evalResult\n}\n\nexport const evaluateDynamicStringAndGetCalcContext = (\n  keyInDataTree: string,\n  dynamicString: string,\n  dataTree: Record<string, any>,\n) => {\n  const requiresEval = hasDynamicStringSnippet(dynamicString)\n  let evalResult\n  let context: Record<string, unknown> = {}\n  if (requiresEval) {\n    if (isRunScriptAttr(keyInDataTree) && isWrapperCode(dynamicString)) {\n      evalResult = realInputValueWithScript(dynamicString, true)\n    } else {\n      try {\n        const result = getDynamicValue(dynamicString, dataTree)\n        evalResult = result?.result\n        context = result?.context || {}\n      } catch (error) {\n        evalResult = undefined\n        context = {}\n        throw error\n      }\n    }\n  } else {\n    evalResult = dynamicString\n  }\n  return {\n    result: evalResult,\n    context,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/evaluateDynamicString/utils.ts",
    "content": "import { isDynamicStringSnippet } from \"@illa-public/dynamic-string\"\nimport { getSnippets } from \"./dynamicConverter\"\n\nexport const QUOTED_DYNAMIC_STRING_REGEX = /[\"']({{[\\s\\S]*?}})[\"']/g\nexport const DYNAMIC_STRING_REG = /{{([\\s\\S]*?)}}/\n\nexport const filterBindingSegmentsAndRemoveQuotes = (\n  originDynamicString: string,\n  originStringSnippets: string[],\n  originValues: unknown[],\n) => {\n  const dynamicStringStrippedQuotes = originDynamicString.replace(\n    QUOTED_DYNAMIC_STRING_REGEX,\n    (original, firstGroup) => {\n      return firstGroup\n    },\n  )\n  const stringSnippets: string[] = []\n  const values: unknown[] = []\n  originStringSnippets.forEach((segment, i) => {\n    if (isDynamicStringSnippet(segment)) {\n      stringSnippets.push(segment)\n      values.push(originValues[i])\n    }\n  })\n  return { dynamicString: dynamicStringStrippedQuotes, stringSnippets, values }\n}\n\nexport const stringToJS = (string: string): string => {\n  const { jsSnippets, stringSnippets } = getSnippets(string)\n  return stringSnippets\n    .map((segment, index) => {\n      if (jsSnippets[index] && jsSnippets[index].length > 0) {\n        return jsSnippets[index]\n      } else {\n        return `'${segment}'`\n      }\n    })\n    .join(\" + \")\n}\n\nexport const JSToString = (js: string): string => {\n  const segments = js.split(\" + \")\n  return segments\n    .map((segment) => {\n      if (segment.charAt(0) === \"'\") {\n        return segment.substring(1, segment.length - 1)\n      } else return \"{{\" + segment + \"}}\"\n    })\n    .join(\"\")\n}\n\nexport const wrapCode = (code: string) => {\n  return `\n    (function() {\n      return ${code}\n    })\n  `\n}\nexport function getDisplayNameAndAttrPath(fullPath: string): {\n  displayName: string\n  attrPath: string\n} {\n  const indexOfFirstDot = fullPath.indexOf(\".\")\n  if (indexOfFirstDot === -1) {\n    // No dot was found so path is the entity name itself\n    return {\n      displayName: fullPath,\n      attrPath: \"\",\n    }\n  }\n  const displayName = fullPath.substring(0, indexOfFirstDot)\n  const attrPath = fullPath.substring(indexOfFirstDot + 1)\n  return { displayName, attrPath }\n}\n\nexport const getWidgetOrActionDynamicAttrPaths = (\n  widgetOrAction: Record<string, any>,\n): string[] => {\n  if (Array.isArray(widgetOrAction.$dynamicAttrPaths)) {\n    return [...widgetOrAction.$dynamicAttrPaths]\n  }\n  return []\n}\n\nexport const wrapFunctionCode = (code: string) => {\n  return `(function (){\n      ${code}\n    })\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/utils/evaluateDynamicString/valueConverter.ts",
    "content": "import { Types, getType, isObject } from \"@/utils/typeHelper\"\nimport { filterBindingSegmentsAndRemoveQuotes } from \"./utils\"\n\nexport const templateSubstituteDynamicValues = (\n  dynamicString: string,\n  stringSnippets: string[],\n  values: unknown[],\n): string => {\n  let finalValue = dynamicString\n  stringSnippets.forEach((b, i) => {\n    let value = values[i]\n    if (Array.isArray(value) || isObject(value)) {\n      value = JSON.stringify(value)\n    }\n    try {\n      if (typeof value === \"string\" && JSON.parse(value)) {\n        value = value.replace(/\\\\([\\s\\S])|(\")/g, \"\\\\$1$2\")\n      }\n    } catch (e) {\n      // do nothing\n    }\n    finalValue = finalValue.replace(b, `${value}`)\n  })\n  return finalValue\n}\n\nexport const smartSubstituteDynamicValues = (\n  originDynamicString: string,\n  originStringSnippets: string[],\n  originValues: unknown[],\n): string => {\n  const { dynamicString, stringSnippets, values } =\n    filterBindingSegmentsAndRemoveQuotes(\n      originDynamicString,\n      originStringSnippets,\n      originValues,\n    )\n  let finalBinding = dynamicString\n  stringSnippets.forEach((b, i) => {\n    const value = values[i]\n    switch (getType(value)) {\n      case Types.NUMBER:\n      case Types.BOOLEAN:\n      case Types.NULL:\n      case Types.UNDEFINED:\n        finalBinding = finalBinding.replace(b, `${value}`)\n        break\n      case Types.STRING:\n        finalBinding = finalBinding.replace(b, value as string)\n        break\n      case Types.ARRAY:\n      case Types.OBJECT:\n        finalBinding = finalBinding.replace(b, JSON.stringify(value, null, 2))\n        break\n    }\n  })\n  return finalBinding\n}\n\nexport const substituteDynamicBindingWithValues = (\n  dynamicString: string,\n  stringSnippets: string[],\n  values: unknown[],\n): string => {\n  return templateSubstituteDynamicValues(dynamicString, stringSnippets, values)\n}\n\nconst ASYNC_SCRIPT_CODE_INPUT_START_MARKS = \"{{(async function (){\"\nconst SYNC_SCRIPT_CODE_INPUT_START_MARKS = \"{{(function (){\"\nconst SCRIPT_CODE_INPUT_END_MARKS = \"})()}}\"\n\nexport const realInputValueWithScript = (\n  attrValue: string | undefined,\n  needAsync: boolean = false,\n) => {\n  if (attrValue === \"\" || attrValue == undefined) return \"\"\n  const startMarks = needAsync\n    ? ASYNC_SCRIPT_CODE_INPUT_START_MARKS\n    : SYNC_SCRIPT_CODE_INPUT_START_MARKS\n  return attrValue.startsWith(startMarks)\n    ? attrValue.substring(\n        startMarks.length,\n        attrValue.length - SCRIPT_CODE_INPUT_END_MARKS.length,\n      )\n    : attrValue\n}\n\nexport const wrapperScriptCode = (\n  attrValue: string | undefined,\n  needAsync: boolean = false,\n) => {\n  const startMarks = needAsync\n    ? ASYNC_SCRIPT_CODE_INPUT_START_MARKS\n    : SYNC_SCRIPT_CODE_INPUT_START_MARKS\n\n  return `${startMarks}${attrValue}${SCRIPT_CODE_INPUT_END_MARKS}`\n}\n\nexport const isWrapperCode = (attrValue: string | undefined) => {\n  if (attrValue === \"\" || attrValue == undefined) return false\n  return (\n    (attrValue.startsWith(ASYNC_SCRIPT_CODE_INPUT_START_MARKS) ||\n      attrValue.startsWith(SYNC_SCRIPT_CODE_INPUT_START_MARKS)) &&\n    attrValue.endsWith(SCRIPT_CODE_INPUT_END_MARKS)\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/utils/eventHandlerHelper/index.ts",
    "content": "import { hasDynamicStringSnippet } from \"@illa-public/dynamic-string\"\nimport { get, isNumber } from \"lodash-es\"\nimport { createMessage } from \"@illa-design/react\"\nimport { getActionItemByDisplayName } from \"@/redux/currentApp/action/actionSelector\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport store from \"@/store\"\nimport { evaluateDynamicString } from \"@/utils/evaluateDynamicString\"\nimport { runOriginAction } from \"../action/runAction\"\nimport { wrapperScriptCode } from \"../evaluateDynamicString/valueConverter\"\nimport { clearLocalStorage, setValueLocalStorage } from \"./utils/localStorage\"\n\nexport enum EVENT_ACTION_TYPE {\n  OPEN_URL = \"openUrl\",\n  SHOW_NOTIFICATION = \"showNotification\",\n  SET_GLOBAL_STATE = \"setGlobalState\",\n  SET_LOCAL_STORAGE = \"setLocalStorage\",\n  COPY_TO_CLIPBOARD = \"copyToClipboard\",\n  SET_ROUTER = \"setRouter\",\n  DOWNLOAD_FILE = \"downloadFile\",\n  WIDGET = \"widget\",\n  DATA_SOURCE = \"datasource\",\n  SCRIPT = \"script\",\n  DOWNLOAD_FROM_ILLA_DRIVE = \"downloadFromILLADrive\",\n  SAVE_TO_ILLA_DRIVE = \"saveToILLADrive\",\n}\n\nconst message = createMessage()\n\nexport const transformEvents = (\n  event: any,\n  globalData: Record<string, any>,\n) => {\n  if (!event) return\n  const { actionType } = event\n  switch (actionType as EVENT_ACTION_TYPE) {\n    case EVENT_ACTION_TYPE.OPEN_URL: {\n      const { newTab, url, enabled } = event\n      const params = { url, newTab }\n      return {\n        script: () => {\n          globalData.utils.goToURL(params)\n        },\n        enabled,\n      }\n    }\n    case EVENT_ACTION_TYPE.SHOW_NOTIFICATION: {\n      const { title, description, notificationType, duration, enabled } = event\n      const params = {\n        type: notificationType,\n        title: title,\n        description: description,\n        duration: isNumber(duration) ? duration : undefined,\n      }\n      return {\n        script: () => {\n          globalData.utils.showNotification(params)\n        },\n        enabled,\n      }\n    }\n\n    case EVENT_ACTION_TYPE.COPY_TO_CLIPBOARD: {\n      const { copiedValue, enabled } = event\n      return {\n        script: () => {\n          globalData.utils.copyToClipboard(copiedValue)\n        },\n        enabled,\n      }\n    }\n    case EVENT_ACTION_TYPE.SET_GLOBAL_STATE: {\n      const {\n        stateDisplayName,\n        enabled,\n        globalStateMethod,\n        globalStateValue,\n        globalStateKeyPath,\n      } = event\n      switch (globalStateMethod) {\n        case \"setIn\": {\n          const params = {\n            key: stateDisplayName,\n            path: globalStateKeyPath,\n            value: globalStateValue,\n          }\n\n          return {\n            script: () => {\n              globalData.utils.setGlobalDataIn(params)\n            },\n            enabled,\n          }\n        }\n        case \"setValue\": {\n          const params = { key: stateDisplayName, value: globalStateValue }\n\n          return {\n            script: () => {\n              globalData.utils.setGlobalDataValue(params)\n            },\n            enabled,\n          }\n        }\n      }\n    }\n    case EVENT_ACTION_TYPE.SET_LOCAL_STORAGE: {\n      const { enabled, localStorageMethod } = event\n      switch (localStorageMethod) {\n        case \"clear\": {\n          return {\n            script: () => {\n              clearLocalStorage()\n            },\n            enabled,\n          }\n        }\n        case \"setValue\": {\n          const { localStorageKey, localStorageValue } = event\n          const params = { key: localStorageKey, value: localStorageValue }\n\n          return {\n            script: () => {\n              setValueLocalStorage(params)\n            },\n            enabled,\n          }\n        }\n      }\n      break\n    }\n\n    case EVENT_ACTION_TYPE.SET_ROUTER: {\n      const { pagePath, viewPath, enabled } = event\n\n      return {\n        script: () => {\n          globalData.utils.setRouter({\n            pagePath,\n            viewPath,\n          })\n        },\n        enabled,\n      }\n    }\n    case EVENT_ACTION_TYPE.DOWNLOAD_FILE: {\n      const { fileData, fileType, fileName } = event\n\n      return {\n        script: () => {\n          if ([undefined, null, \"\"].includes(fileData)) {\n            return\n          }\n          globalData.utils.downloadFile({\n            fileType,\n            fileName,\n            data: fileData,\n          })\n        },\n      }\n    }\n    case EVENT_ACTION_TYPE.WIDGET: {\n      const { widgetID, widgetMethod, enabled } = event\n      if (\n        [\n          \"setValue\",\n          \"setSelectedValue\",\n          \"setVolume\",\n          \"setVideoUrl\",\n          \"setAudioUrl\",\n          \"setImageUrl\",\n          \"setFileUrl\",\n          \"setStartValue\",\n          \"setPrimaryValue\",\n          \"setEndValue\",\n          \"setSpeed\",\n          \"seekTo\",\n          \"setStartOfRange\",\n          \"setEndOfRange\",\n          \"setMarkers\",\n          \"addEvent\",\n          \"deleteEvent\",\n          \"setStartTime\",\n          \"setEndTime\",\n          \"selectRow\",\n          \"setValueInArray\",\n          \"setSrc\",\n          \"setFilterModel\",\n          \"setColumnVisibilityModel\",\n          \"setPage\",\n          \"setPageSize\",\n          \"setRowSelection\",\n          \"renderEditor\",\n        ].includes(widgetMethod)\n      ) {\n        const { widgetTargetValue } = event\n        return {\n          script: () => {\n            const method = get(globalData, `${widgetID}.${widgetMethod}`, null)\n            if (method) {\n              method(widgetTargetValue)\n            }\n          },\n          enabled,\n        }\n      }\n      if (\n        [\"setDisabled\", \"setLoop\", \"showControls\", \"mute\"].includes(\n          widgetMethod,\n        )\n      ) {\n        const { widgetSwitchTargetValue } = event\n        return {\n          script: () => {\n            const method = get(globalData, `${widgetID}.${widgetMethod}`, null)\n            if (method) {\n              method(widgetSwitchTargetValue)\n            }\n          },\n          enabled,\n        }\n      }\n      if (\n        widgetMethod === \"play\" ||\n        widgetMethod === \"pause\" ||\n        widgetMethod === \"clearValue\" ||\n        widgetMethod === \"clearValidation\" ||\n        widgetMethod === \"clearSelection\" ||\n        widgetMethod === \"clearFilters\" ||\n        widgetMethod === \"toggle\" ||\n        widgetMethod === \"focus\" ||\n        widgetMethod === \"reset\" ||\n        widgetMethod === \"rowSelect\" ||\n        widgetMethod === \"resetPrimaryValue\" ||\n        widgetMethod === \"slickNext\" ||\n        widgetMethod === \"slickPrevious\" ||\n        widgetMethod === \"resetValue\" ||\n        widgetMethod === \"resetMarkers\" ||\n        widgetMethod === \"onFreeTimeDragOrClick\" ||\n        widgetMethod === \"openScanner\"\n      ) {\n        return {\n          script: `{{${widgetID}.${widgetMethod}()}}`,\n          enabled,\n        }\n      }\n      if (widgetMethod === \"setCurrentViewKey\") {\n        const { key } = event\n        return {\n          script: `{{${widgetID}.${widgetMethod}(\"${key}\")}}`,\n          enabled,\n        }\n      }\n      if (widgetMethod === \"setSort\") {\n        const { sortKey, sortOrder } = event\n        return {\n          script: () => {\n            const method = get(globalData, `${widgetID}.${widgetMethod}`, null)\n            if (method) {\n              method(sortKey, sortOrder)\n            }\n          },\n          enabled,\n        }\n      }\n      if (widgetMethod === \"setFilters\") {\n        const { filters, operator } = event\n        return {\n          script: () => {\n            const method = get(globalData, `${widgetID}.${widgetMethod}`, null)\n            if (method) {\n              method(filters, operator)\n            }\n          },\n          enabled,\n        }\n      }\n      if (widgetMethod === \"selectRow\") {\n        const { rowSelection } = event\n        return {\n          script: `{{${widgetID}.${widgetMethod}(${rowSelection})}}`,\n          enabled,\n        }\n      }\n      if (widgetMethod === \"selectPage\") {\n        const { pageIndex } = event\n        return {\n          script: `{{${widgetID}.${widgetMethod}(${pageIndex})}}`,\n          enabled,\n        }\n      }\n      if (widgetMethod === \"setCurrentViewIndex\") {\n        const { index } = event\n        return {\n          script: `{{${widgetID}.${widgetMethod}(\"${index}\")}}`,\n          enabled,\n        }\n      }\n      if (widgetMethod === \"showNextView\") {\n        const { showNextViewLoopBack } = event\n        return {\n          script: `{{${widgetID}.${widgetMethod}(${!!showNextViewLoopBack})}}`,\n          enabled,\n        }\n      }\n      if (widgetMethod === \"showPreviousView\") {\n        const { showPreviousViewLoopBack } = event\n        return {\n          script: `{{${widgetID}.${widgetMethod}(${!!showPreviousViewLoopBack})}}`,\n          enabled,\n        }\n      }\n\n      if (widgetMethod === \"showNextVisibleView\") {\n        const { showNextVisibleViewLoopBack } = event\n        return {\n          script: `{{${widgetID}.${widgetMethod}(${!!showNextVisibleViewLoopBack})}}`,\n          enabled,\n        }\n      }\n\n      if (widgetMethod === \"showPreviousVisibleView\") {\n        const { showPreviousVisibleViewLoopBack } = event\n        return {\n          script: `{{${widgetID}.${widgetMethod}(${!!showPreviousVisibleViewLoopBack})}}`,\n          enabled,\n        }\n      }\n      if (widgetMethod === \"submit\") {\n        return {\n          script: `{{${widgetID}.${widgetMethod}()}}`,\n          enabled,\n        }\n      }\n      if (widgetMethod === \"validate\") {\n        return {\n          script: `{{${widgetID}.${widgetMethod}()}}`,\n          enabled,\n        }\n      }\n\n      if (widgetMethod === \"openModal\" || widgetMethod === \"closeModal\") {\n        return {\n          script: () => {\n            store.dispatch(\n              executionActions.updateModalDisplayReducer({\n                display: widgetMethod === \"openModal\",\n                displayName: widgetID,\n              }),\n            )\n          },\n          enabled,\n        }\n      }\n      return {\n        script: `{{}}`,\n        enabled: \"{{false}}\",\n      }\n    }\n    case EVENT_ACTION_TYPE.DATA_SOURCE: {\n      const rootState = store.getState()\n      const { queryID, enabled } = event\n      const actionItem = getActionItemByDisplayName(rootState, queryID)\n      if (!actionItem)\n        return {\n          script: `{{}}`,\n          enabled,\n        }\n      return {\n        script: () => {\n          runOriginAction(actionItem)\n        },\n        enabled,\n      }\n    }\n    case EVENT_ACTION_TYPE.DOWNLOAD_FROM_ILLA_DRIVE: {\n      const { downloadInfo, asZip, enabled } = event\n      return {\n        script: () => {\n          globalData.utils.downloadFromILLADrive({\n            downloadInfo,\n            asZip,\n          })\n        },\n        enabled,\n      }\n    }\n\n    case EVENT_ACTION_TYPE.SAVE_TO_ILLA_DRIVE: {\n      const {\n        fileName,\n        fileData,\n        fileType,\n        allowAnonymous,\n        replace,\n        folder,\n        enabled,\n      } = event\n\n      return {\n        script: () => {\n          globalData.utils.saveToILLADrive({\n            fileData,\n            fileName,\n            fileType,\n            allowAnonymous,\n            replace,\n            folder,\n          })\n        },\n        enabled,\n      }\n    }\n    case EVENT_ACTION_TYPE.SCRIPT: {\n      const { script, enabled } = event\n      return {\n        script: wrapperScriptCode(script, true),\n        enabled,\n      }\n    }\n    default: {\n      return {\n        script: `{{}}`,\n        enabled: \"{{false}}\",\n      }\n    }\n  }\n  return {\n    script: `{{}}`,\n    enabled: \"{{false}}\",\n  }\n}\n\nexport const runEventHandler = (\n  scriptObj: any,\n  globalData: Record<string, any>,\n) => {\n  const eventObj = transformEvents(scriptObj, globalData)\n  if (!eventObj) return\n  const { script, enabled } = eventObj\n\n  if (\n    (typeof enabled === \"boolean\" && enabled) ||\n    scriptObj.originEnable == undefined ||\n    scriptObj.originEnable === \"\"\n  ) {\n    if (typeof script === \"string\" && hasDynamicStringSnippet(script)) {\n      try {\n        evaluateDynamicString(\"events\", script, globalData)\n      } catch (e) {\n        message.error({\n          content: \"eventHandler run error\",\n        })\n      }\n      return\n    }\n    if (typeof script === \"function\") {\n      script()\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/eventHandlerHelper/utils/commonUtils.ts",
    "content": "import { SectionViewShape } from \"@illa-public/public-types\"\nimport copy from \"copy-to-clipboard\"\nimport download from \"downloadjs\"\nimport {\n  NotificationType,\n  createMessage,\n  createNotification,\n  isArray,\n} from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport {\n  getComponentMap,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { getRootNodeExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { UpdateExecutionByDisplayNamePayload } from \"@/redux/currentApp/executionTree/executionState\"\nimport { ILLARoute } from \"@/router\"\nimport store from \"@/store\"\nimport { LIMIT_MEMORY, estimateMemoryUsage } from \"@/utils/calculateMemoryUsage\"\nimport {\n  convertToCSV,\n  convertToTSV,\n  downloadExcelFile,\n  downloadFileFromURL,\n  getContentTypeByFileExtension,\n  getFileName,\n} from \"@/utils/file\"\nimport { isBlobURLOrUrl, isObject, isValidUrlScheme } from \"@/utils/typeHelper\"\nimport { isBase64 } from \"@/utils/url/base64\"\n\nconst message = createMessage()\n\nexport const goToURL = (params: { url: string; newTab?: boolean }) => {\n  const { url = \"\", newTab = false } = params\n  if (typeof url !== \"string\" || typeof newTab !== \"boolean\") return\n  let finalURL = url\n  if (!finalURL) return\n  if (!isValidUrlScheme(finalURL)) {\n    finalURL = `https://${finalURL}`\n  }\n  if (newTab) {\n    window.open(finalURL, \"_blank\")\n  } else {\n    window.location.assign(finalURL)\n  }\n}\n\nexport const showNotification = (params: {\n  type: NotificationType\n  title?: string\n  description?: string\n  duration?: number\n}) => {\n  const {\n    type = \"info\",\n    title = \"\",\n    description = \"\",\n    duration = 4500,\n  } = params\n  if (typeof type !== \"string\" || typeof duration !== \"number\") return\n  const notification = createNotification()\n  notification.show({\n    title: `${title}`,\n    content: `${description}`,\n    duration,\n    type,\n  })\n}\n\nexport const copyToClipboard = (copiedValue: unknown) => {\n  if (copiedValue === undefined || copiedValue === null || copiedValue === \"\") {\n    message.info({\n      content: i18n.t(\"empty_copied_tips\"),\n    })\n    return\n  }\n  const memorySize = estimateMemoryUsage(copiedValue)\n  if (LIMIT_MEMORY < memorySize) {\n    message.info({\n      content: i18n.t(\"editor.global.size_exceed\", {\n        current_size: memorySize,\n        limit_size: LIMIT_MEMORY,\n      }),\n    })\n    return\n  }\n  message.success({\n    content: i18n.t(\"copied\"),\n  })\n  if (typeof copiedValue === \"string\" || typeof copiedValue === \"number\") {\n    copy(String(copiedValue))\n    return\n  }\n  copy(JSON.stringify(copiedValue))\n}\n\nexport const setRouter = (params: { pagePath: string; viewPath?: string }) => {\n  const { pagePath, viewPath = \"\" } = params\n  if (typeof pagePath !== \"string\" || typeof viewPath !== \"string\") return\n\n  const isProductionMode = getIsILLAProductMode(store.getState())\n  const rootNodeProps = getRootNodeExecutionResult(store.getState())\n  const { pageSortedKey } = rootNodeProps\n  const index = pageSortedKey.findIndex((path: string) => path === pagePath)\n  if (index === -1) return\n  const routerMatch = ILLARoute.state.matches[0]\n  if (!routerMatch) return\n  const { appId, teamIdentifier } = routerMatch.params\n  if (isProductionMode) {\n    let finalPath = `/${pagePath}`\n    finalPath = viewPath ? finalPath + `/${viewPath}` : finalPath\n    ILLARoute.navigate(`/${teamIdentifier}/deploy/app/${appId}${finalPath}`, {\n      replace: true,\n    })\n  }\n  const updateSlice: UpdateExecutionByDisplayNamePayload[] = [\n    {\n      displayName: \"root\",\n      value: {\n        currentPageIndex: index,\n      },\n    },\n  ]\n  if (viewPath) {\n    const components = getComponentMap(store.getState())\n    if (!components) return\n    const pageNode = searchComponentFromMap(components, pagePath)\n    if (!pageNode) return\n    pageNode.childrenNode.forEach((sectionDisplayName) => {\n      const sectionNode = components[sectionDisplayName]\n      const sectionViewConfigs = sectionNode.props?.sectionViewConfigs || []\n      const viewSortedKey = sectionNode.props?.viewSortedKey || []\n      const findConfig = sectionViewConfigs.find((config: SectionViewShape) => {\n        return config.path === viewPath\n      })\n      if (findConfig) {\n        const viewDisplayName = findConfig.viewDisplayName\n        const indexOfViewKey = viewSortedKey.findIndex(\n          (key: string) => key === viewDisplayName,\n        )\n        if (indexOfViewKey !== -1) {\n          updateSlice.push({\n            displayName: sectionDisplayName,\n            value: {\n              currentViewIndex: indexOfViewKey,\n            },\n          })\n        }\n      }\n    })\n  }\n\n  store.dispatch(\n    executionActions.updateExecutionByMultiDisplayNameReducer(updateSlice),\n  )\n  if (!viewPath) {\n    store.dispatch(\n      executionActions.updateCurrentPagePathReducer({\n        pageDisplayName: pagePath,\n      }),\n    )\n  } else {\n    store.dispatch(\n      executionActions.updateCurrentPagePathReducer({\n        pageDisplayName: pagePath,\n        subPagePath: viewPath,\n      }),\n    )\n  }\n}\n\nexport const downloadFile = (params: {\n  fileType: string\n  fileName: string\n  data: unknown\n}) => {\n  const { fileType = \"auto\", fileName = \"Untitled File\", data } = params\n  if (\n    typeof fileName !== \"string\" ||\n    typeof fileType !== \"string\" ||\n    data == undefined\n  )\n    return\n  const message = createMessage()\n  try {\n    const fileDownloadName = getFileName((fileName ?? \"\").trim(), fileType)\n    const contentType = getContentTypeByFileExtension(\n      fileDownloadName.split(\".\")[1],\n    )\n    const isBase64Suffix = typeof data === \"string\" && isBase64(data)\n    const isValidBase64 = typeof data === \"string\" && isBase64(data, true)\n    const formatData = isArray(data) ? data : isObject(data) ? [data] : data\n    const isValidUrl = typeof data === \"string\" && isBlobURLOrUrl(data)\n\n    let formattedDownloadData: string | Blob | File | Uint8Array\n\n    if (isValidBase64 || data instanceof Blob) {\n      formattedDownloadData = data\n    } else if (isBase64Suffix) {\n      formattedDownloadData = `data:${contentType};base64,${data}`\n    } else if (isValidUrl) {\n      downloadFileFromURL(data, fileDownloadName, contentType)\n      return\n    } else {\n      switch (contentType) {\n        case \"text/csv\":\n          {\n            formattedDownloadData = new Blob(\n              [\"\\ufeff\", convertToCSV(formatData)],\n              {\n                type: \"text/csv;charset=utf-8\",\n              },\n            )\n          }\n          break\n        case \"application/vnd.ms-excel\":\n        case \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\":\n          {\n            formattedDownloadData = new Blob(\n              [downloadExcelFile(data, contentType)],\n              {\n                type: \"application/octet-stream\",\n              },\n            )\n          }\n          break\n        case \"text/tab-separated-values\":\n          {\n            formattedDownloadData = convertToTSV(formatData)\n          }\n          break\n        default:\n          {\n            if (typeof data === \"object\") {\n              formattedDownloadData = JSON.stringify(data, undefined, 2)\n            } else {\n              formattedDownloadData = \"\"\n            }\n          }\n          break\n      }\n    }\n    download(formattedDownloadData, fileDownloadName, contentType)\n  } catch (e) {\n    message.error({\n      content: i18n.t(\"editor.method.file_download.message.download_failed\"),\n    })\n    console.error(e)\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/eventHandlerHelper/utils/driveUtils.ts",
    "content": "import { isILLAAPiError } from \"@illa-public/illa-net\"\nimport { ERROR_FLAG } from \"@illa-public/illa-net/errorFlag\"\nimport {\n  CollarModalType,\n  handleCollaPurchaseError,\n} from \"@illa-public/upgrade-modal\"\nimport { Zip, ZipPassThrough } from \"fflate\"\nimport { createWriteStream } from \"streamsaver\"\nimport { createMessage } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { FILE_ITEM_DETAIL_STATUS_IN_UI } from \"@/page/App/Module/UploadDetail/components/DetailList/interface\"\nimport { updateFileDetailStore } from \"@/page/App/Module/UploadDetail/store\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport { fetchDownloadURLByTinyURL } from \"@/services/drive\"\nimport store from \"@/store\"\nimport { uploadFileToDrive } from \"@/utils/drive/upload/getSingedURL\"\nimport { getContentTypeByFileExtension, getFileName } from \"@/utils/file\"\nimport { isBase64Simple } from \"@/utils/url/base64\"\nimport { dataURLtoFile } from \"@/widgetLibrary/UploadWidget/util\"\nimport { isNeedPreventForPremium } from \"./premiumEventUtils\"\n\nconst message = createMessage()\n\ninterface IDriveDownloadInfo {\n  tinyURL: string\n  fileID: string\n}\n\ninterface IDownloadFromILLADriveParams {\n  downloadInfo: IDriveDownloadInfo[]\n  asZip?: boolean\n}\n\nexport const downloadFromILLADrive = async (\n  params: IDownloadFromILLADriveParams,\n) => {\n  const { downloadInfo, asZip = false } = params\n  if (isNeedPreventForPremium() || !Array.isArray(downloadInfo)) {\n    return\n  }\n  let promise = Promise.resolve()\n  const zip = new Zip()\n\n  const zipName = `illa_drive_download_${new Date().getTime()}.zip`\n  const zipReadableStream = new ReadableStream({\n    start(controller) {\n      zip.ondata = (error, data, final) => {\n        if (error) {\n          controller.error(error)\n        } else {\n          controller.enqueue(data)\n          if (final) {\n            controller.close()\n          }\n        }\n      }\n    },\n  })\n  if (asZip) {\n    const streamsaver = createWriteStream(zipName)\n    zipReadableStream.pipeTo(streamsaver)\n  }\n\n  for (let i = 0; i < downloadInfo.length; i++) {\n    const { tinyURL, fileID } = downloadInfo[i]\n    promise = promise.then(async () => {\n      try {\n        const response = await fetchDownloadURLByTinyURL(tinyURL, fileID)\n        const fileInfo = response.data\n        const { name, downloadURL } = fileInfo\n        const fileResponse = await fetch(downloadURL)\n\n        if (!asZip && window.WritableStream && fileResponse.body?.pipeTo) {\n          const fileStream = createWriteStream(name)\n          return fileResponse.body.pipeTo(fileStream)\n        }\n\n        if (asZip) {\n          const zipStream = new ZipPassThrough(name)\n          zip.add(zipStream)\n          const fileReader = fileResponse.body?.getReader()\n\n          while (fileReader) {\n            const { value, done } = await fileReader.read()\n            if (done) {\n              zipStream.push(new Uint8Array(0), true)\n              return Promise.resolve()\n            }\n            zipStream.push(value)\n          }\n        }\n      } catch (e) {\n        const rootState = store.getState()\n        const isProductionMode = getIsILLAProductMode(rootState)\n        const res = handleCollaPurchaseError(\n          e,\n          CollarModalType.STORAGE,\n          isProductionMode\n            ? \"deploy_traffic_not_enough_event_handler\"\n            : \"builder_editor_traffic_not_enough_event_handler\",\n        )\n        if (res) return\n        if (isILLAAPiError(e)) {\n          if (\n            e.data.errorMessage === ERROR_FLAG.ERROR_FLAG_OUT_OF_USAGE_TRAFFIC\n          ) {\n            message.error({\n              content: i18n.t(\"editor.inspect.setter_message.noTraffic\"),\n            })\n            return Promise.reject(e)\n          }\n        }\n        return Promise.resolve()\n      }\n    })\n  }\n\n  if (asZip) {\n    promise.then(() => {\n      zip.end()\n    })\n  }\n}\n\nexport enum FILE_TYPE {\n  AUTO = \"auto\",\n  TEXT = \"text\",\n  JPEG = \"jpeg\",\n  PNG = \"png\",\n  SVG = \"svg\",\n  JSON = \"json\",\n  CSV = \"csv\",\n  TSV = \"tsv\",\n  XLSX = \"xlsx\",\n}\n\nexport interface ISaveToILLADriveParams {\n  fileName: string\n  fileData: string\n  fileType: FILE_TYPE\n  folder?: string\n  allowAnonymous?: boolean\n  replace?: boolean\n  queryID?: string\n}\n\nexport const saveToILLADrive = async (params: ISaveToILLADriveParams) => {\n  const {\n    fileName,\n    fileData,\n    fileType = FILE_TYPE.AUTO,\n    folder = \"\",\n    allowAnonymous = false,\n    replace = false,\n  } = params\n  if (\n    isNeedPreventForPremium() ||\n    typeof fileName !== \"string\" ||\n    fileData == undefined ||\n    typeof fileData !== \"string\"\n  )\n    return\n\n  message.info({\n    content: i18n.t(\"drive.message.start_upload\"),\n  })\n  const isBase64 = isBase64Simple(fileData)\n\n  const fileDownloadName = getFileName((fileName ?? \"\").trim(), fileType)\n  const contentType = getContentTypeByFileExtension(\n    fileDownloadName.split(\".\")[1],\n  )\n\n  let tmpData = fileData\n  if (!isBase64) {\n    tmpData = `data:${contentType};base64,${fileData}`\n  }\n  const queryID = `${fileDownloadName}_${new Date().getTime()}`\n\n  const abortController = new AbortController()\n\n  updateFileDetailStore.addFileDetailInfo({\n    loaded: 0,\n    total: 0,\n    status: FILE_ITEM_DETAIL_STATUS_IN_UI.WAITING,\n    fileName: fileDownloadName,\n    contentType,\n    queryID: queryID,\n    abortController,\n  })\n  let needUploadFile: File | undefined\n  try {\n    needUploadFile = dataURLtoFile(tmpData, fileDownloadName)\n    updateFileDetailStore.updateFileDetailInfo(queryID, {\n      saveToILLADriveParams: {\n        fileData: needUploadFile,\n        allowAnonymous,\n        folder,\n        replace,\n      },\n    })\n  } catch (e) {\n    updateFileDetailStore.updateFileDetailInfo(queryID, {\n      status: FILE_ITEM_DETAIL_STATUS_IN_UI.ERROR,\n    })\n    message.error({\n      content: i18n.t(\"editor.inspect.setter_message.uploadfail\"),\n    })\n    return\n  }\n\n  try {\n    await uploadFileToDrive(\n      queryID,\n      needUploadFile,\n      {\n        allowAnonymous,\n        folder,\n        replace,\n      },\n      abortController.signal,\n    )\n  } catch (e) {\n    const rootState = store.getState()\n    const isProductionMode = getIsILLAProductMode(rootState)\n    handleCollaPurchaseError(\n      e,\n      CollarModalType.STORAGE,\n      isProductionMode\n        ? \"deploy_storage_not_enough_event_handler\"\n        : \"builder_editor_storage_not_enough_event_handler\",\n    )\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/eventHandlerHelper/utils/globalDataUtils.ts",
    "content": "import { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport store from \"@/store\"\n\nexport const setGlobalDataIn = (params: {\n  key: string\n  path: string\n  value: unknown\n}) => {\n  const { key, path } = params\n  if (typeof key !== \"string\" || typeof path !== \"string\") return\n  store.dispatch(executionActions.setInGlobalStateInExecutionReducer(params))\n}\n\nexport const setGlobalDataValue = (params: { key: string; value: unknown }) => {\n  const { key } = params\n  if (typeof key !== \"string\") return\n  store.dispatch(executionActions.setGlobalStateInExecutionReducer(params))\n}\n"
  },
  {
    "path": "apps/builder/src/utils/eventHandlerHelper/utils/localStorage.ts",
    "content": "import { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport store from \"@/store\"\n\nexport const clearLocalStorage = () => {\n  store.dispatch(executionActions.clearLocalStorageInExecutionReducer())\n}\n\nexport const setValueLocalStorage = (params: {\n  key: string\n  value: unknown\n}) => {\n  const { key } = params\n  if (typeof key !== \"string\") return\n\n  store.dispatch(executionActions.setLocalStorageInExecutionReducer(params))\n}\n"
  },
  {
    "path": "apps/builder/src/utils/eventHandlerHelper/utils/premiumEventUtils.ts",
    "content": "import { createUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { isSubscribeForUseDrive } from \"@illa-public/upgrade-modal/utils\"\nimport { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport store from \"@/store\"\n\nexport const isNeedPreventForPremium = (): boolean => {\n  const isProductionMode = getIsILLAProductMode(store.getState())\n  if (isProductionMode) {\n    return false\n  }\n  if (isCloudVersion) {\n    const teamInfo = getCurrentTeamInfo(store.getState())!\n    const upgradeModal = createUpgradeModal()\n    if (!isSubscribeForUseDrive(teamInfo)) {\n      upgradeModal({\n        modalType: \"upgrade\",\n        from: \"drive_run_event_handler\",\n      })\n      return true\n    }\n  }\n  return false\n}\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/executionTreeFactory.ts",
    "content": "import {\n  convertPathToString,\n  hasDynamicStringSnippet,\n} from \"@illa-public/dynamic-string\"\nimport { Diff, diff } from \"deep-diff\"\nimport { klona } from \"klona\"\nimport { flatten, get, merge, set, toPath, unset } from \"lodash-es\"\nimport toposort from \"toposort\"\nimport { createMessage } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { getContainerListDisplayNameMappedChildrenNodeDisplayName } from \"@/redux/currentApp/components/componentsSelector\"\nimport {\n  DependenciesState,\n  ExecutionErrorType,\n  ExecutionState,\n} from \"@/redux/currentApp/executionTree/executionState\"\nimport store from \"@/store\"\nimport { evaluateDynamicStringAndGetCalcContext } from \"@/utils/evaluateDynamicString\"\nimport { getSnippets } from \"@/utils/evaluateDynamicString/dynamicConverter\"\nimport {\n  getDisplayNameAndAttrPath,\n  getWidgetOrActionDynamicAttrPaths,\n} from \"@/utils/evaluateDynamicString/utils\"\nimport { RawTreeShape } from \"@/utils/executionTreeHelper/interface\"\nimport {\n  extractReferencesFromScript,\n  getImmediateParentsOfPropertyPaths,\n  getObjectPaths,\n  isAction,\n  isWidget,\n} from \"@/utils/executionTreeHelper/utils\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport { VALIDATION_TYPES, validationFactory } from \"@/utils/validationFactory\"\nimport {\n  IExecutionActions,\n  runActionWithExecutionResult,\n} from \"../action/runAction\"\nimport { isWidgetInGridListOrList } from \"../componentNode/search\"\n\nconst message = createMessage()\n\nexport const IGNORE_ACTION_RUN_ATTR_NAME = [\n  \"isRunning\",\n  \"startTime\",\n  \"endTime\",\n  \"data\",\n  \"runResult\",\n  \"responseHeaders\",\n]\n\nexport const IGNORE_AUTO_RUN_WITH_RUN_SCRIPT_ATTR_RULES = [\n  /events\\[\\d+\\]\\.script/,\n  /content\\.successEvent\\[\\d+\\]\\.script/,\n  /content\\.failedEvent\\[\\d+\\]\\.script/,\n]\n\nexport const isRunScriptAttr = (attrPath: string) => {\n  return IGNORE_AUTO_RUN_WITH_RUN_SCRIPT_ATTR_RULES.some((rule) => {\n    return rule.test(attrPath)\n  })\n}\n\nexport class ExecutionTreeFactory {\n  dependenciesState: DependenciesState = {}\n  inDependencyTree: DependenciesState = {}\n  evalOrder: string[] = []\n  oldRawTree: RawTreeShape = {} as RawTreeShape\n  hasCyclical: boolean = false\n  executedTree: RawTreeShape = {} as RawTreeShape\n  errorTree: Record<string, any> = {}\n  allKeys: Record<string, true> = {}\n  runningActionsMap: Map<string, number> = new Map()\n\n  constructor() {}\n\n  destroyTree() {\n    this.dependenciesState = {}\n    this.inDependencyTree = {}\n    this.evalOrder = []\n    this.oldRawTree = {} as RawTreeShape\n    this.hasCyclical = false\n    this.executedTree = {} as RawTreeShape\n    this.errorTree = {}\n    this.allKeys = {}\n    this.runningActionsMap = new Map()\n\n    return undefined\n  }\n\n  initTree(rawTree: RawTreeShape) {\n    const currentRawTree = klona(rawTree)\n    this.oldRawTree = klona(currentRawTree)\n    try {\n      this.dependenciesState = this.generateDependenciesMap(currentRawTree)\n      this.evalOrder = this.sortEvalOrder(this.dependenciesState)\n      this.inDependencyTree = this.generateInDependenciesMap()\n      const { evaluatedTree, errorTree } = this.executeTree(\n        currentRawTree,\n        this.evalOrder,\n      )\n\n      const { validateErrors, validateResultTree } =\n        this.validateTree(evaluatedTree)\n\n      const mergedError = merge(errorTree, validateErrors)\n      this.errorTree = mergedError\n\n      this.executedTree = validateResultTree\n    } catch (e) {\n      return {\n        dependencyTree: this.dependenciesState,\n        evaluatedTree: currentRawTree,\n        errorTree: this.errorTree,\n        independencyTree: this.inDependencyTree,\n      }\n    }\n\n    return {\n      dependencyTree: this.dependenciesState,\n      evaluatedTree: this.executedTree,\n      errorTree: this.errorTree,\n      independencyTree: this.inDependencyTree,\n    }\n  }\n\n  validateTree(tree: RawTreeShape) {\n    const validateErrors: Record<string, any> = {}\n    const validateResultTree = Object.keys(tree).reduce(\n      (current: RawTreeShape, displayName) => {\n        const widgetOrAction = current[displayName]\n        if (!isWidget(widgetOrAction) && !isAction(widgetOrAction)) {\n          return current\n        }\n        let isWidgetInLikeList = false\n        if (widgetOrAction && isWidget(widgetOrAction)) {\n          isWidgetInLikeList = isWidgetInGridListOrList(current, displayName)\n        }\n\n        const validationPaths = widgetOrAction.$validationPaths\n        const listWidgets =\n          getContainerListDisplayNameMappedChildrenNodeDisplayName(\n            store.getState(),\n          )\n\n        const listWidgetDisplayNames = Object.keys(listWidgets)\n        let currentListDisplayName = \"\"\n        for (let i = 0; i < listWidgetDisplayNames.length; i++) {\n          if (listWidgets[listWidgetDisplayNames[i]].includes(displayName)) {\n            currentListDisplayName = listWidgetDisplayNames[i]\n            break\n          }\n        }\n\n        if (isObject(validationPaths)) {\n          getObjectPaths(validationPaths).forEach((validationPath) => {\n            const validationType = get(\n              validationPaths,\n              validationPath,\n            ) as VALIDATION_TYPES\n            const fullPath = `${displayName}.${validationPath}`\n            const validationFunc = validationFactory[validationType]\n            const value = get(widgetOrAction, validationPath)\n\n            const { isValid, safeValue, errorMessage } = validationFunc(\n              value,\n              currentListDisplayName,\n            )\n\n            if (\n              isWidgetInLikeList &&\n              Array.isArray(safeValue) &&\n              validationType === VALIDATION_TYPES.ARRAY\n            ) {\n              if (Array.isArray(safeValue[0])) {\n                set(current, fullPath, safeValue[0])\n              } else {\n                set(current, fullPath, safeValue)\n              }\n            } else {\n              set(current, fullPath, safeValue)\n            }\n            let error = validateErrors[fullPath]\n            if (!isValid) {\n              if (!Array.isArray(error)) {\n                error = []\n              }\n              const hasValidateError = error.some(\n                (v: any) => v.errorType === ExecutionErrorType.VALIDATION,\n              )\n              if (!hasValidateError) {\n                error.push({\n                  errorType: ExecutionErrorType.VALIDATION,\n                  errorMessage: errorMessage as string,\n                  errorName: \"Validation\",\n                })\n              }\n\n              validateErrors[fullPath] = error\n            } else {\n              if (Array.isArray(error)) {\n                const validationIndex = error.findIndex((v) => {\n                  return v.errorType === ExecutionErrorType.VALIDATION\n                })\n                if (validationIndex !== -1) {\n                  error.splice(validationIndex, 1)\n                  if (error.length === 0) {\n                    delete validateErrors[fullPath]\n                  }\n                }\n              }\n            }\n          })\n        }\n\n        return current\n      },\n      tree,\n    )\n    return {\n      validateResultTree,\n      validateErrors,\n    }\n  }\n\n  calcSubTreeSortOrder(\n    differences: Diff<any, any>[],\n    rawTree: RawTreeShape,\n    isIgnoreDynamicPaths: boolean = false,\n  ) {\n    const changePaths: Set<string> = new Set()\n    for (const diff of differences) {\n      if (!Array.isArray(diff.path) || diff.path.length === 0) continue\n      changePaths.add(convertPathToString(diff.path))\n      const entityName = diff.path[0]\n      const entity = rawTree[entityName]\n      if (!entity) {\n        continue\n      }\n      if (isIgnoreDynamicPaths) {\n        continue\n      }\n      const dynamic: string[] = entity.$dynamicAttrPaths\n      dynamic?.forEach((attr) => {\n        changePaths.add(`${entityName}.${attr}`)\n      })\n    }\n    return this.getCompleteSortOrder(\n      Array.from(changePaths),\n      this.inDependencyTree,\n    )\n  }\n\n  getEvaluationSortOrder(\n    changes: Array<string>,\n    inverseMap: DependenciesState,\n  ): Array<string> {\n    const sortOrder: Array<string> = [...changes]\n    let iterator = 0\n    while (iterator < sortOrder.length) {\n      const newNodes = inverseMap[sortOrder[iterator]]\n      if (newNodes) {\n        newNodes.forEach((toBeEvaluatedNode) => {\n          if (!sortOrder.includes(toBeEvaluatedNode)) {\n            sortOrder.push(toBeEvaluatedNode)\n          }\n        })\n      }\n      iterator++\n    }\n    return sortOrder\n  }\n\n  getCompleteSortOrder(changes: string[], inDependencyTree: DependenciesState) {\n    let sortOrders: string[] = []\n    let parents = klona(changes)\n    let subSortOrderArray: string[]\n    const modifyDependencyTree = klona(inDependencyTree)\n    Object.keys(modifyDependencyTree).forEach((key) => {\n      modifyDependencyTree[key] = modifyDependencyTree[key].filter((value) => {\n        return !changes.includes(value)\n      })\n    })\n\n    while (true) {\n      subSortOrderArray = this.getEvaluationSortOrder(\n        parents,\n        modifyDependencyTree,\n      )\n      sortOrders = [...sortOrders, ...subSortOrderArray]\n      parents = getImmediateParentsOfPropertyPaths(subSortOrderArray)\n      if (parents.length <= 0) {\n        break\n      }\n    }\n    const sortOrderSet = new Set(sortOrders)\n    const sortOrderPropertyPaths: string[] = []\n    this.evalOrder.forEach((path) => {\n      if (sortOrderSet.has(path)) {\n        sortOrderPropertyPaths.push(path)\n        sortOrderSet.delete(path)\n      }\n    })\n\n    const completeSortOrder = [\n      ...Array.from(sortOrderSet),\n      ...sortOrderPropertyPaths,\n    ]\n\n    const finalSortOrderArray: Array<string> = []\n    completeSortOrder.forEach((propertyPath) => {\n      const lastIndexOfDot = propertyPath.lastIndexOf(\".\")\n      if (lastIndexOfDot !== -1) {\n        finalSortOrderArray.push(propertyPath)\n      }\n    })\n    return finalSortOrderArray\n  }\n\n  mergeErrorTree(\n    newPartErrorTree: Record<string, any>,\n    updatePathMapAction: Record<string, \"NEW\" | \"DELETE\" | \"UPDATE\">,\n  ) {\n    const newErrorTree = klona(this.errorTree)\n    Object.entries(updatePathMapAction).forEach(([path, action]) => {\n      if (action === \"DELETE\") {\n        Object.keys(newErrorTree).forEach((key) => {\n          key.startsWith(path) && delete newErrorTree[key]\n        })\n      } else {\n        const newErrorTreeValue = get(newPartErrorTree, path)\n        if (newErrorTreeValue) {\n          newErrorTree[path] = newErrorTreeValue\n        } else {\n          delete newErrorTree[path]\n        }\n      }\n    })\n    return newErrorTree\n  }\n\n  updateExecutionTreeByUpdatePaths(\n    updatePathMapAction: Record<string, \"NEW\" | \"DELETE\" | \"UPDATE\">,\n    executionTree: RawTreeShape,\n    rawTree: RawTreeShape,\n    walkedPath: Set<string>,\n  ) {\n    const currentExecutionTree = klona(executionTree)\n    Object.entries(updatePathMapAction).forEach(([path, action]) => {\n      if (!walkedPath.has(path)) {\n        walkedPath.add(path)\n        if (action === \"DELETE\") {\n          const pathArray = toPath(path)\n          const parentPath = pathArray.slice(0, pathArray.length - 1)\n          const parentValue = get(currentExecutionTree, parentPath, undefined)\n          if (Array.isArray(parentValue)) {\n            const index = Number(pathArray[pathArray.length - 1])\n            parentValue.splice(index, 1)\n            set(currentExecutionTree, parentPath, parentValue)\n          } else {\n            unset(currentExecutionTree, path)\n          }\n        } else {\n          const value = get(rawTree, path, undefined)\n          set(currentExecutionTree, path, value)\n        }\n      }\n    })\n\n    return currentExecutionTree\n  }\n\n  mergeOrderPathAndUpdateMapActions(\n    orderPaths: string[],\n    updateMapActions: Record<string, \"NEW\" | \"DELETE\" | \"UPDATE\">,\n  ) {\n    const newUpdateMapActions = klona(updateMapActions)\n    orderPaths.forEach((path) => {\n      if (!newUpdateMapActions[path]) {\n        newUpdateMapActions[path] = \"UPDATE\"\n      }\n    })\n    return newUpdateMapActions\n  }\n\n  updateTree(rawTree: RawTreeShape, isAddAction?: boolean) {\n    const currentRawTree = klona(rawTree)\n    try {\n      this.dependenciesState = this.generateDependenciesMap(currentRawTree)\n      this.evalOrder = this.sortEvalOrder(this.dependenciesState)\n      this.inDependencyTree = this.generateInDependenciesMap()\n    } catch (e) {\n      return {\n        dependencyTree: this.dependenciesState,\n        evaluatedTree: currentRawTree,\n        errorTree: this.errorTree,\n        independencyTree: this.inDependencyTree,\n      }\n    }\n\n    const differences: Diff<RawTreeShape, RawTreeShape>[] =\n      diff(this.oldRawTree, currentRawTree) || []\n    if (differences.length === 0) {\n      return {\n        dependencyTree: this.dependenciesState,\n        evaluatedTree: this.executedTree,\n        errorTree: this.errorTree,\n        independencyTree: this.inDependencyTree,\n      }\n    }\n\n    this.oldRawTree = klona(currentRawTree)\n    const updatePathMapAction = this.getUpdatePathFromDifferences(differences)\n    const walkedPath = new Set<string>()\n\n    let currentExecution = this.updateExecutionTreeByUpdatePaths(\n      updatePathMapAction,\n      this.executedTree,\n      currentRawTree,\n      walkedPath,\n    )\n\n    const path = this.calcSubTreeSortOrder(\n      differences,\n      currentExecution,\n      !isAddAction,\n    )\n\n    const mergedUpdatePathMapAction = this.mergeOrderPathAndUpdateMapActions(\n      path,\n      updatePathMapAction,\n    )\n\n    const originUpdateKeys = Object.keys(updatePathMapAction)\n    Object.keys(mergedUpdatePathMapAction).forEach((key) => {\n      if (originUpdateKeys.includes(key)) {\n        return\n      }\n      const originValue = get(this.oldRawTree, key)\n      if (hasDynamicStringSnippet(originValue)) {\n        set(currentExecution, key, originValue)\n      }\n    }, [])\n\n    const { evaluatedTree, errorTree } = this.executeTree(\n      currentExecution,\n      path,\n      -1,\n    )\n\n    const { validateErrors, validateResultTree } =\n      this.validateTree(evaluatedTree)\n\n    const mergedError = merge({}, validateErrors, errorTree)\n    const errorTreeResult = this.mergeErrorTree(\n      mergedError,\n      mergedUpdatePathMapAction,\n    )\n    this.errorTree = errorTreeResult\n\n    this.executedTree = validateResultTree\n    this.executedTree.globalData = evaluatedTree.root.globalData\n    return {\n      dependencyTree: this.dependenciesState,\n      evaluatedTree: this.executedTree,\n      errorTree: this.errorTree,\n      independencyTree: this.inDependencyTree,\n    }\n  }\n\n  setEvaluatedTree(executedTree: Record<string, any>) {\n    this.executedTree = executedTree as RawTreeShape\n  }\n\n  getUpdatePathFromDifferences(\n    differences: Diff<Record<string, any>, Record<string, any>>[],\n  ) {\n    const updatePathMapAction: Record<string, \"NEW\" | \"DELETE\" | \"UPDATE\"> = {}\n    for (const d of differences) {\n      if (!Array.isArray(d.path) || d.path.length === 0) continue\n      const { path } = d\n      const stringPath = convertPathToString(path)\n      switch (d.kind) {\n        case \"N\": {\n          const rhs = d.rhs\n          if (typeof rhs === \"object\" && rhs !== null) {\n            const keys = Object.keys(rhs)\n            keys.forEach((key) => {\n              updatePathMapAction[convertPathToString([...path, key])] = \"NEW\"\n            })\n          }\n          if (typeof rhs !== \"object\") {\n            updatePathMapAction[stringPath] = \"NEW\"\n          }\n          break\n        }\n        case \"D\": {\n          updatePathMapAction[stringPath] = \"DELETE\"\n          break\n        }\n        case \"E\": {\n          updatePathMapAction[stringPath] = \"UPDATE\"\n          break\n        }\n        case \"A\": {\n          const { index, path, item } = d\n          switch (item.kind) {\n            case \"N\": {\n              updatePathMapAction[convertPathToString([...path, index])] = \"NEW\"\n              break\n            }\n            case \"D\": {\n              updatePathMapAction[convertPathToString([...path, index])] =\n                \"DELETE\"\n              break\n            }\n            case \"E\": {\n              updatePathMapAction[convertPathToString([...path, index])] =\n                \"UPDATE\"\n              break\n            }\n            case \"A\": {\n              break\n            }\n          }\n          break\n        }\n      }\n    }\n    return updatePathMapAction\n  }\n\n  updateRawTreeByUpdatePaths(\n    paths: string[],\n    executionTree: Record<string, any>,\n    walkedPath: Set<string>,\n  ) {\n    const currentExecutionTree = klona(executionTree)\n    paths.forEach((path) => {\n      if (!walkedPath.has(path)) {\n        walkedPath.add(path)\n        const fullPathValue = get(this.oldRawTree, path)\n        if (hasDynamicStringSnippet(fullPathValue)) {\n          const value = get(this.oldRawTree, path, undefined)\n          set(currentExecutionTree, path, value)\n        }\n      }\n    })\n    return currentExecutionTree\n  }\n\n  updateTreeFromExecution(executionTree: Record<string, any>) {\n    const currentExecutionTree = klona(executionTree)\n    const differences: Diff<Record<string, any>, Record<string, any>>[] =\n      diff(this.executedTree, currentExecutionTree) || []\n    if (differences.length === 0) {\n      return {\n        evaluatedTree: this.executedTree,\n      }\n    }\n    const walkedPath = new Set<string>()\n\n    const updatePathMapAction = this.getUpdatePathFromDifferences(differences)\n    Object.keys(updatePathMapAction).forEach((path) => {\n      walkedPath.add(path)\n    })\n\n    const orderPath = this.calcSubTreeSortOrder(\n      differences,\n      currentExecutionTree as RawTreeShape,\n      true,\n    )\n\n    const mergedUpdatePathMapAction = this.mergeOrderPathAndUpdateMapActions(\n      orderPath,\n      updatePathMapAction,\n    )\n\n    let currentRawTree = this.updateRawTreeByUpdatePaths(\n      orderPath,\n      currentExecutionTree,\n      walkedPath,\n    ) as RawTreeShape\n\n    const { evaluatedTree, errorTree } = this.executeTree(\n      currentRawTree,\n      orderPath,\n    )\n    const { validateErrors, validateResultTree } =\n      this.validateTree(evaluatedTree)\n\n    const mergedError = merge({}, validateErrors, errorTree)\n\n    const errorTreeResult = this.mergeErrorTree(\n      mergedError,\n      mergedUpdatePathMapAction,\n    )\n    this.errorTree = errorTreeResult\n    this.executedTree = validateResultTree\n\n    return {\n      evaluatedTree: this.executedTree,\n      errorTree: this.errorTree,\n    }\n  }\n\n  listEntityDependencies(\n    widgetOrAction: Record<string, any>,\n    displayName: string,\n  ) {\n    let dependenciesMap: DependenciesState = {}\n    const dynamicAttrPaths: string[] =\n      getWidgetOrActionDynamicAttrPaths(widgetOrAction)\n    if (dynamicAttrPaths.length) {\n      dynamicAttrPaths.forEach((attrPath) => {\n        const originValue = get(widgetOrAction, attrPath)\n        const { jsSnippets } = getSnippets(originValue)\n        const existingDeps = dependenciesMap[`${displayName}.${attrPath}`] || []\n        dependenciesMap[`${displayName}.${attrPath}`] = existingDeps.concat(\n          jsSnippets.filter((jsSnippet) => !!jsSnippet),\n        )\n      })\n    }\n    return dependenciesMap\n  }\n\n  generateDependenciesMap(rawTree: RawTreeShape) {\n    let dependenciesMap: DependenciesState = {}\n    Object.keys(rawTree).forEach((displayName) => {\n      const widgetProps = rawTree[displayName]\n      const widgetOrActionDependencies = this.listEntityDependencies(\n        widgetProps,\n        displayName,\n      )\n      dependenciesMap = { ...dependenciesMap, ...widgetOrActionDependencies }\n    })\n    Object.keys(dependenciesMap).forEach((key) => {\n      dependenciesMap[key] = flatten(\n        dependenciesMap[key].map((script) => {\n          try {\n            return extractReferencesFromScript(script)\n          } catch (e) {\n            return []\n          }\n        }),\n      ).filter((path) => {\n        const [currentDisplayName, ..._currentPaths] = toPath(key)\n        const [targetDisplayName, ..._targetPaths] = toPath(path)\n        const currentNode = rawTree[currentDisplayName]\n        const targetNode = rawTree[targetDisplayName]\n        if (!currentNode || !targetNode) return path\n        if (currentNode.$type === \"WIDGET\" && targetNode.$type === \"WIDGET\")\n          return currentNode.$parentPageName === targetNode.$parentPageName\n        return path\n      })\n    })\n\n    return dependenciesMap\n  }\n\n  sortEvalOrder(dependenciesMap: DependenciesState): string[] {\n    const dependencyTree: Array<[string, string]> = []\n    Object.keys(dependenciesMap).forEach((key: string) => {\n      if (dependenciesMap[key].length) {\n        dependenciesMap[key].forEach((dep) => dependencyTree.push([key, dep]))\n      } else {\n        dependencyTree.push([key, \"\"])\n      }\n    })\n\n    try {\n      return toposort(dependencyTree)\n        .reverse()\n        .filter((d) => !!d)\n    } catch (e) {\n      this.hasCyclical = true\n      if (e instanceof Error) {\n        console.log(\"e.message\", e.message)\n        const nodes = e.message.match(\n          new RegExp('Cyclic dependency, node was:\"(.*)\"'),\n        )\n        if (nodes) {\n          const node = nodes[1]\n          const entityName = node.split(\".\")[0]\n          message.error({\n            content: i18n.t(\"message.circular_dependency\", {\n              nodeName: entityName,\n            }),\n          })\n        }\n      }\n      throw new Error(\"Cyclic dependency\")\n    }\n  }\n\n  generateInDependenciesMap(): DependenciesState {\n    const inverseDag: DependenciesState = {}\n    this.evalOrder.forEach((propertyPath) => {\n      const incomingEdges: Array<string> = this.dependenciesState[propertyPath]\n      if (incomingEdges) {\n        incomingEdges.forEach((edge) => {\n          const node = inverseDag[edge]\n          if (node) {\n            node.push(propertyPath)\n          } else {\n            inverseDag[edge] = [propertyPath]\n          }\n        })\n      }\n    })\n    return inverseDag\n  }\n\n  executeTree(\n    oldRawTree: RawTreeShape,\n    sortedEvalOrder: string[],\n    point: number = -1,\n  ) {\n    const oldLocalRawTree = klona(oldRawTree)\n    const errorTree: ExecutionState[\"error\"] = {}\n    try {\n      const evaluatedTree = sortedEvalOrder.reduce(\n        (current: RawTreeShape, fullPath: string, currentIndex: number) => {\n          const { displayName, attrPath } = getDisplayNameAndAttrPath(fullPath)\n          const widgetOrAction = current[displayName]\n          let widgetOrActionAttribute = get(current, fullPath)\n          let evaluateValue\n          if (point === currentIndex) {\n            widgetOrActionAttribute = \"defaultValue\"\n          }\n          const requiredEval = hasDynamicStringSnippet(widgetOrActionAttribute)\n          if (requiredEval) {\n            try {\n              const { result, context } =\n                evaluateDynamicStringAndGetCalcContext(\n                  attrPath,\n                  widgetOrActionAttribute,\n                  current,\n                )\n              evaluateValue = result\n\n              const currentContext = get(current, `${displayName}.$context`, {})\n\n              Object.keys(context).forEach((key) => {\n                const value = context[key] ?? \"\"\n                currentContext[key] = value\n              })\n\n              if (typeof evaluateValue === \"function\") {\n                set(current, fullPath, undefined)\n              } else {\n                set(current, fullPath, evaluateValue)\n              }\n            } catch (e) {\n              let oldError = errorTree[fullPath]\n              if (!Array.isArray(oldError)) {\n                oldError = []\n              }\n              oldError.push({\n                errorType: ExecutionErrorType.EVALUATED,\n                errorMessage: (e as Error).message,\n                errorName: (e as Error).name,\n              })\n              errorTree[fullPath] = oldError\n              set(current, fullPath, undefined)\n            }\n          }\n          if (\n            isAction(widgetOrAction) &&\n            !IGNORE_ACTION_RUN_ATTR_NAME.includes(toPath(attrPath)[0])\n          ) {\n            for (let i = currentIndex + 1; i < sortedEvalOrder.length; i++) {\n              const currentDynamicString = sortedEvalOrder[i]\n              if (currentDynamicString.includes(widgetOrAction.displayName)) {\n                return current\n              }\n            }\n            if (\n              widgetOrAction.actionType !== \"transformer\" &&\n              widgetOrAction.triggerMode === \"automate\"\n            ) {\n              const { $actionID } = widgetOrAction\n\n              const runningActionID = this.runningActionsMap.get($actionID)\n              if (runningActionID) {\n                window.clearTimeout(runningActionID)\n              }\n              const deleteID = window.setTimeout(() => {\n                runActionWithExecutionResult(\n                  widgetOrAction as IExecutionActions,\n                )\n              }, 300)\n              this.runningActionsMap.set($actionID, deleteID)\n            }\n          }\n          return current\n        },\n        oldLocalRawTree,\n      )\n      return { evaluatedTree, errorTree }\n    } catch (e) {\n      return { evaluatedTree: oldLocalRawTree, errorTree }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/generateGlobalData.ts",
    "content": "import { hasDynamicStringSnippet } from \"@illa-public/dynamic-string\"\nimport { klona } from \"klona\"\nimport { isObject } from \"../typeHelper\"\n\nexport const generateGlobalData = (globalData: Record<string, unknown>) => {\n  const clonedGlobalData = klona(globalData)\n  const $dynamicAttrPaths: string[] = []\n  if (isObject(globalData)) {\n    Object.keys(globalData).forEach((key) => {\n      if (hasDynamicStringSnippet(globalData[key])) {\n        $dynamicAttrPaths.push(key)\n      }\n    })\n  }\n  clonedGlobalData.$dynamicAttrPaths = $dynamicAttrPaths\n  return clonedGlobalData\n}\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/generatePageInfo.ts",
    "content": "import { WidgetSeedShape } from \"./interface\"\n\nexport const generateCurrentPageInfo = () => {\n  return {\n    pagePath: \"{{root.pageSortedKey[root.currentPageIndex]}}\",\n    subPagePath: \"{{root.currentSubPagePath}}\",\n    $dynamicAttrPaths: [\"pagePath\", \"subPagePath\"],\n  }\n}\n\nexport const generatePageInfos = (widgets: WidgetSeedShape) => {\n  const rootNode = widgets.root\n  if (!rootNode) return []\n  const pageDisplayNameMapViewDisplayName: Record<string, Set<string>> = {}\n  const pageNodes = rootNode.$childrenNode as string[]\n  const homepageDisplayName: string =\n    rootNode.homepageDisplayName ?? pageNodes[0]\n  pageNodes.forEach((pageNodeDisplayName) => {\n    pageDisplayNameMapViewDisplayName[pageNodeDisplayName] = new Set()\n    const pageNode = widgets[pageNodeDisplayName]\n    const sectionNodes = pageNode.$childrenNode as string[]\n    sectionNodes.forEach((sectionNodeDisplayName) => {\n      const sectionNode = widgets[sectionNodeDisplayName]\n      const sectionConfigs =\n        (sectionNode.sectionViewConfigs as Record<string, string>[]) ?? []\n      sectionConfigs.forEach((sectionConfig: Record<string, string>) => {\n        pageDisplayNameMapViewDisplayName[pageNodeDisplayName].add(\n          sectionConfig.path,\n        )\n      })\n    })\n  })\n  const result: {\n    pagePath: string\n    subPagePath?: string\n    pageName: string\n    subPageName?: string\n    isHomePage: boolean\n    subPageGroup: string\n  }[] = []\n  Object.keys(pageDisplayNameMapViewDisplayName).forEach((pageDisplayName) => {\n    const subPagePaths = Array.from(\n      pageDisplayNameMapViewDisplayName[pageDisplayName],\n    )\n    if (subPagePaths.length > 0) {\n      subPagePaths.forEach((path, index, array) => {\n        if (array.length === 1) {\n          result.push({\n            pagePath: `/${pageDisplayName}`,\n            subPagePath: `/${pageDisplayName}/${path}`,\n            pageName: pageDisplayName,\n            subPageName: path,\n            isHomePage: pageDisplayName === homepageDisplayName,\n            subPageGroup: \"\",\n          })\n        } else {\n          result.push({\n            pagePath: `/${pageDisplayName}`,\n            subPagePath: `/${pageDisplayName}/${path}`,\n            pageName: pageDisplayName,\n            subPageName: path,\n            isHomePage: pageDisplayName === homepageDisplayName,\n            subPageGroup: pageDisplayName,\n          })\n        }\n      })\n    } else {\n      result.push({\n        pagePath: `/${pageDisplayName}`,\n        pageName: pageDisplayName,\n        isHomePage: pageDisplayName === homepageDisplayName,\n        subPageGroup: \"\",\n      })\n    }\n  })\n  return result\n}\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/generateRawAction.ts",
    "content": "import { ActionContent, TransformerAction } from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { getNewWidgetPropsByUpdateSlice } from \"../componentNode\"\nimport { VALIDATION_TYPES } from \"../validationFactory\"\n\ninterface RawAction {\n  [key: string]: any\n\n  $type: \"ACTION\"\n  $dynamicAttrPaths: string[]\n}\n\nexport const generateActionValidatePaths = () => {\n  return {\n    \"config.advancedConfig.delayWhenLoaded\": VALIDATION_TYPES.NUMBER,\n    \"config.advancedConfig.periodInterval\": VALIDATION_TYPES.NUMBER,\n  }\n}\n\nexport const generateRawAction = (\n  action: ActionItem<ActionContent>,\n): RawAction => {\n  const {\n    content,\n    transformer,\n    actionID,\n    resourceID,\n    displayName,\n    actionType,\n    config,\n    triggerMode,\n  } = action\n  const modifiedAction: RawAction = {\n    $actionID: actionID,\n    $resourceID: resourceID,\n    displayName,\n    actionType,\n    $type: \"ACTION\",\n    $dynamicAttrPaths: [],\n  }\n  if (actionType === \"transformer\") {\n    modifiedAction.value = (content as TransformerAction).transformerString\n  } else {\n    modifiedAction.data = undefined\n    modifiedAction.content = content\n    modifiedAction.config = config\n    modifiedAction.triggerMode = triggerMode\n    modifiedAction.transformer = transformer\n    modifiedAction.$validationPaths = generateActionValidatePaths()\n  }\n\n  const newProps = getNewWidgetPropsByUpdateSlice(modifiedAction, {})\n  modifiedAction.$dynamicAttrPaths = [\n    ...((newProps?.$dynamicAttrPaths ?? []) as string[]),\n  ]\n  let context: Record<string, unknown> = {}\n\n  modifiedAction.$context = context\n\n  return modifiedAction\n}\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/generateRawWidget.ts",
    "content": "import { WidgetShape } from \"@/utils/executionTreeHelper/interface\"\nimport { generateAllTypePathsFromWidgetConfig } from \"@/utils/generators/generateAllTypePathsFromWidgetConfig\"\nimport { widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\n\nexport const generateRawWidget = (widget: WidgetShape) => {\n  const { $widgetType } = widget\n  const widgetConfig = widgetBuilder($widgetType)\n  if (!widgetConfig) return widget\n  const panelConfig = widgetConfig.panelConfig\n  const { validationPaths } = generateAllTypePathsFromWidgetConfig(\n    panelConfig,\n    widget,\n  )\n\n  return {\n    ...widget,\n    $validationPaths: validationPaths,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/generateUrlParams.ts",
    "content": "import { parse } from \"qs\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport store from \"@/store\"\n\nexport const generateUrlParams = () => {\n  const href = window.location.href\n  const query = href.split(\"?\")[1]\n  const queryArray = parse(query)\n  let appURL = href\n  if (getIsILLAProductMode(store.getState())) {\n    appURL = window.location.origin + window.location.pathname\n  }\n  return {\n    query: queryArray,\n    url: href,\n    appURL,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/interface.ts",
    "content": "import { ActionContent, CurrentUserInfo } from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { BuilderInfo } from \"@/redux/builderInfo/builderInfoState\"\n\nexport interface CurrentUserInfoInTree {\n  userID: string\n  nickname: string\n  email: string\n  avatar: string\n  language: string\n  createdAt: string\n  updateAt: string\n}\n\nexport interface RawTreeShape {\n  [key: string]: any\n  builderInfo: BuilderInfo\n  currentUserInfo: CurrentUserInfoInTree\n}\n\ntype ActionSeedShape = ActionItem<ActionContent>[]\n\nexport interface WidgetShape {\n  [key: string]: any\n  $type: \"WIDGET\"\n  $widgetType: string\n  $childrenNode: string[]\n}\nexport interface WidgetSeedShape {\n  [key: string]: WidgetShape\n}\n\nexport interface RawTreeSeedShape {\n  widgets: WidgetSeedShape\n  actions: ActionSeedShape\n  builderInfo: BuilderInfo\n  currentUserInfo: CurrentUserInfo\n  globalData: Record<string, unknown>\n}\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/rawTreeFactory.ts",
    "content": "import { generateRawAction } from \"@/utils/executionTreeHelper/generateRawAction\"\nimport { generateRawWidget } from \"@/utils/executionTreeHelper/generateRawWidget\"\nimport {\n  CurrentUserInfoInTree,\n  RawTreeSeedShape,\n  RawTreeShape,\n} from \"@/utils/executionTreeHelper/interface\"\nimport { CUSTOM_STORAGE_PREFIX } from \"../storage\"\nimport { generateGlobalData } from \"./generateGlobalData\"\nimport { generateCurrentPageInfo, generatePageInfos } from \"./generatePageInfo\"\nimport { generateUrlParams } from \"./generateUrlParams\"\n\nexport const CURRENT_USER_INFO_ACCESS_LIST_KEY = [\n  \"userID\",\n  \"nickname\",\n  \"email\",\n  \"avatar\",\n  \"language\",\n  \"createdAt\",\n  \"updatedAt\",\n]\n\nexport class RawTreeFactory {\n  static create(seeds: RawTreeSeedShape): RawTreeShape {\n    const { widgets, actions, builderInfo, currentUserInfo, globalData } = seeds\n    const rawTree: RawTreeShape = {} as RawTreeShape\n\n    actions.forEach((action) => {\n      rawTree[action.displayName] = generateRawAction(action)\n    })\n\n    Object.keys(widgets).forEach((key) => {\n      rawTree[key] = generateRawWidget(widgets[key])\n    })\n\n    const customStorage = localStorage[CUSTOM_STORAGE_PREFIX]\n\n    const canShownUserInfo: CurrentUserInfoInTree = Object.keys(\n      currentUserInfo,\n    ).reduce((acc, key) => {\n      if (\n        CURRENT_USER_INFO_ACCESS_LIST_KEY.includes(key) &&\n        currentUserInfo[key as keyof typeof currentUserInfo]\n      ) {\n        acc[key as keyof CurrentUserInfoInTree] = currentUserInfo[\n          key as keyof typeof currentUserInfo\n        ] as string\n      }\n      return acc\n    }, {} as CurrentUserInfoInTree)\n\n    rawTree.builderInfo = builderInfo\n    rawTree.currentUserInfo = canShownUserInfo\n    rawTree.globalData = generateGlobalData(globalData)\n    rawTree.urlParams = generateUrlParams()\n    rawTree.localStorage = customStorage ? JSON.parse(customStorage) : {}\n    rawTree.currentPageInfo = generateCurrentPageInfo()\n    rawTree.pageInfos = generatePageInfos(widgets)\n    return rawTree\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/rrecursiveDelete.ts",
    "content": "export function recursiveDelete(\n  obj: Record<string, unknown>,\n  ignoredKeys?: string[],\n): Record<string, unknown> {\n  const newObj: Record<string, unknown> = {}\n\n  for (let key in obj) {\n    if (!key.startsWith(\"$\") && !ignoredKeys?.includes(key)) {\n      if (\n        typeof obj[key] === \"object\" &&\n        obj[key] !== null &&\n        !Array.isArray(obj[key])\n      ) {\n        newObj[key] = recursiveDelete(\n          obj[key] as Record<string, unknown>,\n          ignoredKeys,\n        )\n      } else {\n        newObj[key] = obj[key]\n      }\n    }\n  }\n\n  return newObj\n}\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/runtimePropsCollector.ts",
    "content": "import dayjs from \"dayjs\"\nimport { klona } from \"klona/json\"\nimport _ from \"lodash-es\"\nimport numbro from \"numbro\"\nimport Papa from \"papaparse\"\nimport { NIL, parse, stringify, v1, v3, v4, v5, validate, version } from \"uuid\"\nimport {\n  getExecutionResult,\n  getExecutionResultToCurrentPageCodeMirror,\n  getExecutionResultToGlobalCodeMirror,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport store from \"@/store\"\nimport { runActionWithExecutionResult } from \"../action/runAction\"\nimport {\n  copyToClipboard,\n  downloadFile,\n  goToURL,\n  setRouter,\n  showNotification,\n} from \"../eventHandlerHelper/utils/commonUtils\"\nimport {\n  downloadFromILLADrive,\n  saveToILLADrive,\n} from \"../eventHandlerHelper/utils/driveUtils\"\nimport {\n  setGlobalDataIn,\n  setGlobalDataValue,\n} from \"../eventHandlerHelper/utils/globalDataUtils\"\nimport {\n  clearLocalStorage,\n  setValueLocalStorage,\n} from \"../eventHandlerHelper/utils/localStorage\"\n\nconst THIRD_PARTY_PACKAGES = {\n  _: {\n    ..._,\n  },\n  uuid: {\n    NIL,\n    parse,\n    stringify,\n    v1,\n    v3,\n    v4,\n    v5,\n    validate,\n    version,\n  },\n  dayjs,\n  numbro,\n  Papa,\n}\nclass ILLAEditorRuntimePropsCollector {\n  private _runtimeProps: Record<string, unknown> = {}\n  private static instance: ILLAEditorRuntimePropsCollector | null = null\n\n  constructor() {\n    this._runtimeProps = {\n      ...THIRD_PARTY_PACKAGES,\n      utils: {\n        goToURL,\n        showNotification,\n        copyToClipboard,\n        setRouter,\n        downloadFile,\n        downloadFromILLADrive,\n        saveToILLADrive,\n        setGlobalDataIn,\n        setGlobalDataValue,\n        setLocalStorage: setValueLocalStorage,\n        clearLocalStorage,\n      },\n    }\n  }\n\n  public static getInstance(): ILLAEditorRuntimePropsCollector {\n    if (!ILLAEditorRuntimePropsCollector.instance) {\n      ILLAEditorRuntimePropsCollector.instance =\n        new ILLAEditorRuntimePropsCollector()\n    }\n    return ILLAEditorRuntimePropsCollector.instance\n  }\n\n  public addRuntimeProp(displayName: string, runtimeProp: unknown) {\n    this._runtimeProps[displayName] = runtimeProp\n  }\n\n  public deleteRuntimeProp(displayName: string) {\n    if (!this._runtimeProps[displayName]) return\n    delete this._runtimeProps[displayName]\n  }\n\n  public getRuntimeProps() {\n    return this._runtimeProps\n  }\n\n  public getThirdPartyPackages() {\n    return THIRD_PARTY_PACKAGES\n  }\n\n  public getGlobalCalcContext(otherContext: Record<string, unknown> = {}) {\n    const rootState = store.getState()\n    const executionResult = getExecutionResult(rootState)\n    const cloneDeepExecutionResult = klona(executionResult)\n\n    const formatedExecutionResult = Object.keys(\n      cloneDeepExecutionResult,\n    ).reduce(\n      (acc, prevKey) => {\n        const prev = cloneDeepExecutionResult[prevKey]\n        if (!prev) {\n          return acc\n        }\n        if (prev.$type === \"ACTION\") {\n          return {\n            ...acc,\n            [prev.displayName]: {\n              ...prev,\n              trigger: async () => {\n                return await runActionWithExecutionResult(prev, false)\n              },\n            },\n          }\n        }\n        if (prev.$type === \"WIDGET\") {\n          const runtimePros = this._runtimeProps[prev.displayName]\n          if (runtimePros) {\n            return {\n              ...acc,\n              [prev.displayName]: {\n                ...prev,\n                ...runtimePros,\n              },\n            }\n          }\n        }\n        return {\n          ...acc,\n          [prevKey]: prev,\n        }\n      },\n      {} as Record<string, any>,\n    )\n\n    const utils = this._runtimeProps.utils as Record<string, unknown>\n    const mergeResult = {\n      ...formatedExecutionResult,\n      ...THIRD_PARTY_PACKAGES,\n      utils,\n      ...otherContext,\n    }\n\n    return mergeResult\n  }\n\n  public getCurrentPageCalcContext(otherContext: Record<string, unknown> = {}) {\n    const rootState = store.getState()\n    const executionResult = getExecutionResultToCurrentPageCodeMirror(\n      rootState,\n    ) as Record<string, any>\n    const cloneDeepExecutionResult = klona(executionResult)\n    const formatedExecutionResult = Object.keys(\n      cloneDeepExecutionResult,\n    ).reduce(\n      (acc, prevKey) => {\n        const prev = cloneDeepExecutionResult[prevKey]\n\n        if (!prev) {\n          return acc\n        }\n\n        if (\n          (Object.hasOwn && Object.hasOwn(prev, \"actionType\")) ||\n          Object.prototype.hasOwnProperty.call(prev, \"actionType\")\n        ) {\n          return {\n            ...acc,\n            [prev.displayName]: {\n              ...prev,\n              trigger: async () => {\n                return await runActionWithExecutionResult(prev, false)\n              },\n            },\n          }\n        }\n\n        if (prev.$type === \"WIDGET\") {\n          switch (prev.$widgetType) {\n            case \"MODAL_WIDGET\":\n              return {\n                ...acc,\n                [prevKey]: {\n                  ...prev,\n                  openModal: () => {\n                    store.dispatch(\n                      executionActions.updateModalDisplayReducer({\n                        display: true,\n                        displayName: prevKey,\n                      }),\n                    )\n                  },\n                  closeModal: () => {\n                    store.dispatch(\n                      executionActions.updateModalDisplayReducer({\n                        display: false,\n                        displayName: prevKey,\n                      }),\n                    )\n                  },\n                },\n              }\n            default: {\n              const runtimePros = this._runtimeProps[prev.displayName]\n              if (runtimePros) {\n                return {\n                  ...acc,\n                  [prev.displayName]: {\n                    ...prev,\n                    ...runtimePros,\n                  },\n                }\n              }\n            }\n          }\n        }\n        return {\n          ...acc,\n          [prevKey]: prev,\n        }\n      },\n      {} as Record<string, any>,\n    )\n    const utils = this._runtimeProps.utils as Record<string, unknown>\n    const mergeResult = {\n      ...formatedExecutionResult,\n      ...THIRD_PARTY_PACKAGES,\n      utils,\n      ...otherContext,\n    }\n\n    return mergeResult\n  }\n\n  public getGlobalCalcContextWithLimit(otherContext?: Record<string, unknown>) {\n    const rootState = store.getState()\n    const executionResult = getExecutionResultToGlobalCodeMirror(rootState)\n    const cloneDeepExecutionResult = klona(executionResult)\n    const utils = this._runtimeProps.utils as Record<string, unknown>\n    const mergeResult = {\n      ...cloneDeepExecutionResult,\n      ...THIRD_PARTY_PACKAGES,\n      utils,\n      ...otherContext,\n    }\n    return mergeResult\n  }\n}\n\nexport const ILLAEditorRuntimePropsCollectorInstance =\n  ILLAEditorRuntimePropsCollector.getInstance()\n"
  },
  {
    "path": "apps/builder/src/utils/executionTreeHelper/utils.ts",
    "content": "import {\n  convertPathToString,\n  extractIdentifierInfoFromCode,\n} from \"@illa-public/dynamic-string\"\nimport { toPath } from \"lodash-es\"\nimport { isObject } from \"@/utils/typeHelper\"\n\nconst IMMEDIATE_PARENT_REGEX = /^(.*)(\\..*|\\[.*\\])$/\n\nexport const extractReferencesFromScript = (script: string): string[] => {\n  const newReference = new Set<string>()\n  const { references } = extractIdentifierInfoFromCode(script)\n\n  references.forEach((identifier: string) => {\n    newReference.add(identifier)\n    const subPaths = toPath(identifier)\n    let current = \"\"\n    while (subPaths.length > 1) {\n      current = convertPathToString(subPaths)\n      newReference.add(current)\n      subPaths.pop()\n    }\n  })\n  return Array.from(newReference)\n}\n\nexport function getDisplayNameAndPropertyPath(fullPath: string): {\n  displayName: string\n  attrPath: string\n} {\n  const indexOfFirstDot = fullPath.indexOf(\".\")\n  if (indexOfFirstDot === -1) {\n    return {\n      displayName: fullPath,\n      attrPath: \"\",\n    }\n  }\n  const displayName = fullPath.substring(0, indexOfFirstDot)\n  const attrPath = fullPath.substring(indexOfFirstDot + 1)\n  return { displayName, attrPath }\n}\n\nexport function isWidget(entity: Record<string, any>) {\n  return (\n    typeof entity === \"object\" && \"$type\" in entity && entity.$type === \"WIDGET\"\n  )\n}\n\nexport function isAction(entity: Record<string, any>) {\n  return (\n    typeof entity === \"object\" && \"$type\" in entity && entity.$type === \"ACTION\"\n  )\n}\n\nexport const getImmediateParentsOfPropertyPaths = (\n  propertyPaths: string[],\n): string[] => {\n  const parents: Set<string> = new Set()\n\n  propertyPaths.forEach((path) => {\n    const matches = path.match(IMMEDIATE_PARENT_REGEX)\n\n    if (matches !== null) {\n      parents.add(matches[1])\n    }\n  })\n\n  return Array.from(parents)\n}\n\nexport const removeIgnoredKeys = (result: Record<string, unknown>) => {\n  return Object.keys(result).reduce(\n    (acc: Record<string, unknown>, key: string) => {\n      const componentOrAction = result[key]\n      if (isObject(componentOrAction)) {\n        const updatedComponentOrAction = Object.keys(componentOrAction).reduce(\n          (obj: Record<string, unknown>, innerKey: string) => {\n            if (!innerKey.startsWith(\"$\")) {\n              obj[innerKey] = componentOrAction[innerKey]\n            }\n            return obj\n          },\n          {},\n        )\n        acc[key] = updatedComponentOrAction\n      } else {\n        acc[key] = componentOrAction\n      }\n      return acc\n    },\n    {},\n  )\n}\n\nexport const removeParentPath = (paths: string[]) => {\n  const dotPaths = paths.map((path) => toPath(path).join(\".\"))\n\n  const filteredPaths = dotPaths.filter((path, index, array) => {\n    return !array.some((otherPath, otherIndex) => {\n      if (index === otherIndex) return false\n      return otherPath.startsWith(`${path}.`)\n    })\n  })\n\n  return filteredPaths.map((path) => convertPathToString(toPath(path)))\n}\n\nexport const removeWidgetOrActionMethods = (\n  result: Record<string, unknown>,\n) => {\n  return Object.keys(result).reduce(\n    (acc: Record<string, unknown>, key: string) => {\n      if (key === \"utils\") return acc\n      const componentOrAction = result[key]\n      if (\n        isObject(componentOrAction) &&\n        (componentOrAction.$type === \"WIDGET\" ||\n          componentOrAction.$type === \"ACTION\")\n      ) {\n        const updatedComponentOrAction = Object.keys(componentOrAction).reduce(\n          (obj: Record<string, unknown>, innerKey: string) => {\n            const innerValue = componentOrAction[innerKey]\n            if (typeof innerValue !== \"function\") {\n              obj[innerKey] = componentOrAction[innerKey]\n            }\n            return obj\n          },\n          {},\n        )\n        acc[key] = updatedComponentOrAction\n      } else {\n        acc[key] = componentOrAction\n      }\n      return acc\n    },\n    {},\n  )\n}\n\nexport function getObjectPaths(obj: Record<string, unknown>, currentPath = \"\") {\n  let paths: string[] = []\n\n  if (typeof obj === \"object\" && obj !== null) {\n    Object.keys(obj).forEach((key) => {\n      const value = obj[key]\n      const newPath = Array.isArray(obj)\n        ? `${currentPath}.${key}`\n        : `${currentPath ? currentPath + \".\" : \"\"}${key}`\n      if (typeof value === \"object\" && value !== null) {\n        paths = paths.concat(\n          getObjectPaths(value as Record<string, unknown>, newPath),\n        )\n      } else {\n        paths.push(newPath)\n      }\n    })\n  }\n\n  return paths.map((path) => (path.startsWith(\".\") ? path.substr(1) : path))\n}\n"
  },
  {
    "path": "apps/builder/src/utils/file/calculateFileInfo.ts",
    "content": "import XLSX from \"xlsx\"\nimport { createMessage, isArray, isObject } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { fetchDownloadFileFromURL } from \"@/services/action\"\nimport { downloadFile } from \"../eventHandlerHelper/utils/commonUtils\"\n\nexport const calculateFileSize = (data: string | string[]) => {\n  const blobArr = Array.isArray(data) ? data : [data]\n  return new Blob(blobArr).size\n}\n\nexport const isValidBase64 = (str: string) => {\n  try {\n    window.atob(str)\n    return true\n  } catch (e) {\n    return false\n  }\n}\n\nexport const getFileExtensionFromBase64 = (base64: string) => {\n  return base64.split(\";\")[0].split(\"/\")[1]\n}\n\nexport const downloadSingleFile = (\n  contentType: string,\n  fileName: string,\n  data: BlobPart,\n) => {\n  const isBase64 = typeof data === \"string\" ? isValidBase64(data) : false\n  const isDownloadBase64 = isBase64 && !!contentType\n  let href = \"\"\n  if (!isDownloadBase64) {\n    const blob = new Blob([data], { type: contentType })\n    href = URL.createObjectURL(blob)\n  }\n  const a = document.createElement(\"a\")\n  a.download = fileName\n  a.style.display = \"none\"\n  a.href = isDownloadBase64 ? `data:${contentType};base64,${data}` : href\n  document.body.appendChild(a)\n  a.click()\n  document.body.removeChild(a)\n}\n\nexport const FILE_EXTENSION_TO_CONTENT_TYPE_MAP = {\n  // Images\n  jpg: \"image/jpeg\",\n  jpeg: \"image/jpeg\",\n  png: \"image/png\",\n  gif: \"image/gif\",\n  bmp: \"image/bmp\",\n  svg: \"image/svg+xml\",\n  webp: \"image/webp\",\n  ico: \"image/x-icon\",\n\n  // Audio\n  mp3: \"audio/mpeg\",\n  wav: \"audio/wav\",\n  ogg: \"audio/ogg\",\n  mid: \"audio/midi\",\n\n  // Video\n  mp4: \"video/mp4\",\n  avi: \"video/x-msvideo\",\n  mpeg: \"video/mpeg\",\n  mov: \"video/quicktime\",\n  webm: \"video/webm\",\n\n  // Text\n  txt: \"text/plain\",\n  html: \"text/html\",\n  css: \"text/css\",\n  js: \"text/javascript\",\n  json: \"application/json\",\n  xml: \"application/xml\",\n\n  // Documents\n  epub: \"application/epub+zip\",\n  pdf: \"application/pdf\",\n  doc: \"application/msword\",\n  docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n  xls: \"application/vnd.ms-excel\",\n  xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n  ppt: \"application/vnd.ms-powerpoint\",\n  pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n\n  // Data\n  csv: \"text/csv\",\n  tsv: \"text/tab-separated-values\",\n  zip: \"application/zip\",\n  gzip: \"application/gzip\",\n}\n\nexport const getContentTypeByFileExtension = (extension: string) => {\n  return (\n    FILE_EXTENSION_TO_CONTENT_TYPE_MAP[\n      (\n        extension ?? \"\"\n      ).toLowerCase() as keyof typeof FILE_EXTENSION_TO_CONTENT_TYPE_MAP\n    ] || \"application/octet-stream\"\n  )\n}\n\nexport const downloadExcelFile = (data: any, contentType: string) => {\n  const bookType =\n    contentType ===\n    \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\n      ? \"xlsx\"\n      : \"xls\"\n\n  const workbook = XLSX.utils.book_new()\n  const sheetName = \"Sheet1\"\n\n  let isObjectItem = true\n\n  let passData\n  if (isArray(data)) {\n    isObjectItem = data.every((item) => isObject(item) || isArray(item))\n    if (isObjectItem) {\n      passData = data.map((item) => convertObj(item, false))\n    } else {\n      passData = [\n        {\n          value: JSON.stringify(data),\n        },\n      ]\n    }\n  } else if (isObject(data)) {\n    passData = [convertObj(data, false)]\n  } else {\n    passData = [{ value: data }]\n  }\n  const skipHeader = !((isArray(data) && isObjectItem) || isObject(data))\n  const worksheet = XLSX.utils.json_to_sheet(passData, {\n    skipHeader,\n  })\n  XLSX.utils.book_append_sheet(workbook, worksheet, sheetName)\n  return XLSX.write(workbook, { type: \"buffer\", bookType })\n}\n\nconst convertObj = (obj: any, format?: boolean): any => {\n  if (isArray(obj)) {\n    return `[${obj.map((item) => convertObj(item, true))}]`\n  }\n  if (isObject(obj)) {\n    const newObj: any = {}\n    Object.keys(obj).forEach((key) => {\n      newObj[key] = convertObj(obj[key], true)\n    })\n    return format ? JSON.stringify(newObj) : newObj\n  }\n  return obj\n}\n\nexport const convertToCSV = (data: any): string => {\n  if (Array.isArray(data)) {\n    if (data.length === 0) {\n      return \"\"\n    }\n    const firstRow = data[0]\n    const keys = Object.keys(firstRow)\n    const header = keys.map((key) => `${key}`).join(\",\")\n    const rows = data.map((row) => convertToCSV(row))\n    return `${header}\\n${rows.join(\"\\n\")}`\n  } else if (typeof data === \"object\" && data !== null) {\n    const values = []\n    for (const key in data) {\n      if (data.hasOwnProperty(key)) {\n        const value = data[key]\n        if (typeof value === \"object\" && !Array.isArray(value)) {\n          values.push(`\"${convertObj(value, true).replace(/\"/g, '\"\"')}\"`)\n        } else if (Array.isArray(value)) {\n          values.push(\n            `\"[${value\n              .map((item) => convertObj(item, true))\n              .join(\" , \")\n              .replace(/\"/g, '\"\"')}]\"`,\n          )\n        } else {\n          values.push(value)\n        }\n      }\n    }\n    return values.join(\",\")\n  } else {\n    return `${data}`\n  }\n}\n\nexport const convertToTSV = (data: any): string => {\n  if (Array.isArray(data)) {\n    if (data.length === 0) {\n      return \"\"\n    }\n    const firstRow = data[0]\n    const keys = Object.keys(firstRow)\n    const header = keys.join(\"\\t\")\n    const rows = data.map((row) => convertToTSV(row))\n    return `${header}\\n${rows.join(\"\\n\")}`\n  } else if (typeof data === \"object\" && data !== null) {\n    const values = []\n    for (const key in data) {\n      if (data.hasOwnProperty(key)) {\n        const value = data[key]\n        if (typeof value === \"object\" && !Array.isArray(value)) {\n          values.push(`\"${convertObj(value, true).replace(/\"/g, '\"\"')}\"`)\n        } else if (Array.isArray(value)) {\n          values.push(\n            `\"[${value\n              .map((item) => convertObj(item, true))\n              .join(\", \")\n              .replace(/\"/g, '\"\"')}]\"`,\n          )\n        } else {\n          values.push(value)\n        }\n      }\n    }\n    return values.join(\"\\t\")\n  } else {\n    return `${data}`\n  }\n}\n\nexport const getFileName = (fileName: string, fileType: string) => {\n  const namePart = fileName.split(\".\")\n  const length = namePart.length\n  const fileRealName =\n    (!fileName\n      ? \"download\"\n      : length > 1\n        ? namePart.slice(0, -1).join(\".\")\n        : namePart[0]) || \"download\"\n  const fileExtension = length > 1 ? namePart[length - 1] : \"\"\n\n  if (fileExtension) {\n    return `${fileRealName}.${fileExtension}`\n  }\n\n  if (fileType !== \"auto\") {\n    return `${fileRealName}.${fileType}`\n  }\n\n  return `${fileRealName}`\n}\n\nexport const downloadFileFromURL = async (\n  data: string,\n  fileDownloadName: string,\n  contentType: string,\n) => {\n  const message = createMessage()\n  try {\n    const res = await fetchDownloadFileFromURL(data)\n    downloadFile({\n      fileType: contentType,\n      fileName: fileDownloadName,\n      data: res,\n    })\n    return\n  } catch (e) {\n    message.error({\n      content: i18n.t(\"editor.method.file_download.message.fail\"),\n    })\n    return\n  }\n}\n\nexport const base642Blob = async (base64: string) => {\n  const result = await fetch(base64)\n  return result.blob()\n}\n"
  },
  {
    "path": "apps/builder/src/utils/file/index.ts",
    "content": "export * from \"./calculateFileInfo\"\nexport * from \"./upload\"\nexport * from \"./parseFileValue\"\n"
  },
  {
    "path": "apps/builder/src/utils/file/parseFileValue.ts",
    "content": "import {\n  EXCEL_FILE_TYPE_RULES,\n  IMAGE_FILE_TYPE_RULES,\n  PDF_FILE_TYPE_RULES,\n  WORD_FILE_TYPE_RULES,\n  matchRules,\n} from \"@illa-public/utils\"\nimport { extractRawText } from \"mammoth\"\nimport { GlobalWorkerOptions, PDFDocumentProxy, getDocument } from \"pdfjs-dist\"\nimport pdfWorker from \"pdfjs-dist/build/pdf.worker.js?url\"\nimport { read, utils } from \"xlsx\"\n\nGlobalWorkerOptions.workerSrc = pdfWorker\n\nconst C_MAP_URL = \"https://unpkg.com/pdfjs-dist@2.16.105/cmaps/\"\n\nexport const handleParseSheets = (\n  data: any,\n  type: \"base64\" | \"buffer\" | \"string\" = \"base64\",\n) => {\n  let res = {}\n  const f = read(data, { type })\n  const sheetNames = f.SheetNames\n  for (let i = 0; i < sheetNames.length; i++) {\n    const sheet = f.Sheets[sheetNames[i]]\n    const value = {\n      [sheetNames[i]]: utils.sheet_to_txt(sheet, { blankrows: false }),\n    }\n    res = {\n      ...res,\n      ...value,\n    }\n  }\n  return JSON.stringify(res)\n}\n\nexport const handleParsePdf = async (source: ArrayBuffer) => {\n  const getPageText = async (pdf: PDFDocumentProxy, pageNo: number) => {\n    const page = await pdf.getPage(pageNo)\n    const tokenizedText = await page.getTextContent()\n    const pageText = tokenizedText.items\n      .map((token) => {\n        if (\"str\" in token) {\n          return token.str\n        }\n        return \"\"\n      })\n      .join(\"\")\n    return pageText\n  }\n\n  try {\n    const pdf = await getDocument({\n      data: source,\n      cMapPacked: true,\n      cMapUrl: C_MAP_URL,\n    }).promise\n    const maxPages = pdf.numPages\n    const pageTextPromises = []\n    for (let pageNo = 1; pageNo <= maxPages; pageNo++) {\n      pageTextPromises.push(getPageText(pdf, pageNo))\n    }\n    const pageTexts = await Promise.all(pageTextPromises)\n    const res = pageTexts.filter((text) => text !== \"\" && text !== undefined)\n    return res.join(\"\\n\\n\")\n  } catch (e) {\n    throw e\n  }\n}\n\nexport const handleParseDoc = async (source: ArrayBuffer) => {\n  const res = (await extractRawText({ arrayBuffer: source })).value\n  return res === \"\\n\\n\" ? \"\" : res\n}\n\nexport const handleParseLikeText = async (file: File): Promise<string> => {\n  return new Promise((resolve) => {\n    var reader = new FileReader()\n    reader.readAsText(file, \"UTF-8\")\n    reader.onload = function () {\n      resolve(reader.result as string)\n    }\n  })\n}\n\nexport const handleParseImage = async (\n  file: File,\n  needUploadImage?: boolean,\n): Promise<string> => {\n  if (needUploadImage) {\n    // upload image\n    return \"image url\"\n  }\n  return \"\"\n}\n\nexport const handleParseFile = async (\n  file: File,\n  needUploadImage?: boolean,\n): Promise<string> => {\n  if (matchRules(IMAGE_FILE_TYPE_RULES, file.type)) {\n    return await handleParseImage(file, needUploadImage)\n  }\n  if (matchRules(EXCEL_FILE_TYPE_RULES, file.type)) {\n    const buffer = await file.arrayBuffer()\n    return handleParseSheets(buffer, \"buffer\")\n  }\n  if (matchRules(PDF_FILE_TYPE_RULES, file.type)) {\n    const buffer = await file.arrayBuffer()\n    return await handleParsePdf(buffer)\n  }\n  if (matchRules(WORD_FILE_TYPE_RULES, file.type)) {\n    const buffer = await file.arrayBuffer()\n    return await handleParseDoc(buffer)\n  }\n  return await handleParseLikeText(file)\n}\n"
  },
  {
    "path": "apps/builder/src/utils/file/upload.ts",
    "content": "import Axios from \"axios\"\n\nexport const upload = async (url: string, file: Blob) => {\n  const resUrl = url.split(\"?\")[0]\n  await Axios.put(url, file, {\n    headers: {\n      \"Content-Type\": \"multipart/form-data\",\n      \"x-amz-acl\": \"public-read\",\n    },\n  })\n  return resUrl\n}\n"
  },
  {
    "path": "apps/builder/src/utils/focusManager.ts",
    "content": "export type ILLAPanelType =\n  | \"none\"\n  | \"data_component\"\n  | \"data_action\"\n  | \"data_page\"\n  | \"data_global_state\"\n  | \"action\"\n  | \"canvas\"\n  | \"widget_picker\"\n  | \"components_config\"\n  | \"page_config\"\nexport interface ClickPosition {\n  displayName: string\n  type: \"inner_container\" | \"component\" | \"group\"\n  clickPosition: number[]\n}\n\nexport class FocusManager {\n  private static currentFocus: ILLAPanelType = \"none\"\n  private static currentClickPosition?: ClickPosition\n\n  static switchFocus(\n    illaPanelType: ILLAPanelType,\n    clickPosition?: ClickPosition,\n  ) {\n    this.currentFocus = illaPanelType\n    this.currentClickPosition = clickPosition\n  }\n\n  static getClickPosition(): ClickPosition | undefined {\n    return this.currentClickPosition\n  }\n\n  static getFocus(): ILLAPanelType {\n    return this.currentFocus\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/formatData.ts",
    "content": "import { isObject } from \"./typeHelper\"\n\nexport const formatDataAsObject = (data: Record<string, any>[]) => {\n  if (!Array.isArray(data) || !data.length) return {}\n  const result: Record<string, unknown[]> = {}\n  data.forEach((d) => {\n    if (!isObject(d)) return\n    if (!Array.isArray(Object.keys(d))) return\n    Object.keys(d).forEach((key) => {\n      const value = d[key]\n      if (!result.hasOwnProperty(key)) {\n        result[key] = []\n      }\n      result[key].push(value)\n    })\n  })\n  return result\n}\n\nexport const formatDataAsArray = (data: Record<string, unknown[]>) => {\n  const keys = Object.keys(data || {})\n  if (!keys.length) return []\n  const result = []\n  const firstKey = keys[0]\n\n  for (let i = 0; i < data[firstKey].length; i++) {\n    const currentObj = keys.reduce((pre, cur) => {\n      if (data[cur][i] != undefined) {\n        pre[cur] = data[cur][i]\n      }\n      return pre\n    }, {} as Record<string, any>)\n    result.push(currentObj)\n  }\n  return result\n}\n"
  },
  {
    "path": "apps/builder/src/utils/generators/generateAllTypePathsFromWidgetConfig.ts",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { get, set, toPath } from \"lodash-es\"\nimport {\n  PanelConfig,\n  PanelFieldGroupConfig,\n} from \"@/page/App/components/InspectPanel/interface\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const generateAllTypePathsFromWidgetConfig = (\n  panelConfig: PanelConfig[],\n  widgetOrAction: Record<string, any>,\n) => {\n  let validationPaths: Record<string, VALIDATION_TYPES> = {}\n  panelConfig.forEach((config) => {\n    if ((config as PanelFieldGroupConfig).children) {\n      const filedConfigs = (config as PanelFieldGroupConfig).children\n      filedConfigs.forEach((filedConfig) => {\n        const attrPath = filedConfig.attrName\n        const configValidationPaths: Record<string, VALIDATION_TYPES> = {}\n\n        if (Array.isArray(attrPath)) {\n          const expectedType = filedConfig.expectedType\n          if (Array.isArray(expectedType)) {\n            attrPath.forEach((path, i) => {\n              set(configValidationPaths, path, expectedType[i])\n            })\n          } else if (expectedType) {\n            attrPath.forEach((path) => {\n              set(configValidationPaths, path, expectedType)\n            })\n          }\n        } else {\n          if (filedConfig.expectedType) {\n            const expectedType = filedConfig.expectedType\n\n            if (Array.isArray(expectedType)) {\n              set(configValidationPaths, attrPath, expectedType[0])\n            } else if (expectedType) {\n              set(configValidationPaths, attrPath, expectedType)\n            }\n          }\n        }\n\n        if (filedConfig.childrenSetter) {\n          const basePropertyPath = filedConfig.attrName\n          const widgetPropertyValue = get(widgetOrAction, basePropertyPath, [])\n          if (Array.isArray(widgetPropertyValue)) {\n            Object.keys(widgetPropertyValue).forEach((key) => {\n              const objectIndexPropertyPath = convertPathToString(\n                toPath(`${basePropertyPath}.${key}`),\n              )\n              filedConfig.childrenSetter?.forEach((childConfig) => {\n                const childAttrPath = childConfig.attrName\n                const expectedType = childConfig.expectedType\n                if (Array.isArray(childAttrPath)) {\n                  if (Array.isArray(expectedType)) {\n                    childAttrPath.forEach((path, i) => {\n                      set(\n                        configValidationPaths,\n                        convertPathToString(\n                          toPath(`${objectIndexPropertyPath}.${path}`),\n                        ),\n                        expectedType[i],\n                      )\n                    })\n                  } else if (expectedType) {\n                    childAttrPath.forEach((path) => {\n                      set(\n                        configValidationPaths,\n                        convertPathToString(\n                          toPath(`${objectIndexPropertyPath}.${path}`),\n                        ),\n                        expectedType,\n                      )\n                    })\n                  }\n                } else {\n                  if (expectedType) {\n                    if (Array.isArray(expectedType)) {\n                      set(\n                        configValidationPaths,\n                        convertPathToString(\n                          toPath(`${objectIndexPropertyPath}.${childAttrPath}`),\n                        ),\n                        expectedType[0],\n                      )\n                    } else if (expectedType) {\n                      set(\n                        configValidationPaths,\n                        convertPathToString(\n                          toPath(`${objectIndexPropertyPath}.${childAttrPath}`),\n                        ),\n                        expectedType,\n                      )\n                    }\n                  }\n                }\n              })\n            })\n          }\n          if (isObject(widgetPropertyValue)) {\n            Object.keys(widgetPropertyValue).forEach((key) => {\n              const objectIndexPropertyPath = convertPathToString(\n                toPath(`${basePropertyPath}.${key}`),\n              )\n              filedConfig.childrenSetter?.forEach((childConfig) => {\n                const expectedType = childConfig.expectedType\n                if (!Array.isArray(expectedType) && expectedType) {\n                  set(\n                    configValidationPaths,\n                    objectIndexPropertyPath,\n                    expectedType,\n                  )\n                }\n              })\n            })\n          }\n        }\n        validationPaths = {\n          ...validationPaths,\n          ...configValidationPaths,\n        }\n      })\n    }\n  })\n\n  return { validationPaths }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/generators/generateComponentNode.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { CONTAINER_TYPE } from \"@illa-public/public-types\"\nimport { klona } from \"klona\"\nimport { get, set } from \"lodash-es\"\nimport { isObject } from \"@illa-design/react\"\nimport { buildInitDragInfo } from \"@/page/App/components/ComponentPanel/componentListBuilder\"\nimport { DEFAULT_MIN_COLUMN } from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { WidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoState\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\nimport { WidgetType, widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\n\nexport const TEMPLATE_DISPLAYNAME_KEY = \"templateDisplayName\"\n\nexport const generateWidgetLayoutInfo = (\n  type: string,\n  baseDisplayName: string,\n  containerType: CONTAINER_TYPE = CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n): WidgetLayoutInfo | undefined => {\n  const realDisplayName = DisplayNameGenerator.generateDisplayName(\n    type,\n    baseDisplayName,\n  )\n  const currentComponentConfig = buildInitDragInfo(type)\n  if (currentComponentConfig === undefined) {\n    return undefined\n  }\n\n  return {\n    displayName: realDisplayName,\n    widgetType: type,\n    layoutInfo: {\n      w: currentComponentConfig.w,\n      h: currentComponentConfig.h,\n      x: currentComponentConfig.x ?? 0,\n      y: currentComponentConfig.y ?? 0,\n      z: 0,\n      minW: DEFAULT_MIN_COLUMN,\n      minH: currentComponentConfig.minH ?? 3,\n    },\n    containerType,\n    parentNode: \"\",\n    childrenNode: [] as string[],\n  }\n}\n\nexport const generateComponentNodeByWidgetInfo = (\n  displayName: string,\n  widgetInfo: Omit<WidgetConfig, \"icon\" | \"sessionType\" | \"keywords\">,\n  parentNodeDisplayName: string,\n  pathToChildren: string[] = [],\n  scale: number = 1,\n) => {\n  let baseDSL: ComponentTreeNode\n  let childrenNodeDSL: ComponentTreeNode[] = []\n  const {\n    defaults,\n    x = 0,\n    y = 0,\n    w = 0,\n    h = 0,\n    minW = DEFAULT_MIN_COLUMN,\n    minH = 3,\n    type,\n    displayName: showName,\n    containerType = CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n    version,\n  } = widgetInfo\n  let props: Record<string, any> | undefined = {}\n  if (typeof defaults === \"function\") {\n    props = klona(defaults())\n  } else {\n    props = klona(defaults)\n  }\n  if (isObject(props) && props.hasOwnProperty(\"formDataKey\")) {\n    props.formDataKey = `{{${displayName}.displayName}}`\n  }\n\n  if (\n    isObject(props) &&\n    props.hasOwnProperty(\"events\") &&\n    Array.isArray(props.events)\n  ) {\n    props.events = props.events.map((event) => {\n      if (event.actionType !== \"widget\") {\n        return event\n      } else {\n        return {\n          ...event,\n          widgetID: pathToChildren[pathToChildren.length - 1] || \"unknown\",\n        }\n      }\n    })\n  }\n\n  if (widgetInfo.childrenNode && Array.isArray(widgetInfo.childrenNode)) {\n    pathToChildren =\n      containerType === CONTAINER_TYPE.EDITOR_SCALE_SQUARE\n        ? [...pathToChildren, displayName]\n        : pathToChildren\n    widgetInfo.childrenNode.map((childNode) => {\n      if (!childrenNodeDSL) childrenNodeDSL = []\n      const child = newGenerateChildrenComponentNode(\n        childNode,\n        displayName,\n        pathToChildren,\n        scale,\n      )\n      childrenNodeDSL.push(child)\n    })\n  }\n\n  baseDSL = {\n    w: Math.floor(w * scale),\n    h,\n    minW,\n    minH,\n    x: Math.floor(x * scale),\n    y,\n    z: 0,\n    showName: showName,\n    type,\n    displayName: displayName,\n    containerType,\n    parentNode: parentNodeDisplayName,\n    childrenNode: childrenNodeDSL,\n    version,\n    props: props ?? {},\n  }\n  if (baseDSL.type === \"LIST_WIDGET\" || baseDSL.type === \"GRID_LIST_WIDGET\") {\n    baseDSL = transformListWidget(baseDSL)\n  }\n  return baseDSL\n}\n\nexport const newGenerateChildrenComponentNode = (\n  widgetInfo: Omit<WidgetConfig, \"icon\" | \"sessionType\" | \"keywords\">,\n  parentNodeDisplayName: string,\n  pathToChildren: string[] = [],\n  scale: number = 1,\n): ComponentTreeNode => {\n  if (widgetInfo.type === \"CANVAS\") {\n    const realDisplayName = DisplayNameGenerator.generateDisplayName(\n      widgetInfo.type,\n      widgetInfo.displayName,\n    )\n    let childrenNodeDSL: ComponentTreeNode[] = []\n    if (\n      Array.isArray(widgetInfo.childrenNode) &&\n      widgetInfo.childrenNode.length > 0\n    ) {\n      widgetInfo.childrenNode.map((childNode) => {\n        if (!childrenNodeDSL) childrenNodeDSL = []\n        const child = newGenerateChildrenComponentNode(\n          childNode,\n          realDisplayName,\n          pathToChildren,\n          scale,\n        )\n        childrenNodeDSL.push(child)\n      })\n    }\n    return {\n      w: widgetInfo.w,\n      h: widgetInfo.h,\n      minW: DEFAULT_MIN_COLUMN,\n      minH: widgetInfo.minH as number,\n      x: -1,\n      y: -1,\n      z: 0,\n      showName: widgetInfo.displayName,\n      type: widgetInfo.type,\n      containerType: widgetInfo.containerType as CONTAINER_TYPE,\n      parentNode: parentNodeDisplayName,\n      childrenNode: childrenNodeDSL,\n      displayName: realDisplayName,\n      props: {},\n      version: widgetInfo.version,\n    }\n  }\n  const layoutInfo = generateWidgetLayoutInfo(\n    widgetInfo.type,\n    widgetInfo.displayName,\n    widgetInfo.containerType,\n  )\n\n  return generateComponentNodeByWidgetInfo(\n    layoutInfo?.displayName!,\n    widgetInfo,\n    parentNodeDisplayName,\n    pathToChildren,\n    scale,\n  )\n}\n\nexport const newGenerateComponentNode = (\n  x: number,\n  y: number,\n  defaultW: number,\n  widgetType: WidgetType,\n  displayName: string,\n  parentNodeDisplayName: string,\n  pathToChildren: string[] = [],\n  scale: number = 1,\n) => {\n  let baseDSL: ComponentTreeNode\n  const baseConfig = widgetBuilder(widgetType).config\n  let childrenNodeDSL: ComponentTreeNode[] = []\n  const {\n    defaults,\n    w,\n    h,\n    minW = DEFAULT_MIN_COLUMN,\n    minH = 3,\n    type,\n    displayName: showName,\n    containerType = CONTAINER_TYPE.EDITOR_SCALE_SQUARE,\n    version,\n  } = baseConfig\n  let props: Record<string, any> | undefined = {}\n  if (typeof defaults === \"function\") {\n    props = klona(defaults())\n  } else {\n    props = klona(defaults)\n  }\n  if (isObject(props) && Object.hasOwn(props, \"formDataKey\")) {\n    props.formDataKey = `{{${displayName}.displayName}}`\n  }\n\n  if (\n    isObject(props) &&\n    props.hasOwnProperty(\"events\") &&\n    Array.isArray(props.events)\n  ) {\n    props.events = props.events.map((event) => {\n      if (event.actionType !== \"widget\") {\n        return event\n      } else {\n        return {\n          ...event,\n          widgetID: pathToChildren[pathToChildren.length - 1] || \"unknown\",\n        }\n      }\n    })\n  }\n\n  if (baseConfig.childrenNode && Array.isArray(baseConfig.childrenNode)) {\n    pathToChildren =\n      containerType === CONTAINER_TYPE.EDITOR_SCALE_SQUARE\n        ? [...pathToChildren, displayName]\n        : pathToChildren\n    baseConfig.childrenNode.map((childNode) => {\n      if (!childrenNodeDSL) childrenNodeDSL = []\n      const child = newGenerateChildrenComponentNode(\n        childNode,\n        displayName,\n        pathToChildren,\n        scale,\n      )\n      childrenNodeDSL.push(child)\n    })\n  }\n\n  baseDSL = {\n    w: type === \"MODAL_WIDGET\" ? w : defaultW,\n    h,\n    minW,\n    minH,\n    x,\n    y,\n    z: 0,\n    showName: showName,\n    type,\n    displayName: displayName,\n    containerType,\n    parentNode: parentNodeDisplayName,\n    childrenNode: childrenNodeDSL,\n    props: props ?? {},\n    version,\n  }\n  if (baseDSL.type === \"LIST_WIDGET\" || baseDSL.type === \"GRID_LIST_WIDGET\") {\n    baseDSL = transformListWidget(baseDSL)\n  } else {\n    baseDSL = transFormTemplateDisplayName(baseDSL)\n  }\n  return baseDSL\n}\n\nfunction transformListWidget(baseDSL: ComponentTreeNode) {\n  const container = baseDSL.childrenNode[0]\n  let templateChildren = container.childrenNode\n  templateChildren.map((node) => {\n    return transFormTemplateDisplayName(node, baseDSL.displayName)\n  })\n  return baseDSL\n}\n\nfunction transFormTemplateDisplayName(\n  baseDSL: ComponentTreeNode,\n  targetDisplayName: string = baseDSL.displayName,\n) {\n  const props = baseDSL.props\n  if (props && Array.isArray(props.$dynamicAttrPaths)) {\n    props.$dynamicAttrPaths.forEach((path) => {\n      const originValue = get(baseDSL, `props.${path}`, \"\")\n      const finalValue = originValue.replace(\n        TEMPLATE_DISPLAYNAME_KEY,\n        targetDisplayName,\n      )\n      set(baseDSL, `props.${path}`, finalValue)\n    })\n  }\n  return baseDSL\n}\n"
  },
  {
    "path": "apps/builder/src/utils/generators/generateDisplayName.ts",
    "content": "// string for component\nimport { ActionContent, ComponentTreeNode } from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { Connection, getTextMessagePayload } from \"@/api/ws\"\nimport { TextSignal, TextTarget } from \"@/api/ws/textSignal\"\n\nexport const ADD_DISPLAY_NAME = \"addDisplayName\"\nexport const REMOVE_DISPLAY_NAME = \"removeDisplayName\"\nexport const UPDATE_DISPLAY_NAME = \"updateDisplayName\"\nexport const GENERATE_OR_UPDATE_DISPLAYNAME = \"generateOrUpdateDisplayName\"\n\nexport const PLACEHOLDER_DISPLAYNAME = [\"document\", \"utils\"]\n\nexport class DisplayNameGenerator {\n  static displayNameList = new Set<string>(PLACEHOLDER_DISPLAYNAME)\n\n  static appId: string = \"\"\n  static teamID: string = \"\"\n  static uid: string = \"\"\n\n  static isAlreadyGenerate(displayName: string): boolean {\n    return this.displayNameList.has(displayName)\n  }\n\n  static initApp(appId: string, teamID: string, uid: string) {\n    this.appId = appId\n    this.teamID = teamID\n    this.uid = uid\n  }\n\n  // use when create success\n  static generateDisplayName(type: string, showName?: string): string {\n    let index = 1\n    let name = `${showName || type}${index}`\n    // check cache map\n    while (this.isAlreadyGenerate(name)) {\n      index = index + 1\n      name = `${showName || type}${index}`\n    }\n    this.displayNameList.add(name)\n    Connection.getTextRoom(\"app\", this.appId)?.send(\n      getTextMessagePayload(\n        TextSignal.BROADCAST_ONLY,\n        TextTarget.DISPLAY_NAME,\n        true,\n        { type: ADD_DISPLAY_NAME, payload: [name] },\n        this.teamID,\n        this.uid,\n        [],\n      ),\n    )\n    return name\n  }\n\n  static updateDisplayNameList(\n    componentNode: ComponentTreeNode,\n    actionList: ActionItem<ActionContent>[],\n  ) {\n    this.displayNameList = new Set<string>(PLACEHOLDER_DISPLAYNAME)\n    actionList.forEach((action) => {\n      this.displayNameList.add(action.displayName)\n    })\n    this.addComponentDisplayName(componentNode)\n    const globalData = componentNode.props?.globalData ?? {}\n    Object.keys(globalData).forEach((key) => {\n      this.displayNameList.add(key)\n    })\n  }\n\n  static addComponentDisplayName(componentNode: ComponentTreeNode) {\n    this.displayNameList.add(componentNode.displayName)\n    componentNode.childrenNode?.forEach((child) => {\n      this.addComponentDisplayName(child)\n    })\n  }\n\n  static addDisplayNames(displayNames: string[]) {\n    displayNames.forEach((displayName) => {\n      this.displayNameList.add(displayName)\n    })\n  }\n\n  static updateOrGenerateDisplayName(displayName: string) {\n    if (this.displayNameList.has(displayName)) {\n      return this.generateDisplayName(displayName)\n    }\n    this.displayNameList.add(displayName)\n    Connection.getTextRoom(\"app\", this.appId)?.send(\n      getTextMessagePayload(\n        TextSignal.BROADCAST_ONLY,\n        TextTarget.DISPLAY_NAME,\n        true,\n        {\n          type: GENERATE_OR_UPDATE_DISPLAYNAME,\n          payload: displayName,\n        },\n        this.teamID,\n        this.uid,\n        [],\n      ),\n    )\n    return displayName\n  }\n\n  static removeDisplayName(displayName: string) {\n    this.displayNameList.delete(displayName)\n    Connection.getTextRoom(\"app\", this.appId)?.send(\n      getTextMessagePayload(\n        TextSignal.BROADCAST_ONLY,\n        TextTarget.DISPLAY_NAME,\n        true,\n        { type: REMOVE_DISPLAY_NAME, payload: [displayName] },\n        this.teamID,\n        this.uid,\n        [],\n      ),\n    )\n  }\n\n  static removeDisplayNameMulti(displayNames: string[]) {\n    displayNames.forEach((displayName) => {\n      this.displayNameList.delete(displayName)\n    })\n    Connection.getTextRoom(\"app\", this.appId)?.send(\n      getTextMessagePayload(\n        TextSignal.BROADCAST_ONLY,\n        TextTarget.DISPLAY_NAME,\n        true,\n        { type: REMOVE_DISPLAY_NAME, payload: displayNames },\n        this.teamID,\n        this.uid,\n        [],\n      ),\n    )\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/generators/generatePageOrSectionConfig.ts",
    "content": "import {\n  ComponentTreeNode,\n  ModalSectionNode,\n  SECTION_POSITION,\n  SectionTreeNode,\n} from \"@illa-public/public-types\"\nimport { CONTAINER_TYPE, PADDING_MODE } from \"@illa-public/public-types\"\nimport { v4 } from \"uuid\"\nimport { getColor } from \"@illa-design/react\"\nimport {\n  DEFAULT_ASIDE_COLUMNS_NUMBER,\n  DEFAULT_BODY_COLUMNS_NUMBER,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport {\n  PageNode,\n  PageNodeProps,\n} from \"@/redux/currentApp/components/componentsState\"\nimport { newGenerateComponentNode } from \"./generateComponentNode\"\nimport { DisplayNameGenerator } from \"./generateDisplayName\"\n\nexport type SectionNodeType =\n  | \"bodySection\"\n  | \"leftSection\"\n  | \"rightSection\"\n  | \"headerSection\"\n  | \"footerSection\"\n  | \"modalSection\"\n\nexport const generateSectionContainerConfig = (\n  parentNode: string,\n  showName: string,\n): ComponentTreeNode => {\n  const displayName = DisplayNameGenerator.generateDisplayName(\n    \"CONTAINER_NODE\",\n    `${parentNode}-${showName}`,\n  )\n  return {\n    displayName: displayName,\n    parentNode: parentNode,\n    showName: showName,\n    type: \"CONTAINER_NODE\",\n    containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n    h: 0,\n    w: 0,\n    minH: 0,\n    minW: 0,\n    x: -1,\n    y: -1,\n    z: 0,\n    childrenNode: [],\n    version: 0,\n    props: {},\n  }\n}\n\nconst generateSectionsChildrenMenuComponentNode = (\n  parentDisplayName: string,\n) => {\n  const displayName = DisplayNameGenerator.generateDisplayName(\n    \"MENU_WIDGET\",\n    \"menu\",\n  )\n  const menuNode = newGenerateComponentNode(\n    0,\n    0,\n    32,\n    \"MENU_WIDGET\",\n    displayName,\n    parentDisplayName,\n  )\n  menuNode.props!.$dynamicAttrPaths = [\"dataSources\", \"selectedValues\"]\n  return menuNode\n}\n\nexport const generateSectionConfig = (\n  parentNode: string,\n  showName: SectionNodeType,\n  bodySubpaths: string[] = [\"sub-page1\"],\n): SectionTreeNode => {\n  const displayName = DisplayNameGenerator.generateDisplayName(\n    \"SECTION_NODE\",\n    showName,\n  )\n  const childrenNode = generateSectionContainerConfig(\n    displayName,\n    `${showName}Container`,\n  )\n\n  if (showName === \"headerSection\") {\n    const menuNode = generateSectionsChildrenMenuComponentNode(\n      childrenNode.displayName,\n    )\n    childrenNode.childrenNode.push(menuNode)\n  }\n\n  if (showName === \"leftSection\") {\n    const menuNode = generateSectionsChildrenMenuComponentNode(\n      childrenNode.displayName,\n    )\n    menuNode.w = 8\n    menuNode.props!.mode = \"vertical\"\n    childrenNode.childrenNode.push(menuNode)\n  }\n\n  const defaultSubPath =\n    Array.isArray(bodySubpaths) && bodySubpaths.length > 0\n      ? bodySubpaths[0]\n      : \"sub-page1\"\n\n  const result: SectionTreeNode = {\n    displayName: `${displayName}`,\n    parentNode: parentNode,\n    showName: showName,\n    type: \"SECTION_NODE\",\n    containerType: CONTAINER_TYPE.EDITOR_LAYOUT_SQUARE,\n    h: 0,\n    w: 0,\n    minH: 0,\n    minW: 0,\n    x: -1,\n    y: -1,\n    z: 0,\n    version: 0,\n    props: {\n      currentViewIndex: 0,\n      viewSortedKey: [childrenNode.displayName],\n      defaultViewKey: defaultSubPath,\n      sectionViewConfigs: [\n        {\n          id: v4(),\n          viewDisplayName: childrenNode.displayName,\n          key: defaultSubPath,\n          path: defaultSubPath,\n        },\n      ],\n      style: {},\n    },\n    childrenNode: [childrenNode],\n  }\n  if (showName === \"bodySection\") {\n    result.props.style = {\n      padding: {\n        mode: PADDING_MODE.ALL,\n        size: \"24\",\n      },\n    }\n  }\n  if (showName !== \"bodySection\") {\n    result.props.style = {\n      dividerColor: getColor(\"grayBlue\", \"08\"),\n    }\n  }\n  return result\n}\n\nexport const generateModalSectionConfig = (\n  parentNode: string,\n  showName: SectionNodeType,\n): ModalSectionNode => {\n  const displayName = DisplayNameGenerator.generateDisplayName(\n    \"MODAL_SECTION_NODE\",\n    showName,\n  )\n\n  return {\n    displayName: displayName,\n    parentNode: parentNode,\n    showName: showName,\n    type: \"MODAL_SECTION_NODE\",\n    containerType: CONTAINER_TYPE.EDITOR_LAYOUT_SQUARE,\n    h: 0,\n    w: 0,\n    minH: 0,\n    minW: 0,\n    x: -1,\n    y: -1,\n    z: 0,\n    version: 0,\n    props: {},\n    childrenNode: [],\n  }\n}\n\nexport const defaultPageProps: PageNodeProps = {\n  canvasSize: \"auto\",\n  canvasWidth: 100,\n  layout: \"default\",\n  leftPosition: SECTION_POSITION.NONE,\n  rightPosition: SECTION_POSITION.NONE,\n  hasFooter: false,\n  hasHeader: false,\n  hasLeft: false,\n  hasRight: false,\n  leftWidth: 0,\n  rightWidth: 0,\n  topHeight: 0,\n  bottomHeight: 0,\n  isLeftFixed: true,\n  isRightFixed: true,\n  isHeaderFixed: true,\n  isFooterFixed: true,\n  showLeftFoldIcon: false,\n  showRightFoldIcon: false,\n  leftColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n  rightColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n  headerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n  footerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n  bodyColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n}\n\nexport const generatePageConfig = (): PageNode => {\n  const displayName = DisplayNameGenerator.generateDisplayName(\n    \"PAGE_NODE\",\n    \"page\",\n  )\n  const childrenNode = generateSectionConfig(displayName, \"bodySection\")\n  const modalSectionNode = generateModalSectionConfig(\n    displayName,\n    \"modalSection\",\n  )\n  return {\n    displayName: displayName,\n    parentNode: \"root\",\n    showName: \"page\",\n    type: \"PAGE_NODE\",\n    containerType: CONTAINER_TYPE.EDITOR_PAGE_SQUARE,\n    h: 0,\n    w: 0,\n    minH: 0,\n    minW: 0,\n    x: -1,\n    y: -1,\n    z: 0,\n    version: 0,\n    props: defaultPageProps,\n    childrenNode: [childrenNode, modalSectionNode],\n  }\n}\n\nexport const generateDefaultLayoutConfig = (\n  currentDisplayName: string,\n): PageNode => {\n  const childrenNode = generateSectionConfig(currentDisplayName, \"bodySection\")\n  const modalSectionNode = generateModalSectionConfig(\n    currentDisplayName,\n    \"modalSection\",\n  )\n  return {\n    displayName: currentDisplayName,\n    parentNode: \"root\",\n    showName: \"page\",\n    type: \"PAGE_NODE\",\n    containerType: CONTAINER_TYPE.EDITOR_PAGE_SQUARE,\n    h: 0,\n    w: 0,\n    minH: 0,\n    minW: 0,\n    x: -1,\n    y: -1,\n    z: 0,\n    version: 0,\n    props: {\n      canvasSize: \"auto\",\n      canvasWidth: 100,\n      layout: \"default\",\n      leftPosition: SECTION_POSITION.NONE,\n      rightPosition: SECTION_POSITION.NONE,\n      hasFooter: false,\n      hasHeader: false,\n      hasLeft: false,\n      hasRight: false,\n      leftWidth: 0,\n      rightWidth: 0,\n      topHeight: 0,\n      bottomHeight: 0,\n      isLeftFixed: true,\n      isRightFixed: true,\n      isHeaderFixed: true,\n      isFooterFixed: true,\n      showLeftFoldIcon: false,\n      showRightFoldIcon: false,\n      leftColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n      rightColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n      headerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n      footerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n      bodyColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n    },\n    childrenNode: [childrenNode, modalSectionNode],\n  }\n}\n\nexport const generatePresetALayoutConfig = (\n  currentDisplayName: string,\n): PageNode => {\n  const leftSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"leftSection\",\n  )\n  const bodySectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"bodySection\",\n  )\n  const modalSectionNode = generateModalSectionConfig(\n    currentDisplayName,\n    \"modalSection\",\n  )\n\n  return {\n    displayName: currentDisplayName,\n    parentNode: \"root\",\n    showName: \"page\",\n    type: \"PAGE_NODE\",\n    containerType: CONTAINER_TYPE.EDITOR_PAGE_SQUARE,\n    h: 0,\n    w: 0,\n    minH: 0,\n    minW: 0,\n    x: -1,\n    y: -1,\n    z: 0,\n    version: 0,\n    props: {\n      canvasSize: \"auto\",\n      canvasWidth: 100,\n      layout: \"presetA\",\n      leftPosition: SECTION_POSITION.FULL,\n      rightPosition: SECTION_POSITION.NONE,\n      hasFooter: false,\n      hasHeader: false,\n      hasLeft: true,\n      hasRight: false,\n      leftWidth: 20,\n      rightWidth: 0,\n      topHeight: 0,\n      bottomHeight: 0,\n      isLeftFixed: true,\n      isRightFixed: true,\n      isHeaderFixed: true,\n      isFooterFixed: true,\n      showLeftFoldIcon: false,\n      showRightFoldIcon: false,\n      leftColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n      rightColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n      headerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n      footerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n      bodyColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n    },\n    childrenNode: [leftSectionNode, bodySectionNode, modalSectionNode],\n  }\n}\n\nexport const generatePresetBLayoutConfig = (\n  currentDisplayName: string,\n): PageNode => {\n  const headerSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"headerSection\",\n  )\n  const bodySectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"bodySection\",\n  )\n  const footerSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"footerSection\",\n  )\n  const modalSectionNode = generateModalSectionConfig(\n    currentDisplayName,\n    \"modalSection\",\n  )\n\n  return {\n    displayName: currentDisplayName,\n    parentNode: \"root\",\n    showName: \"page\",\n    type: \"PAGE_NODE\",\n    containerType: CONTAINER_TYPE.EDITOR_PAGE_SQUARE,\n    h: 0,\n    w: 0,\n    minH: 0,\n    minW: 0,\n    x: -1,\n    y: -1,\n    z: 0,\n    version: 0,\n    props: {\n      canvasSize: \"auto\",\n      canvasWidth: 100,\n      layout: \"presetB\",\n      leftPosition: SECTION_POSITION.NONE,\n      rightPosition: SECTION_POSITION.NONE,\n      hasFooter: true,\n      hasHeader: true,\n      hasLeft: false,\n      hasRight: false,\n      leftWidth: 0,\n      rightWidth: 0,\n      topHeight: 96,\n      bottomHeight: 96,\n      isLeftFixed: true,\n      isRightFixed: true,\n      isHeaderFixed: true,\n      isFooterFixed: true,\n      showLeftFoldIcon: false,\n      showRightFoldIcon: false,\n      leftColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n      rightColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n      headerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n      footerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n      bodyColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n    },\n    childrenNode: [\n      headerSectionNode,\n      bodySectionNode,\n      footerSectionNode,\n      modalSectionNode,\n    ],\n  }\n}\n\nexport const generatePresetCLayoutConfig = (\n  currentDisplayName: string,\n): PageNode => {\n  const headerSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"headerSection\",\n  )\n  const leftSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"leftSection\",\n  )\n  const bodySectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"bodySection\",\n  )\n  const footerSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"footerSection\",\n  )\n  const modalSectionNode = generateModalSectionConfig(\n    currentDisplayName,\n    \"modalSection\",\n  )\n\n  return {\n    displayName: currentDisplayName,\n    parentNode: \"root\",\n    showName: \"page\",\n    type: \"PAGE_NODE\",\n    containerType: CONTAINER_TYPE.EDITOR_PAGE_SQUARE,\n    h: 0,\n    w: 0,\n    minH: 0,\n    minW: 0,\n    x: -1,\n    y: -1,\n    z: 0,\n    version: 0,\n    props: {\n      canvasSize: \"auto\",\n      canvasWidth: 100,\n      layout: \"presetC\",\n      leftPosition: SECTION_POSITION.BOTTOM,\n      rightPosition: SECTION_POSITION.NONE,\n      hasFooter: true,\n      hasHeader: true,\n      hasLeft: true,\n      hasRight: false,\n      leftWidth: 20,\n      rightWidth: 0,\n      topHeight: 96,\n      bottomHeight: 96,\n      isLeftFixed: true,\n      isRightFixed: true,\n      isHeaderFixed: true,\n      isFooterFixed: true,\n      showLeftFoldIcon: false,\n      showRightFoldIcon: false,\n    },\n    childrenNode: [\n      headerSectionNode,\n      leftSectionNode,\n      bodySectionNode,\n      footerSectionNode,\n      modalSectionNode,\n    ],\n  }\n}\n\nexport const generatePresetDLayoutConfig = (\n  currentDisplayName: string,\n): PageNode => {\n  const headerSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"headerSection\",\n  )\n  const leftSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"leftSection\",\n  )\n  const rightSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"rightSection\",\n  )\n  const bodySectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"bodySection\",\n  )\n  const footerSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"footerSection\",\n  )\n  const modalSectionNode = generateModalSectionConfig(\n    currentDisplayName,\n    \"modalSection\",\n  )\n\n  return {\n    displayName: currentDisplayName,\n    parentNode: \"root\",\n    showName: \"page\",\n    type: \"PAGE_NODE\",\n    containerType: CONTAINER_TYPE.EDITOR_PAGE_SQUARE,\n    h: 0,\n    w: 0,\n    minH: 0,\n    minW: 0,\n    x: -1,\n    y: -1,\n    z: 0,\n    version: 0,\n    props: {\n      canvasSize: \"auto\",\n      canvasWidth: 100,\n      layout: \"presetD\",\n      leftPosition: SECTION_POSITION.BOTTOM,\n      rightPosition: SECTION_POSITION.BOTTOM,\n      hasFooter: true,\n      hasHeader: true,\n      hasLeft: true,\n      hasRight: true,\n      leftWidth: 20,\n      rightWidth: 20,\n      topHeight: 96,\n      bottomHeight: 96,\n      isLeftFixed: true,\n      isRightFixed: true,\n      isHeaderFixed: true,\n      isFooterFixed: true,\n      showLeftFoldIcon: false,\n      showRightFoldIcon: false,\n      leftColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n      rightColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n      headerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n      footerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n      bodyColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n    },\n    childrenNode: [\n      headerSectionNode,\n      rightSectionNode,\n      leftSectionNode,\n      bodySectionNode,\n      footerSectionNode,\n      modalSectionNode,\n    ],\n  }\n}\n\nexport const generatePresetELayoutConfig = (\n  currentDisplayName: string,\n): PageNode => {\n  const headerSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"headerSection\",\n  )\n  const leftSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"leftSection\",\n  )\n  const bodySectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"bodySection\",\n  )\n  const footerSectionNode = generateSectionConfig(\n    currentDisplayName,\n    \"footerSection\",\n  )\n  const modalSectionNode = generateModalSectionConfig(\n    currentDisplayName,\n    \"modalSection\",\n  )\n\n  return {\n    displayName: currentDisplayName,\n    parentNode: \"root\",\n    showName: \"page\",\n    type: \"PAGE_NODE\",\n    containerType: CONTAINER_TYPE.EDITOR_PAGE_SQUARE,\n    h: 0,\n    w: 0,\n    minH: 0,\n    minW: 0,\n    x: -1,\n    y: -1,\n    z: 0,\n    version: 0,\n    props: {\n      canvasSize: \"auto\",\n      canvasWidth: 100,\n      layout: \"presetE\",\n      leftPosition: SECTION_POSITION.FULL,\n      rightPosition: SECTION_POSITION.NONE,\n      hasFooter: true,\n      hasHeader: true,\n      hasLeft: true,\n      hasRight: false,\n      leftWidth: 20,\n      rightWidth: 20,\n      topHeight: 96,\n      bottomHeight: 96,\n      isLeftFixed: true,\n      isRightFixed: true,\n      isHeaderFixed: true,\n      isFooterFixed: true,\n      showLeftFoldIcon: false,\n      showRightFoldIcon: false,\n      leftColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n      rightColumns: DEFAULT_ASIDE_COLUMNS_NUMBER,\n      headerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n      footerColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n      bodyColumns: DEFAULT_BODY_COLUMNS_NUMBER,\n    },\n    childrenNode: [\n      headerSectionNode,\n      leftSectionNode,\n      bodySectionNode,\n      footerSectionNode,\n      modalSectionNode,\n    ],\n  }\n}\n\nexport const layoutValueMapGenerateConfig = {\n  default: generateDefaultLayoutConfig,\n  presetA: generatePresetALayoutConfig,\n  presetB: generatePresetBLayoutConfig,\n  presetC: generatePresetCLayoutConfig,\n  presetD: generatePresetDLayoutConfig,\n  presetE: generatePresetELayoutConfig,\n}\n"
  },
  {
    "path": "apps/builder/src/utils/mediaSourceLoad/index.tsx",
    "content": "import {\n  HTTP_REQUEST_PUBLIC_BASE_URL,\n  PUBLIC_DRIVE_REQUEST_PREFIX,\n  publicDriveRequest,\n} from \"@illa-public/illa-net\"\nimport {\n  CollarModalType,\n  handleCollaPurchaseError,\n} from \"@illa-public/upgrade-modal\"\nimport { FC, createContext, useCallback, useRef } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport { Inject, MediaSourceLoadProviderProps } from \"./interface\"\nimport { getReportElementByWidget } from \"./utils\"\n\nexport const MediaSourceLoadContext = createContext<Inject>({} as Inject)\n\nexport const MediaSourceLoadProvider: FC<MediaSourceLoadProviderProps> = ({\n  children,\n}) => {\n  const isShowedCollaError = useRef<boolean>(false)\n  const isProductionMode = useSelector(getIsILLAProductMode)\n\n  const sourceLoadErrorHandler = useCallback(\n    async (sourceURL: string | undefined, widgetType: string) => {\n      if (isShowedCollaError.current || !sourceURL) return\n      let prefix = HTTP_REQUEST_PUBLIC_BASE_URL + PUBLIC_DRIVE_REQUEST_PREFIX\n      if (!sourceURL.includes(prefix)) return\n      try {\n        await publicDriveRequest({\n          url: sourceURL.replace(prefix, \"\"),\n          method: \"GET\",\n        })\n      } catch (e) {\n        let res: boolean = false\n        if (!isShowedCollaError.current) {\n          res = handleCollaPurchaseError(\n            e,\n            CollarModalType.TRAFFIC,\n            getReportElementByWidget(widgetType, isProductionMode)!,\n          )\n        }\n        if (res) {\n          isShowedCollaError.current = true\n        }\n      }\n    },\n    [isProductionMode],\n  )\n  return (\n    <MediaSourceLoadContext.Provider value={{ sourceLoadErrorHandler }}>\n      {children}\n    </MediaSourceLoadContext.Provider>\n  )\n}\n\nMediaSourceLoadContext.displayName = \"MediaSourceLoadContext\"\n"
  },
  {
    "path": "apps/builder/src/utils/mediaSourceLoad/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface Inject {\n  sourceLoadErrorHandler: (\n    sourceURL: string | undefined,\n    widgetType: string,\n  ) => void\n}\nexport interface MediaSourceLoadProviderProps {\n  children: ReactNode\n}\n"
  },
  {
    "path": "apps/builder/src/utils/mediaSourceLoad/utils.ts",
    "content": "export const getReportElementByWidget = (\n  widgetType: string,\n  isProductionMode?: boolean,\n) => {\n  let prefix = isProductionMode ? \"deploy_\" : \"builder_editor_\"\n  switch (widgetType) {\n    case \"IMAGE_WIDGET\":\n      return `${prefix}traffic_not_enough_image`\n    case \"CAROUSEL_WIDGET\":\n      return `${prefix}traffic_not_enough_carousel`\n    case \"VIDEO_WIDGET\":\n      return `${prefix}traffic_not_enough_video`\n    case \"AUDIO_WIDGET\":\n      return `${prefix}traffic_not_enough_audio`\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/mixpanelHelper/index.tsx",
    "content": "import {\n  ILLAMixpanel,\n  ILLAProperties,\n  ILLA_MIXPANEL_BUILDER_PAGE_NAME,\n  ILLA_MIXPANEL_EVENT_TYPE,\n  ILLA_PAGE_NAME,\n} from \"@illa-public/mixpanel-utils\"\nimport { getCurrentTeamInfo, getCurrentUser } from \"@illa-public/user-data\"\nimport {\n  getIllaMode,\n  getIsILLAProductMode,\n} from \"@/redux/config/configSelector\"\nimport { getAppInfo } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport { getRootComponentNode } from \"@/redux/currentApp/components/componentsSelector\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { getGuideInfo } from \"@/redux/guide/guideSelector\"\nimport { ILLARoute } from \"@/router\"\nimport store from \"@/store\"\n\nconst getInfoFromUrl = () => {\n  const { state } = ILLARoute\n  const { matches } = state\n  const match = matches[0]?.params || {}\n  return {\n    appId: match.appId,\n    teamIdentifier: match.teamIdentifier,\n  }\n}\n\nconst getPreviewInfo = () => {\n  const rootState = store.getState()\n  const rootNode = getRootComponentNode(rootState)\n  const isProduction = getIsILLAProductMode(rootState)\n  const rootProps = rootNode?.props\n  if (!rootProps)\n    return {\n      w: \"auto\",\n      h: \"auto\",\n    }\n  const { viewportWidth = \"auto\", viewportHeight = \"auto\" } = rootProps\n  return {\n    w: isProduction ? \"auto\" : viewportWidth,\n    h: isProduction ? \"auto\" : viewportHeight,\n  }\n}\n\nconst getPageInfo = () => {\n  const rootState = store.getState()\n  const executionResult = getExecutionResult(rootState)\n  const rootExecutionProps = executionResult.root\n  let result: Record<string, unknown>[] = []\n  if (!rootExecutionProps) return result\n  const { pageSortedKey, homepageDisplayName } = rootExecutionProps\n  if (!Array.isArray(pageSortedKey) || pageSortedKey.length === 0) return result\n  pageSortedKey.forEach((key) => {\n    const pageInfo = executionResult[key]\n    if (!pageInfo) return\n    const childrenNode = (pageInfo.$childrenNode || []) as string[]\n    let leftViews: number = 0\n    let rightViews: number = 0\n    let headerViews: number = 0\n    let footerViews: number = 0\n    let bodyViews: number = 0\n    childrenNode.forEach((node) => {\n      const nodeInfo = executionResult[node]\n      if (!nodeInfo) return\n      const { displayName, viewSortedKey } = nodeInfo\n      const viewsNumber = Array.isArray(viewSortedKey)\n        ? viewSortedKey.length\n        : 0\n      if (displayName.startsWith(\"left\")) {\n        leftViews = viewsNumber\n      } else if (displayName.startsWith(\"right\")) {\n        rightViews = viewsNumber\n      } else if (displayName.startsWith(\"header\")) {\n        headerViews = viewsNumber\n      } else if (displayName.startsWith(\"footer\")) {\n        footerViews = viewsNumber\n      } else if (displayName.startsWith(\"body\")) {\n        bodyViews = viewsNumber\n      }\n    })\n    const item = {\n      homepage: (homepageDisplayName || pageSortedKey[0]) === key,\n      left: leftViews,\n      right: rightViews,\n      header: headerViews,\n      footer: footerViews,\n      body: bodyViews,\n    }\n    result.push(item)\n  })\n  return result\n}\n\nconst getTeamInfo = () => {\n  const teamInfo = getCurrentTeamInfo(store.getState())\n  return {\n    role: teamInfo?.myRole || \"-1\",\n  }\n}\n\nconst getAppType = () => {\n  const rootState = store.getState()\n  const guide = getGuideInfo(rootState)\n  return guide.isOpen ? \"Onboarding app\" : \"Normal\"\n}\n\nconst getAppIsPublish = () => {\n  const rootState = store.getState()\n  const appInfo = getAppInfo(rootState)\n  return appInfo.deployed\n}\n\nconst getAppIsPublic = () => {\n  const rootState = store.getState()\n  const appInfo = getAppInfo(rootState)\n  return appInfo.config.public\n}\n\nconst getUserID = () => {\n  const userInfo = getCurrentUser(store.getState())\n  return userInfo?.userID || \"\"\n}\n\nconst getAPPMode = () => {\n  const rootState = store.getState()\n  const appMode = getIllaMode(rootState)\n  return appMode\n}\n\nconst getPageName = () => {\n  const appMode = getAPPMode()\n  switch (appMode) {\n    case \"edit\": {\n      return ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR\n    }\n    case \"preview\": {\n      return ILLA_MIXPANEL_BUILDER_PAGE_NAME.PREVIEW\n    }\n    case \"production\": {\n      return ILLA_MIXPANEL_BUILDER_PAGE_NAME.DEPLOY\n    }\n    default: {\n      return ILLA_MIXPANEL_BUILDER_PAGE_NAME.EDITOR\n    }\n  }\n}\n\nexport const track = (\n  event: ILLA_MIXPANEL_EVENT_TYPE,\n  pageName: ILLA_PAGE_NAME,\n  properties: Omit<ILLAProperties, \"parameter11\" | \"team_id\" | \"page\"> = {},\n) => {\n  const { teamIdentifier } = getInfoFromUrl()\n  const { role } = getTeamInfo()\n  const userID = getUserID()\n  ILLAMixpanel.track(event, {\n    ...properties,\n    page: pageName,\n    user_id: userID,\n    parameter11: role,\n    team_id: teamIdentifier,\n  })\n}\n\nexport const trackInEditor = (\n  event: ILLA_MIXPANEL_EVENT_TYPE,\n  properties: Omit<\n    ILLAProperties,\n    | \"parameter5\"\n    | \"parameter6\"\n    | \"parameter7\"\n    | \"parameter8\"\n    | \"parameter9\"\n    | \"parameter10\"\n    | \"parameter11\"\n    | \"team_id\"\n    | \"page\"\n    | \"user_id\"\n  > = {},\n) => {\n  const previewInfo = getPreviewInfo()\n  const pageInfo = getPageInfo()\n  const appType = getAppType()\n  const isPublish = getAppIsPublish()\n  const isPublic = getAppIsPublic()\n  const pageName = getPageName()\n  const { appId } = getInfoFromUrl()\n  track(event, pageName, {\n    ...properties,\n    parameter5: appId,\n    parameter6: previewInfo,\n    parameter7: pageInfo,\n    parameter8: appType,\n    parameter9: isPublish,\n    parameter10: isPublic,\n  })\n}\n\nexport const trackPageDurationStart = () => {\n  ILLAMixpanel.pageTimeEvent()\n}\n\nexport const trackPageDurationEnd = (pageName: ILLA_PAGE_NAME) => {\n  const { teamIdentifier } = getInfoFromUrl()\n\n  ILLAMixpanel.trackTimeEvent(pageName, teamIdentifier ?? \"-1\")\n}\n\nexport const resourceContextHelper = (parameter1: string) => {\n  return (\n    event: ILLA_MIXPANEL_EVENT_TYPE,\n    pageName: ILLA_PAGE_NAME,\n    properties: Omit<ILLAProperties, \"page\">,\n  ) => {\n    const mergeParam = parameter1 ? { ...properties, parameter1 } : properties\n    track(event, pageName, mergeParam)\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/navigate/index.ts",
    "content": "export const handleLinkOpen = (link: string) => {\n  window.open(link, \"_blank\")\n}\n\nexport const openDiscord = () => {\n  handleLinkOpen(\"https://discord.com/invite/illacloud\")\n}\n"
  },
  {
    "path": "apps/builder/src/utils/routerHelper.ts",
    "content": "import { ILLARoute } from \"@/router\"\n\nexport const getParamsFromIllaRoute = (key: string) => {\n  const routerParams = ILLARoute.state.matches[0].params\n  return routerParams[key]\n}\n"
  },
  {
    "path": "apps/builder/src/utils/screen/index.ts",
    "content": "export const MOBILE_SCREEN_WIDTH = 780\n\nexport const isMobileByWindowSize = (currentWidth: number) => {\n  return currentWidth < MOBILE_SCREEN_WIDTH\n}\n"
  },
  {
    "path": "apps/builder/src/utils/shortcut/index.tsx",
    "content": "import { isILLAAPiError } from \"@illa-public/illa-net\"\nimport { ILLA_MIXPANEL_EVENT_TYPE } from \"@illa-public/mixpanel-utils\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { getCurrentTeamInfo, getPlanUtils } from \"@illa-public/user-data\"\nimport { canUseUpgradeFeature } from \"@illa-public/user-role-utils\"\nimport { isCloudVersion } from \"@illa-public/utils\"\nimport { FC, ReactNode, useCallback, useEffect, useState } from \"react\"\nimport { useHotkeys } from \"react-hotkeys-hook\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { Key } from \"ts-key-enum\"\nimport { createModal, useMessage } from \"@illa-design/react\"\nimport { onDeleteActionItem } from \"@/page/App/components/Actions/api\"\nimport {\n  getIsILLAEditMode,\n  getSelectedAction,\n  getSelectedComponentDisplayNames,\n  isShowDot,\n} from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getActionItemByDisplayName } from \"@/redux/currentApp/action/actionSelector\"\nimport {\n  getComponentMap,\n  getOriginalGlobalDataNames,\n  searchComponentFromMap,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { takeSnapShot } from \"@/services/history\"\nimport store from \"@/store\"\nimport { CopyManager } from \"@/utils/copyManager\"\nimport { FocusManager } from \"@/utils/focusManager\"\nimport { trackInEditor } from \"@/utils/mixpanelHelper\"\nimport { ShortCutContext } from \"@/utils/shortcut/shortcutProvider\"\nimport IllaUndoRedoManager from \"@/utils/undoRedo/undo\"\nimport { isMAC } from \"@/utils/userAgent\"\nimport { DisplayNameGenerator } from \"../generators/generateDisplayName\"\n\nexport const Shortcut: FC<{ children: ReactNode }> = ({ children }) => {\n  const dispatch = useDispatch()\n  const { t } = useTranslation()\n  const message = useMessage()\n\n  const { appId } = useParams()\n\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const currentSelectedComponent = useSelector(getSelectedComponentDisplayNames)\n  const currentSelectedAction = useSelector(getSelectedAction)\n  const componentsMap = useSelector(getComponentMap)\n  const executionResult = useSelector(getExecutionResult)\n  const showShadows = useSelector(isShowDot)\n  const teamInfo = useSelector(getCurrentTeamInfo)\n  const upgradeModal = useUpgradeModal()\n\n  // shortcut\n  const [alreadyShowDeleteDialog, setAlreadyShowDeleteDialog] =\n    useState<boolean>(false)\n  const [saveLoading, setSaveLoading] = useState<boolean>(false)\n\n  const canUseBillingFeature = canUseUpgradeFeature(\n    teamInfo?.myRole,\n    getPlanUtils(teamInfo),\n    teamInfo?.totalTeamLicense?.teamLicensePurchased,\n    teamInfo?.totalTeamLicense?.teamLicenseAllPaid,\n  )\n\n  const showDeleteDialog = (\n    displayName: string[],\n    type?: \"widget\" | \"page\" | \"action\" | \"subpage\" | \"pageView\" | \"globalData\",\n    options?: Record<string, any>,\n  ) => {\n    const modal = createModal()\n    if (!alreadyShowDeleteDialog && displayName.length > 0) {\n      const textList = displayName.join(\", \").toString()\n      setAlreadyShowDeleteDialog(true)\n      const id = modal.show({\n        blockOkHide: true,\n        blockCancelHide: true,\n        title: t(\"editor.component.delete_title\", {\n          displayName: textList,\n        }),\n        children: t(\"editor.component.delete_content\", {\n          displayName: textList,\n        }),\n        cancelText: t(\"editor.component.cancel\"),\n        okText: t(\"editor.component.delete\"),\n        okButtonProps: {\n          colorScheme: \"red\",\n        },\n        closable: false,\n        onCancel: () => {\n          setAlreadyShowDeleteDialog(false)\n          modal.update(id, { visible: false })\n        },\n        onOk: () => {\n          switch (type) {\n            case \"page\": {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"delete_page_modal_delete\",\n              })\n              dispatch(\n                componentsActions.deletePageNodeReducer({\n                  displayName: displayName[0],\n                  originPageSortedKey: options?.originPageSortedKey || [],\n                }),\n              )\n              break\n            }\n            case \"widget\": {\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"component_delete_modal_delete\",\n                parameter3: options?.source || \"left_delete\",\n              })\n              dispatch(\n                componentsActions.deleteComponentNodeReducer({\n                  displayNames: displayName,\n                  source: options?.source || \"left_delete\",\n                }),\n              )\n              dispatch(configActions.clearSelectedComponent())\n              break\n            }\n            case \"action\": {\n              setAlreadyShowDeleteDialog(false)\n              modal.update(id, { okLoading: true })\n              for (let i = 0; i < displayName.length; i++) {\n                const action = getActionItemByDisplayName(\n                  store.getState(),\n                  displayName[i],\n                )\n                const globalDataNames = getOriginalGlobalDataNames(\n                  store.getState(),\n                )\n                if (action) {\n                  // fail to await @chenlongbo\n                  onDeleteActionItem(action)\n                }\n                if (globalDataNames.includes(displayName[i])) {\n                  dispatch(\n                    componentsActions.deleteGlobalStateByKeyReducer({\n                      key: displayName[i],\n                    }),\n                  )\n                  DisplayNameGenerator.removeDisplayName(displayName[i])\n                }\n              }\n              trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.CLICK, {\n                element: \"action_delete_modal_delete\",\n              })\n              modal.update(id, { okLoading: false })\n              modal.update(id, { visible: false })\n              return\n            }\n            case \"subpage\": {\n              dispatch(\n                componentsActions.deleteSubPageViewNodeReducer({\n                  pageName: options!.parentPageName,\n                  subPagePath: displayName[0],\n                }),\n              )\n              break\n            }\n            case \"pageView\": {\n              dispatch(\n                componentsActions.deleteSectionViewReducer({\n                  viewDisplayName: options!.viewDisplayName,\n                  parentNodeName: options!.parentNodeName,\n                  originPageSortedKey: options!.originPageSortedKey,\n                }),\n              )\n              break\n            }\n            case \"globalData\": {\n              dispatch(\n                componentsActions.deleteGlobalStateByKeyReducer({\n                  key: displayName[0],\n                }),\n              )\n              DisplayNameGenerator.removeDisplayName(displayName[0])\n              break\n            }\n          }\n          setAlreadyShowDeleteDialog(false)\n          modal.update(id, { visible: false })\n        },\n        afterOpen: () => {\n          if (type === \"page\") {\n            trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n              element: \"delete_page_modal\",\n            })\n          }\n          if (type === \"widget\") {\n            trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n              element: \"component_delete_modal\",\n              parameter3: options?.source || \"\",\n            })\n          }\n          if (type === \"action\") {\n            trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SHOW, {\n              element: \"action_delete_modal\",\n            })\n          }\n        },\n      })\n    }\n  }\n\n  const selectAllBodyComponentsHandler = useCallback(() => {\n    switch (FocusManager.getFocus()) {\n      case \"none\":\n        break\n      case \"data_component\":\n        break\n      case \"data_action\":\n        break\n      case \"data_page\":\n        break\n      case \"data_global_state\":\n        break\n      case \"action\":\n        break\n      case \"widget_picker\":\n        break\n      case \"components_config\":\n        break\n      case \"page_config\":\n        break\n      case \"canvas\": {\n        if (componentsMap) {\n          const rootNode = executionResult.root\n          if (!rootNode) return\n          const currentPageDisplayName =\n            rootNode.pageSortedKey[rootNode.currentPageIndex]\n          const pageNode = searchComponentFromMap(\n            componentsMap,\n            currentPageDisplayName,\n          )\n          if (!pageNode) return\n          let bodySectionDisplayName: string = \"\"\n          pageNode.childrenNode.find((sectionNodeDisplayName) => {\n            const currentSectionProps = executionResult[sectionNodeDisplayName]\n            if (\n              currentSectionProps &&\n              currentSectionProps.viewSortedKey &&\n              currentSectionProps.currentViewIndex >= 0 &&\n              componentsMap[sectionNodeDisplayName].showName === \"bodySection\"\n            ) {\n              const { currentViewIndex, viewSortedKey } = currentSectionProps\n              bodySectionDisplayName = viewSortedKey[currentViewIndex]\n            }\n          })\n          if (!bodySectionDisplayName) return\n          const allChildrenNodeDisplayNames = Array.isArray(\n            componentsMap[bodySectionDisplayName].childrenNode,\n          )\n            ? componentsMap[bodySectionDisplayName].childrenNode\n            : []\n\n          trackInEditor(ILLA_MIXPANEL_EVENT_TYPE.SELECT, {\n            element: \"component\",\n            parameter1: \"keyboard\",\n          })\n          dispatch(\n            configActions.updateSelectedComponent(allChildrenNodeDisplayNames),\n          )\n        }\n      }\n    }\n  }, [componentsMap, dispatch, executionResult])\n\n  const copySomethingHandler = () => {\n    switch (FocusManager.getFocus()) {\n      case \"data_page\":\n        break\n      case \"data_global_state\":\n        break\n      case \"none\":\n        break\n      case \"canvas\":\n      case \"data_component\":\n        if (\n          currentSelectedComponent != null &&\n          currentSelectedComponent.length > 0\n        ) {\n          CopyManager.copyComponentNodeByDisplayName(currentSelectedComponent)\n        }\n        break\n      case \"data_action\":\n      case \"action\":\n        if (currentSelectedAction != null) {\n          CopyManager.copyActionByActionID(currentSelectedAction.actionID)\n        }\n        break\n      case \"widget_picker\":\n        break\n      case \"components_config\":\n        break\n      case \"page_config\":\n        break\n    }\n  }\n\n  const copyAndPasteHandler = () => {\n    switch (FocusManager.getFocus()) {\n      case \"data_page\":\n        break\n      case \"data_global_state\":\n        break\n      case \"none\":\n        break\n      case \"canvas\":\n      case \"data_component\":\n        if (\n          currentSelectedComponent != null &&\n          currentSelectedComponent.length > 0\n        ) {\n          CopyManager.copyComponentNodeByDisplayName(currentSelectedComponent)\n        }\n        break\n      case \"data_action\":\n      case \"action\":\n        if (currentSelectedAction != null) {\n          CopyManager.copyActionByActionID(currentSelectedAction.actionID)\n        }\n        break\n      case \"widget_picker\":\n        break\n      case \"components_config\":\n        break\n      case \"page_config\":\n        break\n    }\n    CopyManager.paste(\"keyboard\")\n  }\n\n  const showDotHandler = useCallback(\n    (keyboardEventType: string) => {\n      if (keyboardEventType === \"keydown\") {\n        dispatch(configActions.updateShowDot(true))\n      } else if (keyboardEventType === \"keyup\") {\n        dispatch(configActions.updateShowDot(false))\n      }\n    },\n    [dispatch],\n  )\n\n  const changeShadowHidden = useCallback(() => {\n    if (showShadows) {\n      dispatch(configActions.updateShowDot(false))\n    }\n  }, [dispatch, showShadows])\n\n  const handleSaveToHistory = useCallback(async () => {\n    if (!canUseBillingFeature) {\n      upgradeModal({\n        modalType: \"upgrade\",\n        from: \"app_edit_keyboard_history\",\n      })\n    } else if (appId) {\n      if (saveLoading) return\n      setSaveLoading(true)\n      try {\n        await takeSnapShot(appId)\n        message.success({ content: t(\"editor.history.message.suc.save\") })\n      } catch (error) {\n        if (isILLAAPiError(error)) {\n          message.error({ content: t(\"editor.history.message.fail.save\") })\n        } else {\n          message.error({ content: t(\"network_error\") })\n        }\n      } finally {\n        setSaveLoading(false)\n      }\n    }\n  }, [appId, canUseBillingFeature, message, saveLoading, t, upgradeModal])\n\n  useHotkeys(\n    `${isMAC() ? Key.Meta : Key.Control}+s`,\n    (keyboardEvent) => {\n      if (keyboardEvent.repeat) return\n      if (isCloudVersion) {\n        handleSaveToHistory()\n      } else {\n        message.success({\n          content: t(\"dont_need_save\"),\n        })\n      }\n    },\n    {\n      enableOnFormTags: true,\n      enableOnContentEditable: true,\n      preventDefault: true,\n      enabled: isEditMode,\n    },\n    [handleSaveToHistory],\n  )\n\n  useHotkeys(\n    Key.Backspace,\n    (keyboardEvent) => {\n      if (keyboardEvent.repeat) return\n      switch (FocusManager.getFocus()) {\n        case \"data_page\":\n          break\n        case \"data_global_state\":\n          break\n        case \"none\":\n          break\n        case \"canvas\":\n        case \"data_component\":\n          showDeleteDialog(\n            currentSelectedComponent.map((displayName) => {\n              return displayName\n            }),\n            \"widget\",\n            { source: \"keyboard\" },\n          )\n          break\n        case \"data_action\":\n        case \"action\":\n          if (currentSelectedAction?.displayName) {\n            showDeleteDialog([currentSelectedAction.displayName], \"action\", {\n              source: \"keyboard\",\n            })\n          }\n          break\n        case \"widget_picker\":\n          break\n        case \"components_config\":\n          break\n        case \"page_config\":\n          break\n      }\n    },\n    {\n      enabled: isEditMode,\n    },\n    [showDeleteDialog, currentSelectedComponent, currentSelectedAction],\n  )\n\n  useHotkeys(\n    `${isMAC() ? Key.Meta : Key.Control}+a`,\n    (keyboardEvent) => {\n      if (keyboardEvent.repeat) return\n      selectAllBodyComponentsHandler()\n    },\n    {\n      preventDefault: true,\n      enabled: isEditMode,\n    },\n    [selectAllBodyComponentsHandler],\n  )\n\n  useHotkeys(\n    `${isMAC() ? Key.Meta : Key.Control}+c`,\n    (keyboardEvent) => {\n      if (keyboardEvent.repeat) return\n      copySomethingHandler()\n    },\n    {\n      preventDefault: false,\n      enabled: isEditMode,\n    },\n    [copySomethingHandler],\n  )\n\n  useHotkeys(\n    `${isMAC() ? Key.Meta : Key.Control}+v`,\n    (keyboardEvent) => {\n      if (keyboardEvent.repeat) return\n      CopyManager.paste(\"keyboard\")\n    },\n    {\n      preventDefault: false,\n      enabled: isEditMode,\n    },\n    [copySomethingHandler],\n  )\n\n  useHotkeys(\n    `${isMAC() ? Key.Meta : Key.Control}+d`,\n    (keyboardEvent) => {\n      if (keyboardEvent.repeat) return\n      copyAndPasteHandler()\n    },\n    {\n      preventDefault: true,\n      enabled: isEditMode,\n    },\n    [copyAndPasteHandler],\n  )\n\n  useHotkeys(\n    `${isMAC() ? Key.Meta : Key.Control}`,\n    (keyboardEvent) => {\n      if (keyboardEvent.repeat) return\n\n      showDotHandler(keyboardEvent.type)\n    },\n    {\n      keydown: true,\n      keyup: true,\n      preventDefault: false,\n      enabled: isEditMode,\n    },\n    [showDotHandler],\n  )\n\n  useHotkeys(\n    `${isMAC() ? Key.Meta : Key.Control}+z`,\n    (keyboardEvent) => {\n      if (keyboardEvent.repeat) return\n\n      IllaUndoRedoManager.popFromUndoStack()\n    },\n    {\n      enabled: isEditMode,\n    },\n    [isEditMode],\n  )\n\n  useHotkeys(\n    `${isMAC() ? Key.Meta : Key.Control}+${Key.Shift}+z`,\n    (keyboardEvent) => {\n      if (keyboardEvent.repeat) return\n      IllaUndoRedoManager.popFromRedoStack()\n    },\n    {\n      enabled: isEditMode,\n    },\n    [isEditMode],\n  )\n\n  // cancel show dot\n  useEffect(() => {\n    if (isEditMode) {\n      window.addEventListener(\"blur\", changeShadowHidden)\n    }\n\n    return () => {\n      if (isEditMode) {\n        window.removeEventListener(\"blur\", changeShadowHidden)\n      }\n    }\n  }, [changeShadowHidden, dispatch, isEditMode])\n\n  return (\n    <ShortCutContext.Provider value={{ showDeleteDialog }}>\n      {children}\n    </ShortCutContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/utils/shortcut/interface.ts",
    "content": "export interface ShortcutContextProp {\n  showDeleteDialog: (\n    displayName: string[],\n    type?: \"page\" | \"widget\" | \"action\" | \"subpage\" | \"pageView\" | \"globalData\",\n    options?: Record<string, any>,\n  ) => void\n}\n"
  },
  {
    "path": "apps/builder/src/utils/shortcut/shortcutProvider.tsx",
    "content": "import { createContext } from \"react\"\nimport { ShortcutContextProp } from \"./interface\"\n\nexport const ShortCutContext = createContext<ShortcutContextProp>(\n  {} as ShortcutContextProp,\n)\n\nShortCutContext.displayName = \"ShortCutContext\"\n"
  },
  {
    "path": "apps/builder/src/utils/storage.ts",
    "content": "import ILLAStorage from \"@illa-public/illa-storage\"\n\nexport const ILLABuilderStorage = new ILLAStorage(`ILLABuilder@0.0.0`, 5)\n\nexport const CUSTOM_STORAGE_PREFIX = \"ILLABuilderCustomStorage\"\n"
  },
  {
    "path": "apps/builder/src/utils/styleUtils/padding.ts",
    "content": "export const getPaddingShape = (containerPadding: string = \"\") => {\n  const paddings = containerPadding?.split(\" \")\n  let paddingTop = 0\n  let paddingBottom = 0\n  let paddingLeft = 0\n  let paddingRight = 0\n  if (paddings.length === 1) {\n    paddingTop = isNaN(Number(paddings[0])) ? 0 : Number(paddings[0])\n    paddingBottom = paddingTop\n    paddingLeft = paddingTop\n    paddingRight = paddingTop\n  }\n\n  if (paddings.length === 4) {\n    paddingTop = isNaN(Number(paddings[0])) ? 0 : Number(paddings[0])\n    paddingBottom = isNaN(Number(paddings[2])) ? 0 : Number(paddings[2])\n    paddingLeft = isNaN(Number(paddings[3])) ? 0 : Number(paddings[3])\n    paddingRight = isNaN(Number(paddings[1])) ? 0 : Number(paddings[1])\n  }\n\n  return {\n    paddingTop,\n    paddingBottom,\n    paddingLeft,\n    paddingRight,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/styleUtils/shadow.ts",
    "content": "export const getShadowStyle = (\n  shadowSize?: \"none\" | \"small\" | \"medium\" | \"large\",\n) => {\n  switch (shadowSize) {\n    case \"small\": {\n      return \"0px 2px 8px rgba(0, 0, 0, 0.08);\"\n    }\n    case \"medium\": {\n      return \"0px 4px 16px rgba(0, 0, 0, 0.08);\"\n    }\n    case \"large\": {\n      return \"0px 8px 20px rgba(0, 0, 0, 0.12);\"\n    }\n    case \"none\":\n    default:\n      return \"unset\"\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/team.ts",
    "content": "import { getCurrentId } from \"@illa-public/user-data\"\nimport { ILLARoute } from \"@/router\"\nimport store from \"../store\"\n\nexport const getCurrentTeamID = () => {\n  return getCurrentId(store.getState())\n}\n\n// maybe not same as current team\nexport const getCurrentTeamIdentifier = () => {\n  return ILLARoute.state.matches[0].params.teamIdentifier\n}\n"
  },
  {
    "path": "apps/builder/src/utils/typeHelper.ts",
    "content": "import {\n  ActionContent,\n  ActionType,\n  ILLADriveAction,\n  ILLADriveActionTypeContent,\n  ILLA_DRIVE_ACTION_REQUEST_TYPE,\n  S3Action,\n  S3ActionRequestType,\n  S3ActionTypeContent,\n} from \"@illa-public/public-types\"\nimport { isString } from \"@illa-design/react\"\n\nconst DISPLAY_NAME_REGEX = /^([a-zA-Z_$])([a-zA-Z0-9_$])*$/\n\nexport enum Types {\n  STRING = \"STRING\",\n  NUMBER = \"NUMBER\",\n  BOOLEAN = \"BOOLEAN\",\n  OBJECT = \"OBJECT\",\n  ARRAY = \"ARRAY\",\n  FUNCTION = \"FUNCTION\",\n  UNDEFINED = \"UNDEFINED\",\n  NULL = \"NULL\",\n  UNKNOWN = \"UNKNOWN\",\n}\n\nexport const isObject = (value: unknown): value is Record<string, unknown> => {\n  return Object.prototype.toString.call(value) === \"[object Object]\"\n}\n\nexport const isFunction = (value: unknown): boolean => {\n  return (\n    Object.prototype.toString.call(value) === \"[object Function]\" ||\n    Object.prototype.toString.call(value) === \"[object AsyncFunction]\"\n  )\n}\n\nexport const getType = (value: unknown) => {\n  if (typeof value === \"string\") return Types.STRING\n  if (typeof value === \"number\") return Types.NUMBER\n  if (typeof value === \"boolean\") return Types.BOOLEAN\n  if (Array.isArray(value)) return Types.ARRAY\n  if (isFunction(value)) return Types.FUNCTION\n  if (isObject(value)) return Types.OBJECT\n  if (typeof value === \"undefined\") return Types.UNDEFINED\n  if (value === null) return Types.NULL\n  return Types.UNKNOWN\n}\n\nexport function isURL(str: string) {\n  const pattern = new RegExp(\n    /^(((ht|f)tps?):\\/\\/)?(([^!@#$%^&*?.\\s-]([^!@#$%^&*?.\\s]{0,63}[^!@#$%^&*?.\\s])?\\.)+[a-z]{2,6}|(\\d{1,3}\\.){3}\\d{1,3})\\/?/,\n  ) // fragment locator\n  return !!pattern.test(str)\n}\n\nexport function isBlobURLOrUrl(url: string): boolean {\n  if (!url) return false\n  return url.startsWith(\"blob:\") || isURL(url)\n}\n\nexport const isValidUrlScheme = (url: string): boolean => {\n  return (\n    // Standard http call\n    url.startsWith(\"http://\") ||\n    // Secure http call\n    url.startsWith(\"https://\") ||\n    // Mail url to directly open email app prefilled\n    url.startsWith(\"mailto:\") ||\n    // Tel url to directly open phone app prefilled\n    url.startsWith(\"tel:\")\n  )\n}\n\nexport const isInt = (val: string | number): boolean => {\n  return Number.isInteger(val) || (isString(val) && /^\\d+$/.test(val))\n}\n\nexport const isValidDisplayName = (displayName: string): boolean =>\n  DISPLAY_NAME_REGEX.test(displayName)\n\nexport const isClientS3ActionContent = (\n  actionType: ActionType,\n  actionContent: ActionContent,\n): actionContent is S3Action<S3ActionTypeContent> => {\n  return (\n    actionType === \"s3\" &&\n    \"commands\" in actionContent &&\n    [\n      S3ActionRequestType.READ_ONE,\n      S3ActionRequestType.DOWNLOAD_ONE,\n      S3ActionRequestType.UPLOAD,\n      S3ActionRequestType.UPLOAD_MULTIPLE,\n    ].includes(actionContent.commands)\n  )\n}\n\nexport const isDriveActionContent = (\n  actionType: ActionType,\n  actionContent: ActionContent,\n): actionContent is ILLADriveAction<ILLADriveActionTypeContent> => {\n  return (\n    actionType === \"illadrive\" &&\n    \"operation\" in actionContent &&\n    Object.values(ILLA_DRIVE_ACTION_REQUEST_TYPE).includes(\n      actionContent.operation as ILLA_DRIVE_ACTION_REQUEST_TYPE,\n    )\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/utils/undoRedo/antonymyRule.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { AnyAction } from \"@reduxjs/toolkit\"\nimport { createMessage } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { REDUX_ACTION_FROM } from \"@/middleware/undoRedo/interface\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport store from \"@/store\"\nimport { changeDisplayNameHelperWhenUndoRedo } from \"../componentNode/changeDisplayNameHelper\"\nimport { DisplayNameGenerator } from \"../generators/generateDisplayName\"\nimport {\n  addActionItemWhenUndoRedo,\n  removeActionItemWhenUndoRedo,\n  updateActionDisplayNameReducerWhenUndoRedo,\n  updateActionItemReducerWhenUndoRedo,\n} from \"./undoRedoMethod/action\"\n\nconst message = createMessage()\n\nexport const reduxActionDependOnRestAPI = async (\n  actions: AnyAction[],\n  from: REDUX_ACTION_FROM,\n) => {\n  for (let i = 0; i < actions.length; i++) {\n    const action = actions[i]\n    switch (action.type) {\n      case \"action/addActionItemReducer\": {\n        try {\n          const newPayload = await addActionItemWhenUndoRedo(action.payload)\n          store.dispatch({\n            ...action,\n            payload: newPayload,\n            from,\n          })\n        } catch (e) {\n          message.error({\n            content: i18n.t(`frame.message.${from}.failed`),\n          })\n          return\n        }\n\n        break\n      }\n      case \"action/removeActionItemReducer\": {\n        try {\n          await removeActionItemWhenUndoRedo(action.payload.displayName)\n          store.dispatch(\n            configActions.resetSelectedActionReducer(\n              action.payload.displayName,\n            ),\n          )\n          store.dispatch({\n            ...action,\n            from,\n          })\n        } catch (e) {\n          message.error({\n            content: i18n.t(`frame.message.${from}.failed`),\n          })\n          return\n        }\n        break\n      }\n      case \"action/updateActionItemReducer\": {\n        try {\n          await updateActionItemReducerWhenUndoRedo(action.payload)\n          store.dispatch({\n            ...action,\n            from,\n          })\n        } catch (e) {\n          message.error({\n            content: i18n.t(`frame.message.${from}.failed`),\n          })\n          return\n        }\n        break\n      }\n      case \"action/updateActionDisplayNameReducer\": {\n        try {\n          await updateActionDisplayNameReducerWhenUndoRedo(\n            action.payload.oldDisplayName,\n            action.payload.newDisplayName,\n          )\n          store.dispatch({\n            ...action,\n            from,\n          })\n        } catch (e) {\n          message.error({\n            content: i18n.t(`frame.message.${from}.failed`),\n          })\n          return\n        }\n        break\n      }\n      case \"components/addComponentReducer\": {\n        const originNode = action.payload\n        const newOriginNodeByChangeDisplayName = originNode.map(\n          (item: ComponentTreeNode) =>\n            changeDisplayNameHelperWhenUndoRedo(item),\n        )\n\n        store.dispatch({\n          ...action,\n          from,\n          payload: newOriginNodeByChangeDisplayName,\n        })\n        break\n      }\n      case \"components/addTargetPageSectionReducer\": {\n        if (action.payload.originSectionNode) {\n          const newOriginNodeByChangeDisplayName =\n            changeDisplayNameHelperWhenUndoRedo(\n              action.payload.originSectionNode,\n            )\n          store.dispatch({\n            ...action,\n            from,\n            payload: {\n              ...action.payload,\n              originSectionNode: newOriginNodeByChangeDisplayName,\n            },\n          })\n        }\n        break\n      }\n      case \"components/addSectionViewConfigByConfigReducer\":\n      case \"components/addSectionViewReducer\": {\n        if (Array.isArray(action.payload.originChildrenNode)) {\n          const newOriginNodeByChangeDisplayName =\n            action.payload.originChildrenNode.map((item: ComponentTreeNode) =>\n              changeDisplayNameHelperWhenUndoRedo(item),\n            )\n          store.dispatch({\n            ...action,\n            from,\n            payload: {\n              ...action.payload,\n              originChildrenNode: newOriginNodeByChangeDisplayName,\n            },\n          })\n        }\n        break\n      }\n      case \"components/addPageNodeWithSortOrderReducer\": {\n        const originNode = action.payload\n        const newOriginNodeByChangeDisplayName =\n          changeDisplayNameHelperWhenUndoRedo(originNode)\n        store.dispatch({\n          ...action,\n          from,\n          payload: {\n            ...action.payload,\n            originChildrenNode: newOriginNodeByChangeDisplayName,\n          },\n        })\n        break\n      }\n      case \"components/updateTargetPageLayoutReducer\": {\n        const originNode = action.payload.originPageNode\n        const newOriginNodeByChangeDisplayName =\n          changeDisplayNameHelperWhenUndoRedo(originNode)\n        store.dispatch({\n          ...action,\n          from,\n          payload: {\n            ...action.payload,\n            originChildrenNode: newOriginNodeByChangeDisplayName,\n          },\n        })\n        break\n      }\n      case \"components/setGlobalStateReducer\": {\n        if (action.payload.key) {\n          const newName = DisplayNameGenerator.updateOrGenerateDisplayName(\n            action.payload.key,\n          )\n          store.dispatch({\n            ...action,\n            from,\n            payload: {\n              ...action.payload,\n              key: newName,\n            },\n          })\n        }\n        break\n      }\n\n      default: {\n        store.dispatch({\n          ...action,\n          from,\n        })\n      }\n    }\n  }\n  message.success({\n    content: i18n.t(`frame.message.${from}.suc`),\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/utils/undoRedo/circularStack.ts",
    "content": "export class CircularStack<T> {\n  private data: T[]\n  private maxSize: number\n  private currentIndex: number\n  private currentSize: number\n\n  constructor(maxSize: number) {\n    this.data = new Array<T>(maxSize)\n    this.maxSize = maxSize\n    this.currentIndex = -1\n    this.currentSize = 0\n  }\n\n  push(item: T) {\n    this.currentIndex = (this.currentIndex + 1) % this.maxSize\n    this.data[this.currentIndex] = item\n    this.currentSize++\n  }\n\n  pop(): T | undefined {\n    if (this.isEmpty()) {\n      return undefined\n    }\n\n    const item = this.data[this.currentIndex]\n    this.currentIndex = (this.currentIndex - 1 + this.maxSize) % this.maxSize\n    this.currentSize--\n    return item\n  }\n\n  peek(): T | undefined {\n    if (this.isEmpty()) {\n      return undefined\n    }\n\n    return this.data[this.currentIndex]\n  }\n\n  isEmpty(): boolean {\n    return this.currentSize === 0\n  }\n\n  isFull(): boolean {\n    return this.currentSize === this.maxSize\n  }\n\n  clear() {\n    this.data = new Array<T>(this.maxSize)\n    this.currentIndex = -1\n    this.currentSize = 0\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/undoRedo/undo.ts",
    "content": "import { AnyAction } from \"@reduxjs/toolkit\"\nimport { createMessage } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { REDUX_ACTION_FROM } from \"@/middleware/undoRedo/interface\"\nimport { illaSnapshot } from \"@/page/App/components/DotPanel/constant/snapshotNew\"\nimport { getClientWidgetLayoutInfo } from \"@/redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport store from \"@/store\"\nimport { reduxActionDependOnRestAPI } from \"./antonymyRule\"\nimport { CircularStack } from \"./circularStack\"\n\nexport const UNDO_REDO_STACK_MAX_LENGTH = 30\n\nconst message = createMessage()\n\nexport class ILLA_UNDO_REDO {\n  undoStack: CircularStack<AnyAction[]>\n  redoStack: CircularStack<AnyAction[]>\n\n  constructor(maxStackLength: number = UNDO_REDO_STACK_MAX_LENGTH) {\n    this.undoStack = new CircularStack<AnyAction[]>(maxStackLength)\n    this.redoStack = new CircularStack<AnyAction[]>(maxStackLength)\n  }\n\n  pushToUndoStack(undoAction: AnyAction[]) {\n    if (!this.redoStack.isEmpty() && !undoAction[0].from) {\n      this.redoStack.clear()\n    }\n    this.undoStack.push(undoAction)\n  }\n\n  popFromUndoStack() {\n    const rootState = store.getState()\n    const snapShot = getClientWidgetLayoutInfo(rootState)\n    illaSnapshot.setSnapshot(snapShot)\n    if (this.undoStack.isEmpty()) {\n      message.warning({\n        content: i18n.t(\"frame.message.undo.nothing\"),\n      })\n    } else {\n      const info = this.undoStack.pop() as AnyAction[]\n      reduxActionDependOnRestAPI(info, REDUX_ACTION_FROM.UNDO)\n    }\n  }\n\n  modifyUndoStackAtLast(undoAction: AnyAction[], isRedo: boolean = false) {\n    if (this.undoStack.isEmpty()) {\n      return\n    }\n    const lastUndoAction = this.undoStack.pop() as AnyAction[]\n    if (isRedo) {\n      this.undoStack.push([...lastUndoAction, ...undoAction])\n    } else {\n      this.undoStack.push([...undoAction, ...lastUndoAction])\n    }\n  }\n\n  pushToRedoStack(redoAction: AnyAction[]) {\n    this.redoStack.push(redoAction)\n  }\n\n  popFromRedoStack() {\n    const rootState = store.getState()\n    const snapShot = getClientWidgetLayoutInfo(rootState)\n    illaSnapshot.setSnapshot(snapShot)\n    if (this.redoStack.isEmpty()) {\n      message.warning({\n        content: i18n.t(\"frame.message.redo.nothing\"),\n      })\n    } else {\n      const info = this.redoStack.pop() as AnyAction[]\n      reduxActionDependOnRestAPI(info, REDUX_ACTION_FROM.REDO)\n    }\n  }\n  destroy() {\n    this.undoStack.clear()\n    this.redoStack.clear()\n  }\n}\n\nexport default new ILLA_UNDO_REDO()\n"
  },
  {
    "path": "apps/builder/src/utils/undoRedo/undoRedoMethod/action.ts",
    "content": "import { ActionContent } from \"@illa-public/public-types\"\nimport { ActionItem } from \"@illa-public/public-types\"\nimport { omit } from \"lodash-es\"\nimport { v4 } from \"uuid\"\nimport { getIsILLAGuideMode } from \"@/redux/config/configSelector\"\nimport { getActionList } from \"@/redux/currentApp/action/actionSelector\"\nimport {\n  fetchCreateAction,\n  fetchDeleteAction,\n  fetchUpdateAction,\n} from \"@/services/action\"\nimport store from \"@/store\"\nimport { DisplayNameGenerator } from \"@/utils/generators/generateDisplayName\"\n\nexport const addActionItemWhenUndoRedo = async (\n  action: ActionItem<ActionContent>,\n) => {\n  const isGuideMode = getIsILLAGuideMode(store.getState())\n  const newAction = omit(action, [\"displayName\", \"actionID\"])\n  const displayName = DisplayNameGenerator.isAlreadyGenerate(action.displayName)\n    ? DisplayNameGenerator.generateDisplayName(action.actionType)\n    : DisplayNameGenerator.updateOrGenerateDisplayName(action.displayName)\n  const data: Omit<ActionItem<ActionContent>, \"actionID\"> = {\n    ...newAction,\n    displayName,\n  }\n  if (isGuideMode) {\n    const createActionData: ActionItem<ActionContent> = {\n      ...data,\n      actionID: v4(),\n    }\n    return createActionData\n  }\n  try {\n    const response = await fetchCreateAction(data)\n    return response.data\n  } catch (e) {\n    DisplayNameGenerator.removeDisplayName(displayName)\n    throw e\n  }\n}\n\nexport const removeActionItemWhenUndoRedo = async (displayName: string) => {\n  const isGuideMode = getIsILLAGuideMode(store.getState())\n  const actionList = getActionList(store.getState())\n  const targetAction = actionList.find(\n    (item) => item.displayName === displayName,\n  )\n  if (!targetAction) {\n    throw new Error(\"action not found\")\n  }\n  if (!isGuideMode) {\n    try {\n      await fetchDeleteAction(targetAction.actionID)\n    } catch (e) {\n      throw e\n    }\n  }\n}\n\nexport const updateActionItemReducerWhenUndoRedo = async (\n  action: ActionItem<ActionContent>,\n) => {\n  const isGuideMode = getIsILLAGuideMode(store.getState())\n  const actionList = getActionList(store.getState())\n  const targetAction = actionList.find(\n    (item) => action.displayName === item.displayName,\n  )\n  if (!targetAction) {\n    throw new Error(\"action not found\")\n  }\n  if (!isGuideMode) {\n    try {\n      await fetchUpdateAction(action)\n    } catch (e) {\n      throw e\n    }\n  }\n}\n\nexport const updateActionDisplayNameReducerWhenUndoRedo = async (\n  oldDisplayName: string,\n  newDisplayName: string,\n) => {\n  const isGuideMode = getIsILLAGuideMode(store.getState())\n  const actionList = getActionList(store.getState())\n  const action = actionList.find(\n    (action) => action.displayName === oldDisplayName,\n  )\n  if (!isGuideMode && action) {\n    try {\n      await fetchUpdateAction({ ...action, displayName: newDisplayName })\n    } catch (e) {\n      throw e\n    }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/undoRedo/undoRedoMethod/components.ts",
    "content": ""
  },
  {
    "path": "apps/builder/src/utils/url/base64.ts",
    "content": "const mimeRegex = /^data:\\w+\\/[a-zA-Z+\\-.]+;base64,/\n\nfunction isValidBase64(src: string) {\n  // according file size to use different regex\n  const fileSize = src.length\n\n  let regex\n  if (fileSize > 1024 * 1024) {\n    regex = /^[A-Za-z0-9+/]+=*$/\n  } else {\n    regex = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/\n  }\n  return regex.test(src)\n}\n\nexport const isBase64 = (v: string, mimeRequired?: boolean) => {\n  if (typeof v !== \"string\") return false\n  const value = v.split(\",\")\n  const prefix = value.length > 1 ? value[0] : \"\"\n  const suffix = value.length > 1 ? value[1] : value[0]\n  if (value.length > 2) {\n    return false\n  }\n  if (!isValidBase64(suffix)) {\n    return false\n  }\n  if (mimeRequired) {\n    return mimeRegex.test(prefix + \",\")\n  }\n  return true\n}\n\nexport const isBase64Simple = (str: string) => {\n  if (typeof str !== \"string\") return\n  if (str.indexOf(\"data:\") != -1 && str.indexOf(\"base64\") != -1) {\n    return true\n  } else {\n    return false\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/utils/useFuse.ts",
    "content": "import Fuse from \"fuse.js\"\nimport { isEqual } from \"lodash-es\"\nimport { useEffect, useRef, useState } from \"react\"\n\nexport function useFuse<T>(\n  data: ReadonlyArray<T>,\n  option?: Fuse.IFuseOptions<T>,\n) {\n  const dataRef = useRef<ReadonlyArray<T>>()\n  const optionRef = useRef<Fuse.IFuseOptions<T>>()\n\n  dataRef.current = data\n  optionRef.current = option\n\n  const [fuse, setFuse] = useState(new Fuse<T>(data, option))\n\n  useEffect(() => {\n    if (isEqual(dataRef.current, data) && isEqual(optionRef.current, option)) {\n      return\n    }\n    setFuse(new Fuse<T>(data, option))\n  }, [data, option])\n\n  return fuse\n}\n"
  },
  {
    "path": "apps/builder/src/utils/userAgent/index.ts",
    "content": "export const getUserPlatform = () => {\n  const platform =\n    \"userAgentData\" in navigator\n      ? // @ts-ignore\n        (navigator.userAgentData.platform as string)\n      : navigator.platform\n\n  const localStringForPlatform = platform.toLocaleLowerCase()\n  if (/(mac|iphone|ipod|ipad)/i.test(localStringForPlatform)) {\n    return \"macOS\"\n  }\n  if (/(win)/i.test(localStringForPlatform)) {\n    return \"Windows\"\n  }\n  if (/(linux)/i.test(localStringForPlatform)) {\n    return \"Linux\"\n  }\n}\n\nexport const isMAC = () => {\n  return getUserPlatform() === \"macOS\"\n}\n\nexport const isWindows = () => {\n  return getUserPlatform() === \"Windows\"\n}\n\nexport const isLinux = () => {\n  return getUserPlatform() === \"Linux\"\n}\n"
  },
  {
    "path": "apps/builder/src/utils/validationFactory/index.ts",
    "content": "import { isObject } from \"@/utils/typeHelper\"\n\nexport enum VALIDATION_TYPES {\n  STRING = \"String\",\n  NUMBER = \"Number\",\n  BOOLEAN = \"Boolean\",\n  ARRAY = \"Array\",\n  OBJECT = \"Object\",\n  UNDEFINED = \"Undefined\",\n  ANY = \"any\",\n}\n\nexport interface ValidationResponse {\n  isValid: boolean\n  safeValue: any\n  errorMessage?: string\n}\n\nexport type ValidateFunctionType = (\n  value: unknown,\n  currentListName: string,\n) => ValidationResponse\n\n// TODO: @weichen errorMessage i18n\nexport const validationFactory: Record<string, ValidateFunctionType> = {\n  [VALIDATION_TYPES.STRING]: (value, currentListName) => {\n    if (value == undefined) {\n      return {\n        isValid: true,\n        safeValue: undefined,\n      }\n    }\n    if (Array.isArray(value) && currentListName) {\n      const isString = typeof value[0] === \"string\"\n      if (!isString) {\n        return {\n          isValid: false,\n          safeValue: \"\",\n          errorMessage: \"Must be a string\",\n        }\n      }\n      return {\n        isValid: true,\n        safeValue: value[0],\n      }\n    }\n    const isString = typeof value === \"string\"\n\n    if (!isString) {\n      return {\n        isValid: false,\n        safeValue: \"\",\n        errorMessage: \"Must be a string\",\n      }\n    }\n    return {\n      isValid: true,\n      safeValue: value,\n    }\n  },\n  [VALIDATION_TYPES.BOOLEAN]: (value, currentListName) => {\n    if (value == undefined || value === \"\") {\n      return {\n        isValid: true,\n        safeValue: undefined,\n      }\n    }\n    if (Array.isArray(value) && currentListName) {\n      return {\n        isValid: true,\n        safeValue: value[0],\n      }\n    }\n    const isBoolean = typeof value === \"boolean\"\n    if (!isBoolean) {\n      return {\n        isValid: false,\n        safeValue: false,\n        errorMessage: \"Must be a boolean\",\n      }\n    }\n    return {\n      isValid: true,\n      safeValue: value,\n    }\n  },\n  [VALIDATION_TYPES.NUMBER]: (value, currentListName) => {\n    if (value == undefined || value === \"\") {\n      return {\n        isValid: true,\n        safeValue: undefined,\n      }\n    }\n    if (Array.isArray(value) && currentListName) {\n      return {\n        isValid: true,\n        safeValue: value[0],\n      }\n    }\n    const isNumber = typeof value === \"number\"\n    if (!isNumber) {\n      return {\n        isValid: false,\n        safeValue: 0,\n        errorMessage: \"Must be a number\",\n      }\n    }\n    return {\n      isValid: true,\n      safeValue: value,\n    }\n  },\n  [VALIDATION_TYPES.ARRAY]: (value) => {\n    if (value == undefined || value === \"\") {\n      return {\n        isValid: true,\n        safeValue: undefined,\n      }\n    }\n    const isArray = Array.isArray(value)\n    if (!isArray) {\n      return {\n        isValid: false,\n        safeValue: [],\n        errorMessage: \"Must be a Array\",\n      }\n    }\n    return {\n      isValid: true,\n      safeValue: value,\n    }\n  },\n  [VALIDATION_TYPES.OBJECT]: (value) => {\n    if (value == undefined || value === \"\") {\n      return {\n        isValid: true,\n        safeValue: undefined,\n      }\n    }\n    const isObjectValue = isObject(value)\n    if (!isObjectValue) {\n      return {\n        isValid: false,\n        safeValue: {},\n        errorMessage: \"Must be a Object\",\n      }\n    }\n    return {\n      isValid: true,\n      safeValue: value,\n    }\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AudioWidget/audio.tsx",
    "content": "import { isBoolean } from \"lodash-es\"\nimport {\n  FC,\n  forwardRef,\n  useCallback,\n  useContext,\n  useEffect,\n  useRef,\n  useState,\n} from \"react\"\nimport ReactPlayer from \"react-player\"\nimport { Loading, isNumber, isString } from \"@illa-design/react\"\nimport { MediaSourceLoadContext } from \"@/utils/mediaSourceLoad\"\nimport {\n  audioWrapperStyle,\n  fullStyle,\n  loadingStyle,\n} from \"@/widgetLibrary/AudioWidget/style\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { AudioWidgetProps, WrappedAudioProps } from \"./interface\"\n\nexport const WrappedAudio = forwardRef<ReactPlayer, WrappedAudioProps>(\n  (props, ref) => {\n    const {\n      url,\n      playing,\n      autoPlay,\n      controls = true,\n      loop,\n      volume,\n      muted,\n      playbackRate,\n      onPlay,\n      onReady,\n      onPause,\n      onEnded,\n      onPlaybackRateChange,\n    } = props\n    const [loading, setLoading] = useState(true)\n    const [_error, setError] = useState(false)\n    const { sourceLoadErrorHandler } = useContext(MediaSourceLoadContext)\n\n    return (\n      <>\n        {loading ? (\n          <div css={loadingStyle}>\n            <Loading colorScheme=\"black\" />\n          </div>\n        ) : null}\n        <ReactPlayer\n          css={audioWrapperStyle}\n          style={loading ? { display: \"none\" } : undefined}\n          config={{\n            file: {\n              forceAudio: true,\n            },\n          }}\n          ref={ref}\n          width=\"100%\"\n          height=\"100%\"\n          // show unavailable link state for audio empty state\n          url={url || \" \"}\n          volume={volume}\n          muted={muted}\n          controls={controls}\n          playbackRate={playbackRate}\n          loop={loop}\n          playing={autoPlay || playing}\n          draggable={false}\n          onReady={() => {\n            setLoading(false)\n            setError(false)\n            onReady()\n          }}\n          onPlay={onPlay}\n          onPause={onPause}\n          onEnded={onEnded}\n          onError={() => {\n            sourceLoadErrorHandler?.(url, \"AUDIO_WIDGET\")\n            setLoading(false)\n            setError(true)\n          }}\n          onPlaybackRateChange={onPlaybackRateChange}\n        />\n      </>\n    )\n  },\n)\n\nWrappedAudio.displayName = \"WrappedAudio\"\n\nexport const AudioWidget: FC<AudioWidgetProps> = (props) => {\n  const {\n    handleUpdateDsl,\n    handleUpdateMultiExecutionResult,\n    displayName,\n    tooltipText,\n    triggerEventHandler,\n    deleteComponentRuntimeProps,\n    updateComponentRuntimeProps,\n  } = props\n\n  const audioRef = useRef<ReactPlayer>(null)\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      play: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { playing: true },\n          },\n        ])\n      },\n      pause: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { playing: false },\n          },\n        ])\n      },\n      setAudioUrl: (url: string) => {\n        if (!isString(url)) {\n          console.error(\"TypeError: url is not a string\")\n          return\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { url },\n          },\n        ])\n      },\n      seekTo: (time: number, type: \"seconds\" | \"fraction\" = \"seconds\") => {\n        if (!isNumber(time)) {\n          console.error(\"TypeError: value is not a number\")\n          return\n        }\n        audioRef.current?.seekTo(time, type)\n      },\n      mute: (value: boolean) => {\n        if (!isBoolean(value)) {\n          console.error(\"TypeError: value is not a boolean\")\n          return\n        }\n        const audio = audioRef.current?.getInternalPlayer() as HTMLAudioElement\n        if (audio) {\n          // As the player doesn't update internally, it's necessary to modify the DOM directly.\n          audio.muted = value\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { muted: value },\n          },\n        ])\n      },\n      setLoop: (value: boolean) => {\n        if (!isBoolean(value)) {\n          console.error(\"TypeError: value is not a boolean\")\n          return\n        }\n        const audio = audioRef.current?.getInternalPlayer() as HTMLAudioElement\n        if (audio) {\n          // As the player doesn't update internally, it's necessary to modify the DOM directly.\n          audio.loop = value\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { loop: value },\n          },\n        ])\n      },\n      setSpeed: (value: number) => {\n        if (!isNumber(value)) {\n          console.error(\"TypeError: value is not a number\")\n          return\n        }\n        // playbackRate range [0.0625, 16]\n        const clampedValue = Math.max(0.0625, Math.min(16, value))\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { playbackRate: clampedValue },\n          },\n        ])\n      },\n      setVolume: (value: number) => {\n        if (!isNumber(value)) {\n          console.error(\"TypeError: value is not a number\")\n          return\n        }\n        // volume range [0, 1]\n        const clampedValue = Math.max(0, Math.min(1, value))\n        const audio = audioRef.current?.getInternalPlayer() as HTMLAudioElement\n        if (audio) {\n          // As the player doesn't update internally, it's necessary to modify the DOM directly.\n          audio.volume = clampedValue\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { volume: clampedValue },\n          },\n        ])\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    displayName,\n    handleUpdateMultiExecutionResult,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n  ])\n\n  const onPlay = useCallback(() => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: { playing: true },\n      },\n    ])\n    triggerEventHandler(\"play\")\n  }, [displayName, triggerEventHandler, handleUpdateMultiExecutionResult])\n\n  const onPause = useCallback(() => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: { playing: false },\n      },\n    ])\n    triggerEventHandler(\"pause\")\n  }, [displayName, triggerEventHandler, handleUpdateMultiExecutionResult])\n\n  const onReady = useCallback(() => {\n    triggerEventHandler(\"loaded\")\n  }, [triggerEventHandler])\n\n  const onEnded = useCallback(() => {\n    triggerEventHandler(\"ended\")\n  }, [triggerEventHandler])\n\n  const onPlaybackRateChange = useCallback(\n    (playbackRate: number) => {\n      if (isNumber(playbackRate)) {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { playbackRate },\n          },\n        ])\n      }\n    },\n    [displayName, handleUpdateMultiExecutionResult],\n  )\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div css={fullStyle}>\n        <WrappedAudio\n          {...props}\n          ref={audioRef}\n          onReady={onReady}\n          onPlay={onPlay}\n          onPause={onPause}\n          onEnded={onEnded}\n          onPlaybackRateChange={onPlaybackRateChange}\n        />\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nAudioWidget.displayName = \"AudioWidget\"\n\nexport default AudioWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AudioWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const AUDIO_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.play\",\n      ),\n      value: \"play\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.pause\",\n      ),\n      value: \"pause\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.loaded\",\n      ),\n      value: \"loaded\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.ended\",\n      ),\n      value: \"ended\",\n    },\n  ],\n  methods: [\n    \"play\",\n    \"pause\",\n    \"setAudioUrl\",\n    \"setVolume\",\n    \"setSpeed\",\n    \"setLoop\",\n    \"seekTo\",\n    \"mute\",\n  ],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AudioWidget/index.tsx",
    "content": "export { AUDIO_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { AUDIO_PANEL_CONFIG } from \"./panelConfig\"\nexport { AUDIO_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AudioWidget/interface.tsx",
    "content": "import { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\n// todo: @echoxyc error\nexport interface WrappedAudioProps extends BaseWidgetProps {\n  url?: string\n  controls?: boolean\n  autoPlay?: boolean\n  playing?: boolean\n  loop?: boolean\n  volume?: number\n  playbackRate?: number\n  muted?: boolean\n  onPlay: () => void\n  onPause: () => void\n  onEnded: () => void\n  onReady: () => void\n  onPlaybackRateChange: (rate: number) => void\n}\n\nexport interface AudioWidgetProps\n  extends Omit<WrappedAudioProps, \"onPlay\" | \"onPause\" | \"onEnded\" | \"onReady\">,\n    BaseWidgetProps,\n    TooltipWrapperProps {}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AudioWidget/panelConfig.tsx",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { AUDIO_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/AudioWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"audio\"\nexport const AUDIO_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-source-self-host`,\n        attrName: \"url\",\n        expectedType: VALIDATION_TYPES.STRING,\n        labelName: i18n.t(\"editor.inspect.setter_label.audio.audio_url\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.audio.audio_url\"),\n        isSetterSingleRow: true,\n        bindAttrName: [],\n        shown: () => !isCloudVersion,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-source-cloud-version`,\n        attrName: \"url\",\n        expectedType: VALIDATION_TYPES.STRING,\n        labelName: i18n.t(\"editor.inspect.setter_label.audio.audio_url\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.audio.audio_url\"),\n        isSetterSingleRow: true,\n        bindAttrName: [],\n        shown: () => isCloudVersion,\n        setterType: \"DRIVE_SOURCE_GROUP_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-autoPlay`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.autoplay\"),\n        useCustomLayout: true,\n        attrName: \"autoPlay\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-loop`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.loop\"),\n        useCustomLayout: true,\n        attrName: \"loop\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-mute`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.mute\"),\n        useCustomLayout: true,\n        attrName: \"muted\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-volume`,\n        labelName: i18n.t(\"editor.inspect.setter_label.volume\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tootip.volume\"),\n        placeholder: \"{{ 0.5 }}\",\n        attrName: \"volume\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          AUDIO_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        useCustomLayout: true,\n        attrName: \"hidden\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AudioWidget/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const fullStyle = css`\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n  display: flex;\n  align-items: center;\n`\n\nexport const loadingStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  //background-color: ${getColor(\"gray\", \"01\")};\n  color: ${getColor(\"black\", \"01\")};\n`\n\nexport const audioWrapperStyle = css`\n  & > audio {\n    &::-webkit-media-controls {\n      justify-content: center;\n    }\n  }\n`\n\nexport const applyHiddenStyle = (hidden: boolean): SerializedStyles => {\n  return css`\n    visibility: ${hidden ? \"hidden\" : \"visible\"};\n  `\n}\n\nexport const audioStyle = css`\n  display: flex;\n  gap: 16px;\n  padding: 8px;\n  max-height: 48px;\n  width: 100%;\n  background: ${getColor(\"white\", \"01\")};\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  border-radius: 24px;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AudioWidget/widgetConfig.tsx",
    "content": "import AudioWidgetIcon from \"@/assets/widgetCover/audio.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const AUDIO_WIDGET_CONFIG: WidgetConfig = {\n  type: \"AUDIO_WIDGET\",\n  displayName: \"audio\",\n  widgetName: i18n.t(\"widget.audio.name\"),\n  keywords: [\"Audio\", \"音频\"],\n  icon: <AudioWidgetIcon />,\n  sessionType: \"PRESENTATION\",\n  w: 16,\n  h: 7,\n  version: 0,\n  defaults: {\n    url: \"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3\",\n    hidden: false,\n    autoPlay: false,\n    loop: false,\n    playing: false,\n    muted: false,\n    controls: true,\n    volume: undefined,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AvatarWidget/avatar.tsx",
    "content": "import { getColorByString } from \"@illa-public/utils\"\nimport { isString } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { Avatar } from \"@illa-design/react\"\nimport { getIcon } from \"@/widgetLibrary/IconWidget/utils\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { AvatarWidgetProps, WrappedAvatarProps } from \"./interface\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  labelCaptionStyle,\n  labelContainerStyle,\n  labelStyle,\n} from \"./style\"\nimport { getSafeNode } from \"./utils\"\n\nexport const WrapperAvatar: FC<WrappedAvatarProps> = ({\n  allowWrap = false,\n  labelPosition = \"right\",\n  label,\n  labelAlign = \"left\",\n  labelCaption,\n  labelHidden,\n  avatarType,\n  icon,\n  text,\n  imageSrc,\n  avatarSize,\n  colorScheme,\n  handleOnClick,\n}) => {\n  const finalColorScheme = useMemo(() => {\n    if (colorScheme) {\n      return colorScheme\n    } else {\n      switch (avatarType) {\n        case \"image\":\n          return getColorByString(imageSrc || \"\")\n        case \"icon\":\n          return getColorByString(icon || \"\")\n        case \"text\":\n          return getColorByString(text || \"\")\n      }\n    }\n  }, [avatarType, colorScheme, icon, imageSrc, text])\n\n  const getTextString = () => {\n    if (!text || !isString(text)) return \"\"\n    let finalStr = \"\"\n    finalStr = text\n      .split(\" \")\n      .slice(0, 2)\n      .map((s) => s[0])\n      .join(\"\")\n      .toLocaleUpperCase()\n    return finalStr\n  }\n\n  return (\n    <div css={applyLabelAndComponentWrapperStyle(labelPosition, labelHidden)}>\n      <div css={labelContainerStyle(labelAlign)}>\n        {!labelHidden && (\n          <>\n            <span css={labelStyle(allowWrap)}>{getSafeNode(label)}</span>\n            <span css={labelCaptionStyle(allowWrap)}>\n              {getSafeNode(labelCaption)}\n            </span>\n          </>\n        )}\n      </div>\n\n      {avatarType === \"image\" && (\n        <Avatar\n          src={imageSrc ?? \"\"}\n          size={avatarSize}\n          colorScheme={finalColorScheme}\n          onClick={handleOnClick}\n        />\n      )}\n      {avatarType === \"icon\" && (\n        <Avatar\n          icon={getIcon(icon ?? \"\")?.({})}\n          size={avatarSize}\n          colorScheme={finalColorScheme}\n          onClick={handleOnClick}\n        />\n      )}\n      {avatarType === \"text\" && (\n        <Avatar\n          text={getSafeNode(getTextString())}\n          size={avatarSize}\n          colorScheme={finalColorScheme}\n          onClick={handleOnClick}\n        />\n      )}\n    </div>\n  )\n}\nexport const AvatarWidget: FC<AvatarWidgetProps> = (props) => {\n  const { triggerEventHandler, updateComponentHeight, disabled } = props\n\n  const handleOnClick = useCallback(() => {\n    !disabled && triggerEventHandler(\"click\")\n  }, [disabled, triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <WrapperAvatar {...props} handleOnClick={handleOnClick} />\n    </AutoHeightContainer>\n  )\n}\n\nAvatarWidget.displayName = \"AvatarWidget\"\nexport default AvatarWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AvatarWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const AVATAR_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.click\",\n      ),\n      value: \"click\",\n    },\n  ],\n  methods: [],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AvatarWidget/index.ts",
    "content": "export { AVATAR_PANEL_CONFIG } from \"./panelConfig\"\nexport { AVATAR_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { AVATAR_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\nexport * from \"./interface\"\nexport * from \"./avatar\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AvatarWidget/interface.ts",
    "content": "import LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport type AvatarType = \"image\" | \"icon\" | \"text\"\n\nexport interface WrappedAvatarProps\n  extends Pick<LabelProps, \"label\" | \"labelCaption\" | \"labelHidden\"> {\n  avatarType: AvatarType\n  imageSrc?: string\n  text?: string\n  icon?: string\n  colorScheme?: string\n  allowWrap?: boolean\n  avatarSize?: \"small\" | \"medium\" | \"large\"\n  labelPosition?: \"left\" | \"right\"\n  labelAlign?: \"left\" | \"right\"\n  handleOnClick?: () => void\n}\n\nexport interface AvatarWidgetProps extends BaseWidgetProps, WrappedAvatarProps {\n  disabled?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AvatarWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { AVATAR_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\nimport { AvatarType } from \"./interface\"\n\nconst baseWidgetName = \"avatar\"\nexport const AVATAR_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-avatar-type`,\n        labelName: i18n.t(\"editor.inspect.setter_label.avatar_type\"),\n        attrName: \"avatarType\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"DYNAMIC_SELECT_SETTER\",\n        isSetterSingleRow: true,\n        useCustomLayout: true,\n        openDynamic: true,\n        defaultValue: \"image\",\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_label.avatar_type_options.image\",\n            ),\n            value: \"image\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_label.avatar_type_options.icon\",\n            ),\n            value: \"icon\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_label.avatar_type_options.text\",\n            ),\n            value: \"text\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-image`,\n        labelName: i18n.t(\"editor.inspect.setter_label.imageSrc\"),\n        attrName: \"imageSrc\",\n        isSetterSingleRow: true,\n        bindAttrName: [\"avatarType\"],\n        shown: (avatarType: AvatarType) => avatarType === \"image\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-text`,\n        labelName: i18n.t(\"editor.inspect.setter_label.text\"),\n        attrName: \"text\",\n        bindAttrName: [\"avatarType\"],\n        shown: (avatarType: AvatarType) => avatarType === \"text\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-icon`,\n        labelName: i18n.t(\"editor.inspect.setter_label.icon\"),\n        attrName: \"icon\",\n        bindAttrName: [\"avatarType\"],\n        shown: (avatarType: AvatarType) => avatarType === \"icon\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"ICON_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.hide_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-allow-wrapping`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.allow_wrapping\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.allow_wrapping\"),\n        attrName: \"allowWrap\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.right\"), value: \"right\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          AVATAR_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.avatar_size\"),\n        attrName: \"avatarSize\",\n        setterType: \"BASE_SELECT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.shadow.large\"),\n            value: \"large\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.shadow.medium\"),\n            value: \"medium\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.shadow.small\"),\n            value: \"small\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-colors-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            useCustomLayout: true,\n            setterType: \"CUSTOM_BG_SELECT_SETTER\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AvatarWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const labelContainerStyle = (labelAlign?: string) => {\n  return css`\n    width: 100%;\n    display: flex;\n    flex-direction: column;\n    overflow: hidden;\n\n    font-size: 12px;\n    font-weight: 500;\n    line-height: 16px;\n    text-align: ${labelAlign ?? \"left\"};\n    overflow-wrap: break-word;\n  `\n}\n\nexport const applyLabelAndComponentWrapperStyle = (\n  labelPosition?: \"left\" | \"right\",\n  labelHidden?: boolean,\n) => {\n  return css`\n    max-width: 100%;\n    display: flex;\n    flex-direction: ${labelPosition === \"right\" ? \"row-reverse\" : \"row\"};\n    gap: ${!labelHidden ? \"8px\" : \"0\"};\n    align-items: center;\n  `\n}\n\nexport const labelStyle = (allowWrap?: boolean) => css`\n  color: ${getColor(\"gray\", \"02\")};\n  white-space: ${allowWrap ? \"normal\" : \"nowrap\"};\n  text-overflow: ellipsis;\n  overflow: hidden;\n`\n\nexport const labelCaptionStyle = (allowWrap?: boolean) => css`\n  color: ${getColor(\"gray\", \"04\")};\n  white-space: ${allowWrap ? \"normal\" : \"nowrap\"};\n  text-overflow: ellipsis;\n  overflow: hidden;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AvatarWidget/utils.ts",
    "content": "export const getSafeNode = (value: unknown) => {\n  if (typeof value === \"string\" || typeof value === \"number\") {\n    return `${value}`\n  }\n  return \"\"\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/AvatarWidget/widgetConfig.tsx",
    "content": "import AvatarWidgetIcon from \"@/assets/widgetCover/avatar.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const AVATAR_WIDGET_CONFIG: WidgetConfig = {\n  type: \"AVATAR_WIDGET\",\n  displayName: \"avatar\",\n  widgetName: i18n.t(\"widget.avatar.name\"),\n  icon: <AvatarWidgetIcon />,\n  keywords: [\"avatar\", \"头像\"],\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  sessionType: \"PRESENTATION\",\n  w: 6,\n  h: 6,\n  version: 0,\n  defaults: {\n    avatarType: \"image\",\n    imageSrc:\n      \"https://images.pexels.com/photos/1870376/pexels-photo-1870376.jpeg?auto=compress&cs=tinysrgb&w=800\",\n    hidden: false,\n    label: \"{{currentUserInfo.nickname}}\",\n    labelAlign: \"left\",\n    labelPosition: \"right\",\n    labelCaption: \"{{currentUserInfo.email}}\",\n    avatarSize: \"medium\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/BarProgressWidget/barProgress.tsx",
    "content": "import { FC, useEffect, useMemo } from \"react\"\nimport { Progress } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { applyCenterLabelAndComponentWrapperStyle } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { BarProgressWidgetProps, WrappedBarProgressProps } from \"./interface\"\n\nexport const WrappedBarProgress: FC<WrappedBarProgressProps> = (props) => {\n  const { value, showText, strokeWidth, color, trailColor } = props\n\n  const _strokeWidth = useMemo(() => {\n    return !isNaN(Number(strokeWidth)) ? strokeWidth + \"px\" : strokeWidth\n  }, [strokeWidth])\n\n  return (\n    <Progress\n      type=\"line\"\n      percent={value}\n      showText={!showText}\n      color={color}\n      w=\"100%\"\n      trailColor={trailColor}\n      strokeWidth={_strokeWidth}\n    />\n  )\n}\n\nWrappedBarProgress.displayName = \"WrappedBarProgress\"\n\nexport const BarProgressWidget: FC<BarProgressWidgetProps> = (props) => {\n  const {\n    displayName,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    updateComponentHeight,\n  } = props\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: string) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: undefined })\n      },\n    })\n\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    displayName,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n  ])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyCenterLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedBarProgress {...props} />\n        </div>\n      </TooltipWrapper>\n    </AutoHeightContainer>\n  )\n}\n\nBarProgressWidget.displayName = \"BarProgressWidget\"\n\nexport default BarProgressWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/BarProgressWidget/eventHandlerConfig.ts",
    "content": "import { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const BAR_PROGRESS_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [],\n  methods: [\"setValue\", \"clearValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/BarProgressWidget/index.tsx",
    "content": "export { BAR_PROGRESS_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { BAR_PROGRESS_PANEL_CONFIG } from \"./panelConfig\"\nexport { BAR_PROGRESS_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/BarProgressWidget/interface.tsx",
    "content": "import { ProgressProps } from \"@illa-design/react\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedBarProgressProps\n  extends Pick<\n    ProgressProps,\n    \"showText\" | \"trailColor\" | \"color\" | \"strokeWidth\"\n  > {\n  value?: number\n}\n\nexport interface BarProgressWidgetProps\n  extends WrappedBarProgressProps,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps {}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/BarProgressWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport StrokeWidthIcon from \"@/assets/stroke-width-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst baseWidgetName = \"bar-progress\"\nexport const BAR_PROGRESS_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-Value`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.progress_percentage\"),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-showText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hide_value_label\"),\n        attrName: \"showText\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-color-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.styles\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"color\",\n            defaultValue: \"blue\",\n          },\n          {\n            id: `${baseWidgetName}-trailColor`,\n            labelName: i18n.t(\"editor.inspect.setter_label.trail_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"trailColor\",\n            defaultValue: \"gray\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.styles\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-strokeWidth`,\n            labelName: i18n.t(\"editor.inspect.setter_label.stroke_width\"),\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <StrokeWidthIcon />,\n            attrName: \"strokeWidth\",\n            defaultValue: \"4px\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/BarProgressWidget/widgetConfig.tsx",
    "content": "import LineProgressWidgetIcon from \"@/assets/widgetCover/lineProgress.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const BAR_PROGRESS_WIDGET_CONFIG: WidgetConfig = {\n  type: \"BAR_PROGRESS_WIDGET\",\n  displayName: \"barProgress\",\n  widgetName: i18n.t(\"widget.bar_progress.name\"),\n  keywords: [\"Bar Progress\", \"进度条\"],\n  icon: <LineProgressWidgetIcon />,\n  sessionType: \"PRESENTATION\",\n  w: 8,\n  h: 3,\n  version: 0,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  defaults: {\n    value: \"50\",\n    color: \"blue\",\n    trailColor: \"gray\",\n    strokeWidth: \"4px\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/BasicContainer/BasicContainer.tsx",
    "content": "import { CONTAINER_TYPE } from \"@illa-public/public-types\"\n\nexport const BasicContainerConfig = {\n  type: \"CANVAS\",\n  displayName: \"canvas\",\n  widgetName: \"canvas\",\n  containerType: CONTAINER_TYPE.EDITOR_DOT_PANEL,\n  w: 0,\n  h: 0,\n  version: 0,\n}\n\nexport const generateBasicContainerConfig = (displayName: string) => {\n  return {\n    ...BasicContainerConfig,\n    displayName,\n    widgetName: displayName,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ButtonWidget/button.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { Button } from \"@illa-design/react\"\nimport { buttonLayoutStyle } from \"@/widgetLibrary/ButtonWidget/style\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { ButtonWidgetProps, WrappedButtonProps } from \"./interface\"\n\nexport const WrappedButton: FC<WrappedButtonProps> = (props) => {\n  const {\n    text,\n    variant,\n    leftIcon,\n    rightIcon,\n    disabled,\n    loading,\n    colorScheme,\n    handleOnClick,\n  } = props\n\n  return (\n    <Button\n      disabled={disabled}\n      variant={variant}\n      leftIcon={leftIcon}\n      rightIcon={rightIcon}\n      loading={loading}\n      colorScheme={colorScheme}\n      fullWidth\n      fullHeight\n      onClick={handleOnClick}\n    >\n      {text}\n    </Button>\n  )\n}\n\nWrappedButton.displayName = \"WrappedButton\"\n\nexport const ButtonWidget: FC<ButtonWidgetProps> = (props) => {\n  const { tooltipText, triggerEventHandler } = props\n\n  const handleOnClick = useCallback(() => {\n    triggerEventHandler(\"click\")\n  }, [triggerEventHandler])\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div css={buttonLayoutStyle}>\n        <WrappedButton {...props} handleOnClick={handleOnClick} />\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nButtonWidget.displayName = \"ButtonWidget\"\nexport default ButtonWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ButtonWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const BUTTON_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.click\",\n      ),\n      value: \"click\",\n    },\n  ],\n  methods: [],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ButtonWidget/index.tsx",
    "content": "export { BUTTON_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { BUTTON_PANEL_CONFIG } from \"./panelConfig\"\nexport { BUTTON_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ButtonWidget/interface.tsx",
    "content": "import { ButtonProps } from \"@illa-design/react\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedButtonProps\n  extends Pick<\n    ButtonProps,\n    | \"variant\"\n    | \"leftIcon\"\n    | \"rightIcon\"\n    | \"disabled\"\n    | \"loading\"\n    | \"borderColor\"\n    | \"backgroundColor\"\n  > {\n  text?: string\n  handleOnClick: () => void\n  colorScheme?: string\n}\n\nexport interface ButtonWidgetProps\n  extends WrappedButtonProps,\n    BaseWidgetProps,\n    TooltipWrapperProps {}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ButtonWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { BUTTON_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/ButtonWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"button\"\nexport const BUTTON_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-Text`,\n        labelName: i18n.t(\"editor.inspect.setter_label.text\"),\n        attrName: \"text\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          BUTTON_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-formId`,\n        labelName: i18n.t(\"editor.inspect.setter_label.submit_form\"),\n        // labelDesc: i18n.t(\"xxxxx\"),\n        attrName: \"formId\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"submit\"],\n        shown: (value) => value === true,\n      },\n      {\n        id: `${baseWidgetName}-interaction-loading`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n        attrName: \"loading\",\n        placeholder: \"{{false}}\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"submit\"],\n        shown: (value) => {\n          return !value\n        },\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        placeholder: \"{{false}}\",\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"submit\"],\n        shown: (value) => !value,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        useCustomLayout: true,\n        attrName: \"hidden\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-variant`,\n        setterType: \"RADIO_GROUP_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.variant\"),\n        attrName: \"variant\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_default_value.fill\"),\n            value: \"fill\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_default_value.outline\"),\n            value: \"outline\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-bg`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ButtonWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const buttonLayoutStyle = css`\n  width: 100%;\n  height: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ButtonWidget/widgetConfig.tsx",
    "content": "import ButtonWidgetIcon from \"@/assets/widgetCover/button.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const BUTTON_WIDGET_CONFIG: WidgetConfig = {\n  type: \"BUTTON_WIDGET\",\n  displayName: \"button\",\n  widgetName: i18n.t(\"widget.button.name\"),\n  keywords: [\"Button\", \"按钮\"],\n  icon: <ButtonWidgetIcon />,\n  sessionType: \"PRESENTATION\",\n  w: 6,\n  h: 5,\n  version: 0,\n  defaults: {\n    text: i18n.t(\"widget.button.default_text\"),\n    variant: \"fill\",\n    colorScheme: \"blue\",\n    hidden: false,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CarouselWidget/carousel.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { toPath } from \"lodash-es\"\nimport {\n  FC,\n  HTMLAttributes,\n  forwardRef,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n} from \"react\"\nimport { useSelector } from \"react-redux\"\nimport Slider from \"react-slick\"\nimport { Image } from \"@illa-design/react\"\nimport NextIcon from \"@/assets/carousel/next-shadow.svg?react\"\nimport PreviousIcon from \"@/assets/carousel/prev-shadow.svg?react\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport { MediaSourceLoadContext } from \"@/utils/mediaSourceLoad\"\nimport { buttonLayoutStyle } from \"@/widgetLibrary/ButtonWidget/style\"\nimport {\n  applyDisabledStyle,\n  fullHeightStyle,\n  fullImageStyle,\n  sliderStyle,\n} from \"@/widgetLibrary/CarouselWidget/style\"\nimport { formatData } from \"@/widgetLibrary/CarouselWidget/utils\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { CarouselProps, CarouselWidgetProps } from \"./interface\"\nimport \"./slick-carousel/slick-theme.css\"\nimport \"./slick-carousel/slick.css\"\n\nconst PrevArrow: FC<HTMLAttributes<SVGSVGElement>> = (props) => {\n  const { className, style, onClick } = props\n  return <PreviousIcon className={className} style={style} onClick={onClick} />\n}\n\nconst NextArrow: FC<HTMLAttributes<SVGSVGElement>> = (props) => {\n  const { className, style, onClick } = props\n  return <NextIcon className={className} style={style} onClick={onClick} />\n}\n\nexport const Carousel = forwardRef<Slider, CarouselProps>((props, ref) => {\n  const {\n    onClickItem,\n    showArrows,\n    showDots,\n    autoPlay,\n    data,\n    interval,\n    draggable,\n    radius,\n    onChange,\n    sourceLoadErrorHandler,\n  } = props\n\n  return (\n    <Slider\n      ref={ref}\n      centerMode\n      centerPadding={\"0px\"}\n      css={sliderStyle}\n      // edit mode need to disable slider drag event\n      draggable={draggable}\n      touchMove={draggable}\n      dots={showDots}\n      arrows={showArrows}\n      autoplay={autoPlay}\n      autoplaySpeed={interval}\n      prevArrow={<PrevArrow />}\n      nextArrow={<NextArrow />}\n      lazyLoad={\"anticipated\"}\n      afterChange={onChange}\n    >\n      {data.map((item, index) => {\n        const { id, url, alt, hidden, disabled } = item\n        if (hidden) return null\n        return (\n          <div\n            css={[fullHeightStyle, applyDisabledStyle(disabled)]}\n            key={id}\n            onClick={() => {\n              !disabled && onClickItem?.(index)\n            }}\n          >\n            <Image\n              src={url}\n              objectFit={\"cover\"}\n              alt={alt}\n              radius={radius}\n              height=\"100%\"\n              width=\"100%\"\n              css={fullImageStyle}\n              onError={() => {\n                sourceLoadErrorHandler?.(url, \"CAROUSEL_WIDGET\")\n              }}\n            />\n          </div>\n        )\n      })}\n    </Slider>\n  )\n})\n\nCarousel.displayName = \"Carousel\"\n\nexport const CarouselWidget: FC<CarouselWidgetProps> = (props) => {\n  const {\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n    triggerMappedEventHandler,\n    displayName,\n    tooltipText,\n    manualData,\n    mappedData,\n    configureMode,\n    showArrows,\n    showDots,\n    autoPlay,\n    interval,\n    radius,\n  } = props\n  const carouselRef = useRef<Slider>(null)\n  const isEditMode = useSelector(getIsILLAEditMode) ?? true\n  const { sourceLoadErrorHandler } = useContext(MediaSourceLoadContext)\n\n  const finalRadius = useMemo(() => {\n    const reg = /^\\d+$/\n    const pattern = new RegExp(reg)\n    if (radius && pattern.test(radius)) {\n      return radius + \"px\"\n    }\n    return radius\n  }, [radius])\n\n  const data = useMemo(() => {\n    if (configureMode === \"static\") {\n      return manualData\n    }\n\n    return mappedData ? formatData(mappedData) : []\n  }, [manualData, mappedData, configureMode])\n\n  const handleOnClickItem = useCallback(\n    (index: number) => {\n      if (configureMode === \"static\") {\n        const paths = [\"manualData\", `${index}`, \"events\"]\n        triggerEventHandler(\n          \"click\",\n          convertPathToString(paths),\n          undefined,\n          (path) => {\n            return convertPathToString(toPath(path).slice(3))\n          },\n        )\n      } else {\n        triggerMappedEventHandler(\"click\", `mappedData.events`, index)\n      }\n    },\n    [configureMode, triggerEventHandler, triggerMappedEventHandler],\n  )\n\n  const handleOnClick = useCallback(() => {\n    triggerEventHandler(\"click\")\n  }, [triggerEventHandler])\n\n  const handleOnChange = useCallback(\n    (index: number) => {\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: { current: index },\n        },\n      ])\n    },\n    [displayName, handleUpdateMultiExecutionResult],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      slickNext: () => {\n        carouselRef.current?.slickNext()\n      },\n      slickPrevious: () => {\n        carouselRef.current?.slickPrev()\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [displayName, updateComponentRuntimeProps, deleteComponentRuntimeProps])\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div css={buttonLayoutStyle}>\n        <Carousel\n          ref={carouselRef}\n          // autoPlay change need to reload Carousel\n          draggable={!isEditMode}\n          key={Number(autoPlay)}\n          data={data ?? []}\n          handleOnClick={handleOnClick}\n          showArrows={showArrows}\n          showDots={showDots}\n          autoPlay={autoPlay}\n          interval={interval}\n          onClickItem={handleOnClickItem}\n          onChange={handleOnChange}\n          radius={finalRadius}\n          sourceLoadErrorHandler={sourceLoadErrorHandler}\n        />\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nCarouselWidget.displayName = \"CarouselWidget\"\nexport default CarouselWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CarouselWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const CAROUSEL_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.click\",\n      ),\n      value: \"click\",\n    },\n  ],\n  methods: [\"slickNext\", \"slickPrevious\"],\n}\n\nexport const generatorMappedCarouselEventHandlerConfig = (\n  baseWidgetName: string,\n  events: { label: string; value: string }[] = [],\n  labelName: string = i18n.t(\"editor.inspect.setter_label.event_handler\"),\n  attrName: string = \"events\",\n  defaultValue?: string,\n  labelDesc?: string,\n) => {\n  const config = generatorEventHandlerConfig(\n    baseWidgetName,\n    events,\n    labelName,\n    attrName,\n    defaultValue,\n    labelDesc,\n  )\n  // [INPUT_SETTER] need to be replaced with [OPTION_MAPPED_INPUT_SETTER]\n  config.childrenSetter = config.childrenSetter?.map((item) => {\n    if (item.setterType === \"INPUT_SETTER\") {\n      item.setterType = \"OPTION_MAPPED_INPUT_SETTER\"\n      item.expectedType = VALIDATION_TYPES.ARRAY\n    }\n    return item\n  })\n  return config\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CarouselWidget/index.tsx",
    "content": "export { CAROUSEL_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { CAROUSEL_PANEL_CONFIG } from \"./panelConfig\"\nexport { CAROUSEL_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CarouselWidget/interface.tsx",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface CarouselSettings {\n  id: string\n  label: string\n  url: string\n  alt?: string\n  hidden?: boolean\n  disabled?: boolean\n}\n\nexport interface MappedCarouselData {\n  labels: string[]\n  urls: string[]\n  alts?: string[]\n  isHidden?: boolean[]\n  disables?: boolean[]\n  events?: Record<string, unknown>[]\n}\n\nexport interface CarouselProps {\n  handleOnClick: () => void\n  data: CarouselSettings[]\n  autoPlay?: boolean\n  interval?: number\n  radius?: string\n  hidden?: boolean\n  disabled?: boolean\n  showArrows?: boolean\n  showDots?: boolean\n  draggable?: boolean\n  onClickItem?: (index: number) => void\n  onChange?: (index: number) => void\n  sourceLoadErrorHandler: (\n    sourceURL: string | undefined,\n    widgetType: string,\n  ) => void\n}\n\nexport interface CarouselWidgetProps\n  extends CarouselProps,\n    BaseWidgetProps,\n    TooltipWrapperProps {\n  configureMode?: \"static\" | \"dynamic\"\n  dataSources?: Array<unknown>\n  manualData?: CarouselSettings[]\n  mappedData?: MappedCarouselData\n  componentNode: ComponentTreeNode\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CarouselWidget/panelConfig.tsx",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport {\n  CAROUSEL_EVENT_HANDLER_CONFIG,\n  generatorMappedCarouselEventHandlerConfig,\n} from \"@/widgetLibrary/CarouselWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"carousel\"\nexport const CAROUSEL_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-options-mode`,\n        attrName: \"configureMode\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: i18n.t(\"widget.public.select_options.manual\"),\n            value: \"static\",\n          },\n          {\n            label: i18n.t(\"widget.public.select_options.mapped\"),\n            value: \"dynamic\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-options`,\n        useCustomLayout: true,\n        attrName: \"manualData\",\n        setterType: \"CAROUSEL_LIST_SETTER\",\n        bindAttrName: [\"configureMode\"],\n        shown: (value) => !value || value === \"static\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-options-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-ur-self-host`,\n            attrName: \"url\",\n            expectedType: VALIDATION_TYPES.STRING,\n            labelName: i18n.t(\n              \"editor.inspect.setter_content.image_list.config.image_url\",\n            ),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.img_url_array\"),\n            isSetterSingleRow: true,\n            bindAttrName: [],\n            shown: () => !isCloudVersion,\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-ur-cloud-version`,\n            attrName: \"url\",\n            expectedType: VALIDATION_TYPES.STRING,\n            labelName: i18n.t(\n              \"editor.inspect.setter_content.image_list.config.image_url\",\n            ),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.img_url_array\"),\n            isSetterSingleRow: true,\n            bindAttrName: [],\n            shown: () => isCloudVersion,\n            setterType: \"DRIVE_SOURCE_GROUP_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-alt`,\n            labelName: i18n.t(\"editor.inspect.setter_label.alt_text\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_label.alt_text_desc\"),\n            attrName: \"alt\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n          {\n            id: `${baseWidgetName}-options-hidden`,\n            setterType: \"DYNAMIC_SWITCH_SETTER\",\n            openDynamic: true,\n            labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n            useCustomLayout: true,\n            attrName: \"hidden\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n          {\n            ...generatorEventHandlerConfig(\n              baseWidgetName,\n              CAROUSEL_EVENT_HANDLER_CONFIG.events,\n              i18n.t(\"editor.inspect.setter_label.event_handler\"),\n              \"events\",\n            ),\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-option-data-sources`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_sources\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.carousel.data_source\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"configureMode\"],\n        expectedType: VALIDATION_TYPES.ARRAY,\n        shown: (value) => value === \"dynamic\",\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-options-mapped`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedData\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        bindAttrName: [\"configureMode\"],\n        shown: (value) => value === \"dynamic\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-mappedOption-labels`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"labels\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item.label}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-urls`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_content.image_list.config.image_url\",\n            ),\n            attrName: \"urls\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item.url}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-alts`,\n            labelName: i18n.t(\"editor.inspect.setter_label.alt_text\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_label.alt_text_desc\"),\n            placeholder: \"{{item.alt}}\",\n            attrName: \"alts\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-isHidden`,\n            labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n            attrName: \"isHidden\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            ...generatorMappedCarouselEventHandlerConfig(\n              baseWidgetName,\n              CAROUSEL_EVENT_HANDLER_CONFIG.events,\n              i18n.t(\"editor.inspect.setter_label.event_handler\"),\n              \"events\",\n              undefined,\n              i18n.t(\"editor.inspect.setter_tips.carousel_tips\"),\n            ),\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-disables`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disables\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-auto-play`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.auto_play\"),\n        useCustomLayout: true,\n        attrName: \"autoPlay\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.interval\"),\n        placeholder: \"{{3000}}\",\n        attrName: \"interval\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-show-dots`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_dot\"),\n        useCustomLayout: true,\n        attrName: \"showDots\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-show-arrows`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_button\"),\n        useCustomLayout: true,\n        attrName: \"showArrows\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        useCustomLayout: true,\n        attrName: \"hidden\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        isSetterSingleRow: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.styles\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            attrName: \"radius\",\n            icon: <RadioIcon />,\n            defaultValue: \"0px\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CarouselWidget/slick-carousel/slick-theme.css",
    "content": "@charset \"UTF-8\";\n/* Slider */\n.slick-loading .slick-list\n{\n    background: #fff url('./ajax-loader.gif') center center no-repeat;\n}\n\n/* Icons */\n@font-face\n{\n    font-family: 'slick';\n    font-weight: normal;\n    font-style: normal;\n\n    src: url('./fonts/slick.eot');\n    src: url('./fonts/slick.eot?#iefix') format('embedded-opentype'), url('./fonts/slick.woff') format('woff'), url('./fonts/slick.ttf') format('truetype'), url('./fonts/slick.svg#slick') format('svg');\n}\n/* Arrows */\n.slick-prev,\n.slick-next\n{\n    font-size: 0;\n    line-height: 0;\n\n    position: absolute;\n    top: 50%;\n\n    display: block;\n\n    width: 20px;\n    height: 20px;\n    padding: 0;\n    -webkit-transform: translate(0, -50%);\n    -ms-transform: translate(0, -50%);\n    transform: translate(0, -50%);\n\n    cursor: pointer;\n\n    color: transparent;\n    border: none;\n    outline: none;\n    background: transparent;\n}\n.slick-prev:hover,\n.slick-prev:focus,\n.slick-next:hover,\n.slick-next:focus\n{\n    color: transparent;\n    outline: none;\n    background: transparent;\n}\n.slick-prev:hover:before,\n.slick-prev:focus:before,\n.slick-next:hover:before,\n.slick-next:focus:before\n{\n    opacity: 1;\n}\n.slick-prev.slick-disabled:before,\n.slick-next.slick-disabled:before\n{\n    opacity: .25;\n}\n\n.slick-prev:before,\n.slick-next:before\n{\n    font-family: 'slick';\n    font-size: 20px;\n    line-height: 1;\n\n    opacity: .75;\n    color: white;\n\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n}\n\n.slick-prev\n{\n    left: -25px;\n}\n[dir='rtl'] .slick-prev\n{\n    right: -25px;\n    left: auto;\n}\n.slick-prev:before\n{\n    content: '←';\n}\n[dir='rtl'] .slick-prev:before\n{\n    content: '→';\n}\n\n.slick-next\n{\n    right: -25px;\n}\n[dir='rtl'] .slick-next\n{\n    right: auto;\n    left: -25px;\n}\n.slick-next:before\n{\n    content: '→';\n}\n[dir='rtl'] .slick-next:before\n{\n    content: '←';\n}\n\n/* Dots */\n.slick-dotted.slick-slider\n{\n    margin-bottom: 30px;\n}\n\n.slick-dots\n{\n    position: absolute;\n    bottom: -25px;\n\n    display: block;\n\n    width: 100%;\n    padding: 0;\n    margin: 0;\n\n    list-style: none;\n\n    text-align: center;\n}\n.slick-dots li\n{\n    position: relative;\n\n    display: inline-block;\n\n    width: 20px;\n    height: 20px;\n    margin: 0 5px;\n    padding: 0;\n\n    cursor: pointer;\n}\n.slick-dots li button\n{\n    font-size: 0;\n    line-height: 0;\n\n    display: block;\n\n    width: 20px;\n    height: 20px;\n    padding: 5px;\n\n    cursor: pointer;\n\n    color: transparent;\n    border: 0;\n    outline: none;\n    background: transparent;\n}\n.slick-dots li button:hover,\n.slick-dots li button:focus\n{\n    outline: none;\n}\n.slick-dots li button:hover:before,\n.slick-dots li button:focus:before\n{\n    opacity: 1;\n}\n.slick-dots li button:before\n{\n    font-family: 'slick';\n    font-size: 6px;\n    line-height: 20px;\n\n    position: absolute;\n    top: 0;\n    left: 0;\n\n    width: 20px;\n    height: 20px;\n\n    content: '•';\n    text-align: center;\n\n    opacity: .25;\n    color: black;\n\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n}\n.slick-dots li.slick-active button:before\n{\n    opacity: .75;\n    color: black;\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CarouselWidget/slick-carousel/slick.css",
    "content": "/* Slider */\n.slick-slider\n{\n    position: relative;\n\n    display: block;\n    box-sizing: border-box;\n\n    -webkit-user-select: none;\n       -moz-user-select: none;\n        -ms-user-select: none;\n            user-select: none;\n\n    -webkit-touch-callout: none;\n    -khtml-user-select: none;\n    -ms-touch-action: pan-y;\n        touch-action: pan-y;\n    -webkit-tap-highlight-color: transparent;\n}\n\n.slick-list\n{\n    position: relative;\n\n    display: block;\n    overflow: hidden;\n\n    margin: 0;\n    padding: 0;\n}\n.slick-list:focus\n{\n    outline: none;\n}\n.slick-list.dragging\n{\n    cursor: pointer;\n    cursor: hand;\n}\n\n.slick-slider .slick-track,\n.slick-slider .slick-list\n{\n    -webkit-transform: translate3d(0, 0, 0);\n       -moz-transform: translate3d(0, 0, 0);\n        -ms-transform: translate3d(0, 0, 0);\n         -o-transform: translate3d(0, 0, 0);\n            transform: translate3d(0, 0, 0);\n}\n\n.slick-track\n{\n    position: relative;\n    top: 0;\n    left: 0;\n\n    display: block;\n    margin-left: auto;\n    margin-right: auto;\n}\n.slick-track:before,\n.slick-track:after\n{\n    display: table;\n\n    content: '';\n}\n.slick-track:after\n{\n    clear: both;\n}\n.slick-loading .slick-track\n{\n    visibility: hidden;\n}\n\n.slick-slide\n{\n    display: none;\n    float: left;\n\n    height: 100%;\n    min-height: 1px;\n}\n[dir='rtl'] .slick-slide\n{\n    float: right;\n}\n.slick-slide img\n{\n    display: block;\n}\n.slick-slide.slick-loading img\n{\n    display: none;\n}\n.slick-slide.dragging img\n{\n    pointer-events: none;\n}\n.slick-initialized .slick-slide\n{\n    display: block;\n}\n.slick-loading .slick-slide\n{\n    visibility: hidden;\n}\n.slick-vertical .slick-slide\n{\n    display: block;\n\n    height: auto;\n\n    border: 1px solid transparent;\n}\n.slick-arrow.slick-hidden {\n    display: none;\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CarouselWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport point from \"@/assets/carousel/point.svg\"\n\nexport const sliderStyle = css`\n  height: 100%;\n\n  .slick-track {\n    inset-inline-start: 0;\n  }\n\n  .slick-dotted.slick-slider {\n    margin-bottom: 30px;\n  }\n\n  .slick-dots {\n    bottom: 0;\n    z-index: 1;\n\n    position: absolute;\n    display: block;\n    width: 100%;\n    padding: 16px 0 8px;\n    margin: 0;\n    list-style: none;\n    text-align: center;\n    background: linear-gradient(\n      180deg,\n      rgba(0, 0, 0, 0) 0%,\n      rgba(0, 0, 0, 0.16) 100%\n    );\n  }\n\n  .slick-dots li {\n    position: relative;\n    display: inline-flex;\n    justify-content: center;\n    align-items: center;\n\n    width: 8px;\n    height: 12px;\n    margin: 0 2px;\n  }\n\n  .slick-dots li button {\n    font-size: 0;\n    line-height: 0;\n\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    width: 10px;\n    height: 10px;\n    padding: 0;\n    color: transparent;\n    border: 0;\n    outline: none;\n    background: transparent;\n    transition: opacity 0.2s;\n  }\n\n  .slick-dots li button:focus:before {\n    opacity: 0.25;\n  }\n\n  .slick-dots li button:before {\n    transition: opacity 0.2s;\n    font-size: 6px;\n    line-height: 20px;\n\n    scale: 1;\n    width: 4px;\n    height: 4px;\n    content: \"\";\n\n    opacity: 0.25;\n    color: white;\n    top: unset;\n    left: unset;\n    border-radius: 50%;\n    background-image: url(${point});\n\n    &:hover {\n      opacity: 1;\n    }\n  }\n\n  .slick-dots li.slick-active button {\n    opacity: 0.75;\n    color: white;\n\n    &:before {\n      opacity: 1;\n      color: white;\n    }\n  }\n\n  .slick-prev,\n  .slick-next {\n    z-index: 1;\n    font-size: 12px;\n    width: 16px;\n    height: 16px;\n    color: white;\n    border-radius: 50%;\n    padding: 2px;\n    transition: background 0.2s;\n\n    &:hover {\n      color: white;\n      background: ${getColor(\"blackAlpha\", \"07\")};\n    }\n  }\n\n  .slick-prev {\n    left: 8px;\n  }\n\n  .slick-next {\n    right: 8px;\n  }\n\n  .slick-list,\n  .slick-track,\n  .slick-slide > div {\n    height: 100%;\n  }\n`\nexport const dotStyle = css`\n  width: 4px;\n  height: 4px;\n  cursor: pointer;\n  background: white;\n  opacity: 0.25;\n`\n\nexport const fullHeightStyle = css`\n  height: 100%;\n`\n\nexport const fullImageStyle = css`\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n`\n\nexport const applyDisabledStyle = (disabled?: boolean) => {\n  if (disabled) {\n    return css`\n      cursor: not-allowed;\n    `\n  }\n  return css``\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CarouselWidget/utils.ts",
    "content": "import { v4 } from \"uuid\"\nimport {\n  CarouselSettings,\n  MappedCarouselData,\n} from \"@/widgetLibrary/CarouselWidget/interface\"\n\nexport const generateItemId = () => `Image-${v4()}`\n\nexport const formatData = (mappedData: MappedCarouselData) => {\n  const url = mappedData.urls ?? []\n  const label = mappedData.labels ?? []\n  const hidden = mappedData.isHidden ?? []\n  const disables = mappedData.disables ?? []\n  const alts = mappedData.alts ?? []\n\n  const maxLength = Math.max(\n    url.length,\n    label.length,\n    hidden.length,\n    disables.length,\n  )\n  const options: CarouselSettings[] = []\n  for (let i = 0; i < maxLength; i++) {\n    options.push({\n      id: generateItemId(),\n      url: url[i],\n      label: label[i],\n      hidden: hidden[i],\n      disabled: disables[i],\n      alt: alts[i],\n    })\n  }\n  return options\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CarouselWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport CarouselWidgetIcon from \"@/assets/widgetCover/carousel.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const CAROUSEL_DEFAULT_IMAGE =\n  \"https://images.unsplash.com/photo-1506105524407-94b39b1e7415?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxjb2xsZWN0aW9uLXBhZ2V8MTB8UUZ6YlEwZ0RodlF8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60\"\n\nconst originData = [\n  {\n    id: `Image-${v4()}`,\n    label: \"Image 1\",\n    url: \"https://images.unsplash.com/photo-1506105524407-94b39b1e7415?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxjb2xsZWN0aW9uLXBhZ2V8MTB8UUZ6YlEwZ0RodlF8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60\",\n  },\n  {\n    id: `Image-${v4()}`,\n    label: \"Image 2\",\n    url: \"https://images.unsplash.com/photo-1528074529665-982494e88f39?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxjb2xsZWN0aW9uLXBhZ2V8N3xRRnpiUTBnRGh2UXx8ZW58MHx8fHw%3D&auto=format&fit=crop&w=800&q=60\",\n  },\n  {\n    id: `Image-${v4()}`,\n    label: \"Image 3\",\n    url: \"https://images.unsplash.com/photo-1629044297557-81cbc9d05b8d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxjb2xsZWN0aW9uLXBhZ2V8MTl8UUZ6YlEwZ0RodlF8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60\",\n  },\n]\n\nexport const CAROUSEL_WIDGET_CONFIG: WidgetConfig = {\n  type: \"CAROUSEL_WIDGET\",\n  displayName: \"carousel\",\n  widgetName: i18n.t(\"widget.carousel.name\"),\n  keywords: [\"Carousel\", \"轮播\"],\n  icon: <CarouselWidgetIcon />,\n  sessionType: \"PRESENTATION\",\n  h: 30,\n  w: 20,\n  version: 0,\n  defaults: {\n    configureMode: \"static\",\n    radius: \"0px\",\n    showArrows: true,\n    showDots: true,\n    hidden: false,\n    manualData: originData,\n    dataSources: `{{${JSON.stringify(originData, null, \"  \")}}}`,\n    interval: \"{{3000}}\",\n    current: 0,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CascaderWidget/cascader.tsx",
    "content": "import { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { Cascader } from \"@illa-design/react\"\nimport {\n  CascaderWidgetProps,\n  WrappedCascaderWidgetProps,\n} from \"@/widgetLibrary/CascaderWidget/interface\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { applyLabelAndComponentWrapperStyle } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\n\nexport const WrappedCascaderWidget: FC<WrappedCascaderWidgetProps> = (\n  props,\n) => {\n  const {\n    options,\n    value = [],\n    expandTrigger,\n    placeholder,\n    allowClear,\n    handleOnChange,\n    handleOnFocus,\n    handleOnBlur,\n    handleUpdateMultiExecutionResult,\n    displayName,\n    disabled,\n    readOnly,\n  } = props\n  const handleChangeValue = useCallback(\n    (value: null | (string | string[])[]) => {\n      if (!disabled && !readOnly)\n        new Promise((resolve) => {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                value,\n              },\n            },\n          ])\n          resolve(value)\n        }).then(() => {\n          handleOnChange?.()\n        })\n    },\n    [\n      disabled,\n      displayName,\n      handleOnChange,\n      handleUpdateMultiExecutionResult,\n      readOnly,\n    ],\n  )\n\n  const handleFocus = useCallback(() => {\n    if (!disabled) {\n      handleOnFocus?.()\n    }\n  }, [disabled, handleOnFocus])\n\n  const handleBlur = useCallback(() => {\n    if (!disabled) {\n      handleOnBlur?.()\n    }\n  }, [disabled, handleOnBlur])\n\n  return (\n    <Cascader\n      options={options}\n      value={value}\n      trigger={expandTrigger}\n      placeholder={placeholder}\n      allowClear={allowClear}\n      onChange={handleChangeValue}\n      onFocus={handleFocus}\n      onBlur={handleBlur}\n      disabled={disabled || readOnly}\n      showSearch\n    />\n  )\n}\n\nexport const CascaderWidget: FC<CascaderWidgetProps> = (props) => {\n  const {\n    dataSource = [],\n    updateComponentHeight,\n    tooltipText,\n    labelPosition,\n    labelFull,\n    labelAlign,\n    labelWidth,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    label,\n    dataSourceMode,\n    dataSourceJS = [],\n    value,\n    handleUpdateMultiExecutionResult,\n    displayName,\n    placeholder,\n    expandTrigger,\n    allowClear,\n    disabled,\n    readOnly,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    triggerEventHandler,\n  } = props\n\n  const finalOptions = useMemo(() => {\n    return dataSourceMode === \"dynamic\" ? dataSourceJS || [] : dataSource || []\n  }, [dataSource, dataSourceJS, dataSourceMode])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: any) => {\n        handleUpdateDsl({\n          value: Array.isArray(value) ? value : [],\n        })\n      },\n      clearValue: () => {\n        handleUpdateDsl({\n          value: [],\n        })\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  const handleOnFocus = useCallback(() => {\n    triggerEventHandler(\"focus\")\n  }, [triggerEventHandler])\n\n  const handleOnBlur = useCallback(() => {\n    triggerEventHandler(\"blur\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedCascaderWidget\n            options={Array.isArray(finalOptions) ? finalOptions : []}\n            value={value}\n            handleUpdateMultiExecutionResult={handleUpdateMultiExecutionResult}\n            displayName={displayName}\n            placeholder={placeholder}\n            expandTrigger={expandTrigger}\n            allowClear={allowClear}\n            handleOnChange={handleOnChange}\n            handleOnFocus={handleOnFocus}\n            handleOnBlur={handleOnBlur}\n            disabled={disabled}\n            readOnly={readOnly}\n          />\n        </div>\n      </TooltipWrapper>\n    </AutoHeightContainer>\n  )\n}\n\nexport default CascaderWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CascaderWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const CASCADER_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.focus\",\n      ),\n      value: \"focus\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.blur\",\n      ),\n      value: \"blur\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CascaderWidget/index.ts",
    "content": "export * from \"./widgetConfig\"\nexport * from \"./panelConfig\"\nexport * from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CascaderWidget/interface.ts",
    "content": "import { CascaderProps } from \"@illa-design/react\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedCascaderWidgetProps\n  extends Pick<\n    CascaderProps,\n    | \"options\"\n    | \"value\"\n    | \"placeholder\"\n    | \"allowClear\"\n    | \"disabled\"\n    | \"aria-readonly\"\n  > {\n  displayName: string\n  expandTrigger: CascaderProps[\"trigger\"]\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n  handleOnFocus?: () => void\n  handleOnBlur?: () => void\n  readOnly?: boolean\n}\n\nexport interface CascaderWidgetProps\n  extends Omit<\n      WrappedCascaderWidgetProps,\n      \"handleOnChange\" | \"handleOnFocus\" | \"handleOnBlur\"\n    >,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps {\n  dataSource?: CascaderProps[\"options\"]\n  dataSourceJS?: CascaderProps[\"options\"]\n  dataSourceMode?: \"dynamic\" | \"select\"\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CascaderWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { CASCADER_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/CascaderWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"cascader\"\nexport const CASCADER_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-options`,\n    groupName: i18n.t(\"editor.inspect.setter_group.options\"),\n    children: [\n      {\n        id: `${baseWidgetName}-data-source`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.cascader_data\"),\n        useCustomLayout: true,\n        attrName: \"dataSource\",\n        setterType: \"DATA_SOURCE_SELECT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n      },\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n      },\n      {\n        id: `${baseWidgetName}-basic-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"placeholder\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          CASCADER_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readOnly\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        attrName: \"allowClear\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-expansion-method`,\n        labelName: i18n.t(\"editor.inspect.setter_label.expansion_method\"),\n        attrName: \"expandTrigger\",\n        isSetterSingleRow: true,\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: \"Click\",\n            value: \"click\",\n          },\n          {\n            label: \"Hover\",\n            value: \"hover\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"false\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CascaderWidget/widgetConfig.tsx",
    "content": "import CascaderWidgetIcon from \"@/assets/widgetCover/cascader.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const CASCADER_WIDGET_CONFIG: WidgetConfig = {\n  type: \"CASCADER_WIDGET\",\n  displayName: \"cascader\",\n  widgetName: i18n.t(\"widget.cascader.name\"),\n  keywords: [\"cascader\", \"级联选择\"],\n  icon: <CascaderWidgetIcon />,\n  sessionType: \"SELECT\",\n  w: 6,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    dataSourceJS: `{{[\n  {\n    value: \"media_source_1\",\n    label: \"Media Source 1\",\n    children: [\n      {\n        value: \"campaign_1-1\",\n        label: \"campaign 1-1\",\n      },\n      {\n        value: \"campaign_1-2\",\n        label: \"campaign 1-2\",\n      },\n      {\n        value: \"campaign_1-3\",\n        label: \"campaign 1-3\",\n        disabled: true,\n      }\n      ]\n  },\n  {\n    value: \"media_source_2\",\n    label: \"Media Source 2\",\n    children: [\n      {\n        value: \"campaign_2-1\",\n        label: \"campaign 2-1\",\n      },\n      {\n        value: \"campaign_2-2\",\n        label: \"campaign 2-2\",\n      },\n      {\n        value: \"campaign_2-3\",\n        label: \"campaign 2-3\"\n      }\n      ]\n  }\n]}}`,\n    value: `{{[\"media_source_1\",\"campaign_1-1\"]}}`,\n    placeholder: \"\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    dataSourceMode: \"dynamic\",\n    expandTrigger: \"click\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChartWidget/chart.tsx",
    "content": "import {\n  ArcElement,\n  BarController,\n  BarElement,\n  CategoryScale,\n  ChartData,\n  ChartDataset,\n  Chart as ChartJS,\n  ChartOptions,\n  DoughnutController,\n  Filler,\n  Legend,\n  LineController,\n  LineElement,\n  LinearScale,\n  PieController,\n  PointElement,\n  RadarController,\n  RadialLinearScale,\n  ScatterController,\n  Title,\n  Tooltip,\n} from \"chart.js\"\nimport { get, groupBy as groupByFunc } from \"lodash-es\"\nimport { FC, useMemo, useRef } from \"react\"\nimport { Doughnut, Pie, Radar, Chart as ReactChart } from \"react-chartjs-2\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\nimport { CHART_COLOR_TYPE_CONFIG } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/listItem\"\nimport { formatDataAsObject } from \"@/utils/formatData\"\nimport {\n  ChartWidgetProps,\n  WrappedChartProps,\n} from \"@/widgetLibrary/ChartWidget/interface\"\nimport {\n  formatData,\n  getDateFormatLabel,\n  typeWithDiffColor,\n  typeWithNoAxis,\n} from \"@/widgetLibrary/ChartWidget/utils\"\nimport { chartContainerStyle } from \"./style\"\n\nChartJS.register(\n  /** Bar chart**/\n  BarElement,\n  BarController,\n  /** Line chart**/\n  LineElement,\n  LineController,\n  PointElement,\n  /** Pie chart**/\n  PieController,\n  ArcElement,\n  /** Scatter chart**/\n  ScatterController,\n  /** Doughnut **/\n  DoughnutController,\n  /** Radar **/\n  RadarController,\n  RadialLinearScale,\n  /**Other**/\n  Title,\n  Tooltip,\n  Legend,\n  CategoryScale,\n  LinearScale,\n  Filler,\n)\n\nexport const Chart: FC<ChartWidgetProps> = (props) => {\n  const {\n    datasets,\n    xAxis,\n    chartType,\n    chartTitle,\n    xAxisName,\n    yAxisName,\n    direction,\n    isStack,\n    legendPosition,\n    gridLineColor,\n    xType,\n    dateFormat,\n  } = props\n  const data = useMemo(() => {\n    let curXAis = xAxis\n    if (xType === \"time\") {\n      curXAis = xAxis.map((x) => getDateFormatLabel(x, dateFormat))\n    }\n    return {\n      labels: curXAis,\n      datasets,\n    }\n  }, [datasets, dateFormat, xAxis, xType])\n\n  const options: ChartOptions = useMemo(() => {\n    const horizontalColor =\n      !typeWithNoAxis(chartType) && direction === \"y\"\n        ? gridLineColor\n        : undefined\n    const verticalColor =\n      !typeWithNoAxis(chartType) && direction === \"x\"\n        ? gridLineColor\n        : undefined\n    return {\n      responsive: true,\n      maintainAspectRatio: false,\n      indexAxis: !typeWithNoAxis(chartType) ? direction : undefined,\n      scales: {\n        x: {\n          display: !typeWithNoAxis(chartType),\n          stacked: !typeWithNoAxis(chartType) && isStack,\n          title: {\n            display: !!xAxisName,\n            text: xAxisName,\n            color: globalColor(`--${illaPrefix}-grayBlue-02`),\n            font: {\n              size: 12,\n            },\n          },\n          grid: {\n            color:\n              horizontalColor || globalColor(`--${illaPrefix}-grayBlue-09`),\n            borderColor: globalColor(`--${illaPrefix}-grayBlue-09`),\n            tickColor: globalColor(`--${illaPrefix}-grayBlue-04`),\n          },\n          ticks: {\n            color: globalColor(`--${illaPrefix}-grayBlue-02`),\n            font: {\n              size: 12,\n              weight: \"bold\",\n            },\n          },\n        },\n        y: {\n          display: !typeWithNoAxis(chartType),\n          stacked: !typeWithNoAxis(chartType) && isStack,\n          title: {\n            display: !!yAxisName,\n            text: yAxisName,\n            color: globalColor(`--${illaPrefix}-grayBlue-02`),\n            font: {\n              size: 12,\n            },\n          },\n          grid: {\n            color: verticalColor || globalColor(`--${illaPrefix}-grayBlue-09`),\n            borderColor: globalColor(`--${illaPrefix}-grayBlue-09`),\n            tickColor: globalColor(`--${illaPrefix}-grayBlue-04`),\n          },\n          ticks: {\n            color: globalColor(`--${illaPrefix}-grayBlue-02`),\n            font: {\n              size: 12,\n              weight: \"bold\",\n            },\n          },\n        },\n      },\n      plugins: {\n        title: {\n          display: !!chartTitle,\n          text: chartTitle,\n          color: globalColor(`--${illaPrefix}-grayBlue-02`),\n          font: {\n            size: 16,\n          },\n        },\n        legend: {\n          display: legendPosition !== \"hidden\",\n          labels: {\n            boxWidth: 20,\n            boxHeight: 4,\n          },\n          position: legendPosition !== \"hidden\" ? legendPosition : undefined,\n        },\n      },\n    }\n  }, [\n    chartTitle,\n    chartType,\n    direction,\n    gridLineColor,\n    isStack,\n    legendPosition,\n    xAxisName,\n    yAxisName,\n  ])\n\n  const chartRef = useRef()\n\n  const finalType = useMemo(() => {\n    if (chartType === \"scatter\") {\n      return \"line\"\n    }\n    return chartType\n  }, [chartType])\n\n  switch (finalType) {\n    default:\n    case \"bar\":\n    case \"line\":\n      return (\n        <ReactChart\n          ref={chartRef}\n          type={finalType}\n          datasetIdKey=\"id\"\n          data={data}\n          options={options}\n        />\n      )\n    case \"radar\":\n      return (\n        <Radar\n          datasetIdKey=\"id\"\n          data={data as ChartData<\"radar\", number | null[], string>}\n          options={options as ChartOptions<\"radar\">}\n        />\n      )\n    case \"doughnut\":\n      return (\n        <Doughnut\n          datasetIdKey=\"id\"\n          data={data as ChartData<\"doughnut\", number | null[], string>}\n          options={options as ChartOptions<\"doughnut\">}\n        />\n      )\n    case \"pie\":\n      return (\n        <Pie\n          datasetIdKey=\"id\"\n          data={data as ChartData<\"pie\", number | null[], string>}\n          options={options as ChartOptions<\"pie\">}\n        />\n      )\n  }\n}\n\nexport const ChartWidget: FC<WrappedChartProps> = (props) => {\n  const {\n    dataSource,\n    dataSourceJS,\n    dataSourceMode,\n    chartType,\n    xAxis,\n    groupBy,\n    chartTitle,\n    xAxisName,\n    yAxisName,\n    datasets,\n    backgroundColor = \"white\",\n  } = props\n\n  const realDataSourceArray = useMemo(() => {\n    if (dataSourceMode === \"dynamic\") {\n      return dataSourceJS ? dataSourceJS : []\n    }\n    return dataSource ? dataSource : []\n  }, [dataSource, dataSourceJS, dataSourceMode])\n\n  const realDataSourceObject = useMemo(() => {\n    if (dataSourceMode === \"dynamic\") {\n      return dataSourceJS ? formatDataAsObject(dataSourceJS) : {}\n    }\n    return dataSource ? formatDataAsObject(dataSource) : {}\n  }, [dataSource, dataSourceJS, dataSourceMode])\n\n  const realXAxis = useMemo(() => {\n    const xAxisArray = get(realDataSourceObject, xAxis, [])\n    if (Array.isArray(xAxisArray)) {\n      return Array.from(new Set(xAxisArray)) as string[]\n    }\n    return []\n  }, [realDataSourceObject, xAxis])\n\n  const realDatasets: ChartDataset[] = useMemo(() => {\n    if (!Array.isArray(datasets)) return []\n    const result = datasets\n      .filter((dataset) => {\n        if (dataset.isHidden == undefined) return true\n        return !dataset.isHidden\n      })\n      .map((dataset) => {\n        const { datasetValues, type, datasetName, color, aggregationMethod } =\n          dataset\n        let finalColor: string | string[] = color\n        if (groupBy || typeWithDiffColor(chartType)) {\n          finalColor = get(\n            CHART_COLOR_TYPE_CONFIG,\n            color,\n            CHART_COLOR_TYPE_CONFIG[\"illa-preset\"],\n          )\n        }\n        if (chartType === \"radar\") {\n          finalColor = `${finalColor}77`\n        }\n        let data: number[] = []\n        if (!groupBy || typeWithNoAxis(chartType)) {\n          const formatDataSources = groupByFunc(realDataSourceArray, xAxis)\n          data = formatData(\n            formatDataSources,\n            datasetValues,\n            aggregationMethod,\n            realXAxis,\n          )\n        } else {\n          const groupedData = groupByFunc(realDataSourceArray, groupBy)\n\n          const relationData: Record<string, any> = {}\n          Object.keys(groupedData).forEach((key) => {\n            const value = groupedData[key]\n\n            const groupData = groupByFunc(value, xAxis)\n\n            const formatDataArray = formatData(\n              groupData,\n              datasetValues,\n              aggregationMethod,\n              realXAxis,\n            )\n            relationData[key] = formatDataArray\n          })\n\n          const groupByColor = get(\n            CHART_COLOR_TYPE_CONFIG,\n            color,\n            CHART_COLOR_TYPE_CONFIG[\"illa-preset\"],\n          ) as string[]\n\n          return Object.keys(relationData).map((k, i) => {\n            const value = relationData[k]\n            return {\n              label:\n                Object.keys(groupedData).length > 1\n                  ? `${datasetName}(${k})`\n                  : datasetName,\n              data: Object.values(value) as number[],\n              type,\n              borderColor: groupByColor[i % groupByColor.length],\n              backgroundColor: groupByColor[i % groupByColor.length],\n            }\n          })\n        }\n        let finalVal = {\n          label: datasetName,\n          data: data,\n          type,\n          borderColor: finalColor,\n          backgroundColor: finalColor,\n          fill: false,\n        }\n        if (chartType === \"radar\") {\n          finalVal[\"fill\"] = true\n        }\n        return finalVal\n      })\n      .flat()\n    if (typeWithNoAxis(chartType)) {\n      return result.length > 0 ? [result[result.length - 1]] : []\n    } else {\n      return result\n    }\n  }, [chartType, datasets, groupBy, realDataSourceArray, realXAxis, xAxis])\n\n  return (\n    <div css={chartContainerStyle(backgroundColor)}>\n      <Chart\n        {...props}\n        xAxis={realXAxis}\n        datasets={realDatasets}\n        chartType={chartType}\n        chartTitle={chartTitle}\n        xAxisName={xAxisName}\n        yAxisName={yAxisName}\n      />\n    </div>\n  )\n}\n\nChartWidget.displayName = \"ChartWidget\"\nexport default ChartWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChartWidget/index.tsx",
    "content": "export * from \"./interface\"\nexport { CHART_WIDGET_CONFIG, CHART_WIDGET_V2_CONFIG } from \"./widgetConfig\"\nexport { CHART_PANEL_CONFIG } from \"./panelConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChartWidget/interface.tsx",
    "content": "import { ChartDataset, ChartType } from \"chart.js\"\nimport { ChartDatasetShape } from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/chartDatasetsSetter/interface\"\n\nexport interface WrappedChartProps\n  extends Omit<ChartWidgetProps, \"xAxis\" | \"datasets\"> {\n  dataSource: any[]\n  dataSourceJS: any[]\n  dataSourceMode: \"select\" | \"dynamic\"\n  xAxis: string\n  datasets: ChartDatasetShape[]\n}\n\nexport interface ChartWidgetProps {\n  xAxis: string[]\n  groupBy?: string\n  chartTitle: string\n  xAxisName: string\n  yAxisName: string\n  chartType: ChartType\n  datasets: ChartDataset[]\n  direction: \"x\" | \"y\"\n  isStack?: boolean\n  legendPosition?: \"top\" | \"bottom\" | \"left\" | \"right\" | \"hidden\"\n  gridLineColor?: string\n  backgroundColor?: string\n  xType?: \"default\" | \"time\"\n  dateFormat?: string\n}\n\nexport enum CHART_DATASET_AGGREGATION_METHOD {\n  \"SUM\" = \"SUM\",\n  \"COUNT\" = \"COUNT\",\n  \"AVERAGE\" = \"AVERAGE\",\n  \"MEDIAN\" = \"MEDIAN\",\n  \"MIN\" = \"MIN\",\n  \"MAX\" = \"MAX\",\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChartWidget/panelConfig.tsx",
    "content": "import { ChartType } from \"chart.js\"\nimport {\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n  ReduceIcon,\n  VerticalEndIcon,\n  VerticalStartIcon,\n} from \"@illa-design/react\"\nimport BarChartIcon from \"@/assets/chart/bar-chart.svg?react\"\nimport LineChartIcon from \"@/assets/chart/line-chart.svg?react\"\nimport ScatterPlotIcon from \"@/assets/chart/scatter-plot.svg?react\"\nimport RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport {\n  chartTypeIconCss,\n  chartTypeStringCss,\n} from \"@/page/App/components/InspectPanel/PanelSetters/ChartSetter/style\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { CHART_DATASET_AGGREGATION_METHOD } from \"@/widgetLibrary/ChartWidget/interface\"\nimport { typeWithNoAxis } from \"./utils\"\n\nconst datasetsTypeOption = [\n  {\n    label: (\n      <span>\n        <BarChartIcon css={chartTypeIconCss} />\n        <span css={chartTypeStringCss}>\n          {i18n.t(\"editor.inspect.setter_content.chart_type.bar\")}\n        </span>\n      </span>\n    ),\n    value: \"bar\",\n  },\n  {\n    label: (\n      <div>\n        <LineChartIcon css={chartTypeIconCss} />\n        <span css={chartTypeStringCss}>\n          {i18n.t(\"editor.inspect.setter_content.chart_type.line\")}\n        </span>\n      </div>\n    ),\n    value: \"line\",\n  },\n  {\n    label: (\n      <div>\n        <ScatterPlotIcon css={chartTypeIconCss} />\n        <span css={chartTypeStringCss}>\n          {i18n.t(\"editor.inspect.setter_content.chart_type.scatterplot\")}\n        </span>\n      </div>\n    ),\n    value: \"scatter\",\n  },\n]\n\nconst aggregationMethodOptions = [\n  CHART_DATASET_AGGREGATION_METHOD.SUM,\n  CHART_DATASET_AGGREGATION_METHOD.COUNT,\n  CHART_DATASET_AGGREGATION_METHOD.MAX,\n  CHART_DATASET_AGGREGATION_METHOD.MIN,\n  CHART_DATASET_AGGREGATION_METHOD.AVERAGE,\n  CHART_DATASET_AGGREGATION_METHOD.MEDIAN,\n]\n\nconst baseWidgetName = \"chart\"\nexport const CHART_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-data`,\n    groupName: i18n.t(\"editor.inspect.setter_group.data\"),\n    children: [\n      {\n        id: `${baseWidgetName}-data-source`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        useCustomLayout: true,\n        attrName: \"dataSource\",\n        setterType: \"DATA_SOURCE_SELECT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-data-chart-type`,\n        labelName: i18n.t(\"editor.inspect.setter_label.chart_type\"),\n        attrName: \"chartType\",\n        setterType: \"CHART_TYPE_SELECT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-data-direction`,\n        labelName: i18n.t(\"editor.inspect.setter_label.chart.direction\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.chart.direction\"),\n        attrName: \"direction\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"chartType\"],\n        shown: (chartType: ChartType) => !typeWithNoAxis(chartType),\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.chart.direction.vertical\",\n            ),\n            value: \"x\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.chart.direction.horizontal\",\n            ),\n            value: \"y\",\n          },\n        ],\n      },\n      // x axis or horizontal x axis\n      {\n        id: `${baseWidgetName}-data-x-asis`,\n        labelName: i18n.t(\"editor.inspect.setter_label.x_axis_value\"),\n        isSetterSingleRow: true,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"xAxis\",\n        setterType: \"CHART_KEYS_DYNAMIC_SELECT_SETTER\",\n        bindAttrName: [\"chartType\", \"direction\"],\n        shown: (chartType: ChartType, direction: \"x\" | \"y\") => {\n          if (\n            typeWithNoAxis(chartType) ||\n            (!typeWithNoAxis(chartType) && direction === \"y\")\n          )\n            return false\n          return true\n        },\n      },\n      {\n        id: `${baseWidgetName}-data-x-asis-horizontal`,\n        labelName: i18n.t(\"editor.inspect.setter_label.chart.y-axis_value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.chart.y-axis_value\"),\n        isSetterSingleRow: true,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"xAxis\",\n        setterType: \"CHART_KEYS_DYNAMIC_SELECT_SETTER\",\n        bindAttrName: [\"chartType\", \"direction\"],\n        shown: (chartType: ChartType, direction: \"x\" | \"y\") => {\n          if (!typeWithNoAxis(chartType) && direction === \"y\") return true\n          return false\n        },\n      },\n      {\n        id: `${baseWidgetName}-data-value-labels`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value_labels\"),\n        isSetterSingleRow: true,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"xAxis\",\n        setterType: \"CHART_KEYS_DYNAMIC_SELECT_SETTER\",\n        bindAttrName: [\"chartType\"],\n        shown: (chartType: string) => typeWithNoAxis(chartType),\n      },\n      {\n        id: `${baseWidgetName}-data-group-by`,\n        labelName: i18n.t(\"editor.inspect.setter_label.group_by\"),\n        isSetterSingleRow: true,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"groupBy\",\n        setterType: \"CHART_KEYS_DYNAMIC_SELECT_SETTER\",\n        allowClear: true,\n        bindAttrName: [\"chartType\"],\n        shown: (chartType: string) => !typeWithNoAxis(chartType),\n      },\n      {\n        id: `${baseWidgetName}-data-isStack`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.chart.stack_grouped_data\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.chart.stack_grouped_data\",\n        ),\n        attrName: \"isStack\",\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"chartType\", \"groupBy\"],\n        shown: (chartType: string, groupBy: string) =>\n          !typeWithNoAxis(chartType) && !!groupBy,\n      },\n      {\n        id: `${baseWidgetName}-data-datasets`,\n        labelName: i18n.t(\"editor.inspect.setter_label.datasets\"),\n        useCustomLayout: true,\n        attrName: \"datasets\",\n        setterType: \"CHART_DATASETS_SETTER\",\n        bindAttrName: [\"chartType\"],\n        shown: (chartType: string) => !typeWithNoAxis(chartType),\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-datasets-name`,\n            labelName: i18n.t(\"editor.inspect.setter_label.dataset.name\"),\n            isSetterSingleRow: true,\n            attrName: \"datasetName\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-datasets-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.dataset.value\"),\n            isSetterSingleRow: true,\n            useCustomLayout: true,\n            openDynamic: true,\n            attrName: \"datasetValues\",\n            setterType: \"CHART_KEYS_DYNAMIC_SELECT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-aggregation-method`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.dataset.aggregation_method\",\n            ),\n            isSetterSingleRow: true,\n            attrName: \"aggregationMethod\",\n            setterType: \"SEARCH_SELECT_SETTER\",\n            options: aggregationMethodOptions,\n          },\n          {\n            id: `${baseWidgetName}-chart-type`,\n            labelName: i18n.t(\"editor.inspect.setter_label.chart_type\"),\n            isSetterSingleRow: true,\n            attrName: \"type\",\n            setterType: \"SEARCH_SELECT_SETTER\",\n            options: datasetsTypeOption,\n          },\n          {\n            id: `${baseWidgetName}-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.color\"),\n            isSetterSingleRow: true,\n            attrName: \"color\",\n            setterType: \"CHART_COLOR_SELECT_SETTER\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-data-datasets-bar`,\n        labelName: i18n.t(\"editor.inspect.setter_label.datasets\"),\n        useCustomLayout: true,\n        attrName: \"datasets\",\n        setterType: \"CHART_DATASETS_SETTER\",\n        bindAttrName: [\"chartType\"],\n        shown: (chartType: string) => chartType === \"pie\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-datasets-name`,\n            labelName: i18n.t(\"editor.inspect.setter_label.dataset.name\"),\n            isSetterSingleRow: true,\n            attrName: \"datasetName\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-datasets-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.dataset.value\"),\n            isSetterSingleRow: true,\n            attrName: \"datasetValues\",\n            setterType: \"CHART_KEYS_SELECT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-aggregation-method`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.dataset.aggregation_method\",\n            ),\n            isSetterSingleRow: true,\n            attrName: \"aggregationMethod\",\n            setterType: \"SEARCH_SELECT_SETTER\",\n            options: aggregationMethodOptions,\n          },\n          {\n            id: `${baseWidgetName}-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.color\"),\n            isSetterSingleRow: true,\n            attrName: \"color\",\n            setterType: \"CHART_COLOR_SELECT_SETTER\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-legend_position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.chart.legend_position\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.chart.legend_position\"),\n        attrName: \"legendPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        isSetterSingleRow: true,\n        shown: (labelHidden: boolean) => !labelHidden,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <VerticalStartIcon />,\n            value: \"top\",\n          },\n          {\n            label: <VerticalEndIcon />,\n            value: \"bottom\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n          {\n            label: <ReduceIcon />,\n            value: \"hidden\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-title`,\n        labelName: i18n.t(\"editor.inspect.setter_label.chart_title\"),\n        attrName: \"chartTitle\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-layout-x-axis`,\n        labelName: i18n.t(\"editor.inspect.setter_label.x_axis_name\"),\n        attrName: \"xAxisName\",\n        bindAttrName: [\"chartType\"],\n        shown: (chartType: string) => !typeWithNoAxis(chartType),\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      // x type name or horizontal x type name\n      {\n        id: `${baseWidgetName}-layout-x-type`,\n        labelName: i18n.t(\"editor.inspect.setter_label.chart.x-axis_type\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.chart.x-axis_type\"),\n        attrName: \"xType\",\n        expectedType: VALIDATION_TYPES.STRING,\n        bindAttrName: [\"chartType\", \"direction\"],\n        shown: (chartType: ChartType, direction: \"x\" | \"y\") => {\n          if (typeWithNoAxis(chartType)) return false\n          return direction === \"x\"\n        },\n        setterType: \"SEARCH_SELECT_SETTER\",\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.chart.x-axis_type.Default\",\n            ),\n            value: \"default\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.chart.x-axis_type.Date\",\n            ),\n            value: \"time\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-x-type-horizontal`,\n        labelName: i18n.t(\"editor.inspect.setter_label.chart.y-axis_type\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.chart.y-axis_type\"),\n        attrName: \"xType\",\n        expectedType: VALIDATION_TYPES.STRING,\n        bindAttrName: [\"chartType\", \"direction\"],\n        shown: (chartType: ChartType, direction: \"x\" | \"y\") => {\n          if (typeWithNoAxis(chartType)) return false\n          return direction === \"y\"\n        },\n        setterType: \"SEARCH_SELECT_SETTER\",\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.chart.x-axis_type.Default\",\n            ),\n            value: \"default\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.chart.x-axis_type.Date\",\n            ),\n            value: \"time\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-Format`,\n        labelName: i18n.t(\"editor.inspect.setter_label.chart.format\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.chart.format\"),\n        attrName: \"dateFormat\",\n        bindAttrName: [\"xType\", \"chartType\"],\n        shown: (xType: string, chartType: string) => {\n          if (typeWithNoAxis(chartType)) return false\n          return xType === \"time\"\n        },\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-layout-y-axis`,\n        labelName: i18n.t(\"editor.inspect.setter_label.y_axis_name\"),\n        attrName: \"yAxisName\",\n        bindAttrName: [\"chartType\"],\n        shown: (chartType: string) => !typeWithNoAxis(chartType),\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-styles`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"border\",\n      },\n      {\n        id: `${baseWidgetName}-styles-color`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"border\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-background`,\n            labelName: i18n.t(\"editor.inspect.setter_label.background\"),\n            attrName: \"backgroundColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"#ffffffff\",\n          },\n          {\n            id: `${baseWidgetName}-style-grid-line-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.chart.grid_line\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.chart.grid_line\"),\n            attrName: \"gridLineColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            attrName: \"radius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n          {\n            id: `${baseWidgetName}-style-shadow`,\n            labelName: i18n.t(\"editor.inspect.setter_label.shadow.shadow\"),\n            attrName: \"shadow\",\n            setterType: \"SHADOW_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"none\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChartWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const chartContainerStyle = (bgColor: string) => css`\n  background-color: ${bgColor};\n  width: 100%;\n  height: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChartWidget/utils.ts",
    "content": "import { ChartType } from \"chart.js\"\nimport dayjs from \"dayjs\"\nimport { get, max, mean, min, sum } from \"lodash-es\"\nimport { CHART_DATASET_AGGREGATION_METHOD } from \"@/widgetLibrary/ChartWidget/interface\"\n\nexport const formatDataWithSum = (\n  originData: Record<string, unknown[]>,\n  datasetValues: string,\n  realXAxis: string[],\n) => {\n  const data: number[] = []\n  realXAxis.forEach((x) => {\n    let values: number[] = []\n    const v = originData[x] ?? []\n    v.forEach((vk) => {\n      values.push(Number(get(vk, datasetValues, 0)))\n    })\n    data.push(sum(values))\n  })\n  return data\n}\n\nexport const formatDataWithMax = (\n  originData: Record<string, unknown[]>,\n  datasetValues: string,\n  realXAxis: string[],\n) => {\n  const data: number[] = []\n\n  realXAxis.forEach((x) => {\n    let values: number[] = []\n    const v = originData[x] ?? []\n    v.forEach((vk) => {\n      values.push(Number(get(vk, datasetValues, 0)))\n    })\n    data.push(max(values) || 0)\n  })\n\n  return data\n}\n\nexport const formatDataWithMin = (\n  originData: Record<string, unknown[]>,\n  datasetValues: string,\n  realXAxis: string[],\n) => {\n  const data: number[] = []\n\n  realXAxis.forEach((x) => {\n    let values: number[] = []\n    const v = originData[x] ?? []\n    v.forEach((vk) => {\n      values.push(Number(get(vk, datasetValues, 0)))\n    })\n    data.push(min(values) || 0)\n  })\n\n  return data\n}\n\nexport const formatDataWithAverage = (\n  originData: Record<string, unknown[]>,\n  datasetValues: string,\n  realXAxis: string[],\n) => {\n  const data: number[] = []\n\n  realXAxis.forEach((x) => {\n    let values: number[] = []\n    const v = originData[x] ?? []\n    v.forEach((vk) => {\n      values.push(Number(get(vk, datasetValues, 0)))\n    })\n    data.push(mean(values) || 0)\n  })\n  return data\n}\n\nexport const formatDataWithMedian = (\n  originData: Record<string, unknown[]>,\n  datasetValues: string,\n  realXAxis: string[],\n) => {\n  const data: number[] = []\n\n  realXAxis.forEach((x) => {\n    let values: number[] = []\n    const v = originData[x] ?? []\n    v.forEach((vk) => {\n      values.push(Number(get(vk, datasetValues, 0)))\n    })\n    values = values.sort((a, b) => a - b)\n\n    const len = values.length\n    if (len % 2) {\n      data.push(values[Math.floor(len / 2)])\n    } else {\n      data.push((values[len / 2] + values[len / 2 - 1]) / 2)\n    }\n  })\n\n  return data\n}\n\nexport const formatDataWithCount = (\n  originData: Record<string, unknown[]>,\n  realXAxis: string[],\n) => {\n  const data: number[] = []\n\n  realXAxis.forEach((x) => {\n    const v = originData[x] ?? []\n    data.push(v?.length || 0)\n  })\n  return data\n}\n\nexport const formatData = (\n  formatDataSources: Record<string, unknown[]>,\n  datasetValues: string,\n  aggregationMethod: CHART_DATASET_AGGREGATION_METHOD,\n  realXAxis: string[] = [],\n) => {\n  switch (aggregationMethod) {\n    case CHART_DATASET_AGGREGATION_METHOD.SUM: {\n      return formatDataWithSum(formatDataSources, datasetValues, realXAxis)\n    }\n    case CHART_DATASET_AGGREGATION_METHOD.AVERAGE: {\n      return formatDataWithAverage(formatDataSources, datasetValues, realXAxis)\n    }\n    case CHART_DATASET_AGGREGATION_METHOD.COUNT: {\n      return formatDataWithCount(formatDataSources, realXAxis)\n    }\n    case CHART_DATASET_AGGREGATION_METHOD.MAX: {\n      return formatDataWithMax(formatDataSources, datasetValues, realXAxis)\n    }\n    case CHART_DATASET_AGGREGATION_METHOD.MEDIAN: {\n      return formatDataWithMedian(formatDataSources, datasetValues, realXAxis)\n    }\n    case CHART_DATASET_AGGREGATION_METHOD.MIN: {\n      return formatDataWithMin(formatDataSources, datasetValues, realXAxis)\n    }\n    default: {\n      return []\n    }\n  }\n}\n\nexport const typeWithNoAxis = (type: ChartType | string) => {\n  return type === \"pie\" || type === \"doughnut\" || type === \"radar\"\n}\n\nexport const typeWithDiffColor = (type: ChartType) => {\n  return type === \"pie\" || type === \"doughnut\"\n}\n\nexport const mergeValueFromDynamic = (\n  isDynamic: boolean,\n  attrValue: string,\n  attrValueDynamic: string,\n) => {\n  if (isDynamic) {\n    return attrValueDynamic\n  }\n  return attrValue\n}\n\nexport const getDateFormatLabel = (value: string, dateFormat?: string) => {\n  try {\n    return dayjs(value).format(dateFormat)\n  } catch (e) {\n    return value\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChartWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport ChartWidgetIcon from \"@/assets/widgetCover/chart.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const CHART_WIDGET_CONFIG: WidgetConfig = {\n  type: \"CHART\",\n  displayName: \"chart\",\n  widgetName: i18n.t(\"widget.chart.name\"),\n  keywords: [\"Chart\", \"图表\"],\n  icon: <ChartWidgetIcon />,\n  sessionType: \"DATA\",\n  w: 10,\n  h: 40,\n  version: 0,\n  defaults: initChartWidgetDefaultProps,\n}\n\nexport const CHART_WIDGET_V2_CONFIG: WidgetConfig = {\n  type: \"CHART_WIDGET\",\n  displayName: \"chart\",\n  widgetName: i18n.t(\"widget.chart.name\"),\n  keywords: [\"Chart\", \"图表\"],\n  icon: <ChartWidgetIcon />,\n  sessionType: \"DATA\",\n  w: 10,\n  h: 40,\n  version: 0,\n  defaults: initChartWidgetDefaultProps,\n}\n\nexport function initChartWidgetDefaultProps() {\n  return {\n    dataSourceJS: `{{[\n      {\n        month: \"April\",\n        users: 3700,\n        incomes: 4000,\n      },\n      {\n        month: \"May\",\n        users: 5400,\n        incomes: 8700,\n      },\n      {\n        month: \"June\",\n        users: 6000,\n        incomes: 12000,\n      },\n      {\n        month: \"July\",\n        users: 8000,\n        incomes: 14000,\n      },\n    ]}}`,\n    chartType: \"bar\",\n    dataSourceMode: \"dynamic\",\n    xAxis: \"month\",\n    datasets: [\n      {\n        id: v4(),\n        datasetName: \"Dataset 1\",\n        datasetValues: \"users\",\n        aggregationMethod: \"SUM\",\n        type: \"bar\",\n        color: \"#165DFF\",\n      },\n    ],\n    $dynamicAttrPaths: [\"dataSourceJS\"],\n    direction: \"x\",\n    legendPosition: \"top\",\n    dateFormat: \"YYYY-MM-DD\",\n    radius: \"4px\",\n    backgroundColor: \"#ffffffff\",\n    shadow: \"none\",\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/chat.tsx",
    "content": "import { Resizable, ResizeCallback, ResizeStartCallback } from \"re-resizable\"\nimport { FC, useCallback, useEffect, useMemo, useState } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { BaseChat } from \"@/widgetLibrary/ChatWidget/components/baseChat\"\nimport { ReplyTo } from \"@/widgetLibrary/ChatWidget/components/replyTo\"\nimport {\n  ChatWidgetProps,\n  MessageContent,\n} from \"@/widgetLibrary/ChatWidget/interface\"\nimport {\n  chatContainerStyle,\n  footerStyle,\n  resizeLineStyle,\n} from \"@/widgetLibrary/ChatWidget/style\"\nimport { useSizeChange } from \"@/widgetLibrary/ChatWidget/useSizeChange\"\nimport {\n  addOrDelLoading,\n  formatEventOptions,\n} from \"@/widgetLibrary/ChatWidget/utils\"\nimport RenderChildrenCanvas from \"@/widgetLibrary/PublicSector/RenderChildrenCanvas\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { emptyMessage } from \"./constants\"\n\nexport const ChatWidget: FC<ChatWidgetProps> = (props) => {\n  const {\n    columnNumber,\n    displayName,\n    value = [],\n    tooltipText,\n    receiving = false,\n    footerHeight = 50,\n    childrenNode,\n    mappedOption,\n    showFooter,\n    backgroundColor = \"white\",\n    triggerEventHandler,\n    handleUpdateOriginalDSLMultiAttr,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n  } = props\n  const { messageListRef, containerRef, handleOnSizeChange } = useSizeChange(\n    value.length,\n  )\n  const dispatch = useDispatch()\n  const [replyShow, setReplyShow] = useState(false)\n  const [replyMessage, setReplyMessage] = useState<MessageContent>({})\n\n  const messageList = useMemo(() => {\n    return formatEventOptions(mappedOption)\n  }, [mappedOption])\n\n  const handleUpdateValue = useCallback(\n    (messageList: MessageContent[]) => {\n      if (!messageList || !Array.isArray(messageList)) {\n        return\n      }\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value: messageList,\n          },\n        },\n      ])\n    },\n    [displayName, handleUpdateMultiExecutionResult],\n  )\n\n  const handleResizeStart: ResizeStartCallback = (e) => {\n    e.preventDefault()\n    e.stopPropagation()\n    dispatch(\n      configActions.setResizingNodeIDsReducer([`${displayName}-resize-footer`]),\n    )\n  }\n\n  const handleOnResizeStop: ResizeCallback = useCallback(\n    (e, dir, elementRef, delta) => {\n      const { height } = delta\n      handleUpdateOriginalDSLMultiAttr({\n        footerHeight: footerHeight + height,\n      })\n      dispatch(configActions.setResizingNodeIDsReducer([]))\n    },\n    [dispatch, footerHeight, handleUpdateOriginalDSLMultiAttr],\n  )\n\n  const handleOnResize: ResizeCallback = useCallback(() => {\n    handleOnSizeChange()\n  }, [handleOnSizeChange])\n\n  const handleOnSelect = useCallback(\n    (message: MessageContent) => {\n      return new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              selectedMessage: message,\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"select\")\n      })\n    },\n    [displayName, handleUpdateMultiExecutionResult, triggerEventHandler],\n  )\n  const handleOnReply = useCallback(\n    (message: MessageContent | undefined) => {\n      if (!message) return\n      handleOnSelect(message)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            replyMessage: message,\n          },\n        },\n      ])\n      setReplyShow(true)\n      setReplyMessage(message)\n    },\n    [displayName, handleOnSelect, handleUpdateMultiExecutionResult],\n  )\n\n  const clearReplyMessage = useCallback(() => {\n    setReplyShow(false)\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          replyMessage: emptyMessage,\n        },\n      },\n    ])\n  }, [displayName, handleUpdateMultiExecutionResult])\n\n  const handleOnDelete = useCallback(\n    (message: MessageContent | undefined) => {\n      if (!message) return\n      handleOnSelect(message).then(() => {\n        triggerEventHandler(\"delete\")\n      })\n    },\n    [handleOnSelect, triggerEventHandler],\n  )\n\n  useEffect(() => {\n    handleUpdateValue(messageList)\n  }, [handleUpdateValue, messageList])\n\n  useEffect(() => {\n    addOrDelLoading(\n      receiving,\n      messageList,\n      handleUpdateValue,\n      handleOnSizeChange,\n    )\n  }, [handleUpdateValue, receiving, messageList, handleOnSizeChange])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      clearReplyMessage: clearReplyMessage,\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    clearReplyMessage,\n    deleteComponentRuntimeProps,\n    updateComponentRuntimeProps,\n  ])\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div css={chatContainerStyle(backgroundColor)} ref={containerRef}>\n        <div style={{ height: \"100%\" }}>\n          <BaseChat\n            {...props}\n            ref={messageListRef}\n            value={value}\n            handleOnDelete={handleOnDelete}\n            handleOnReply={handleOnReply}\n          />\n        </div>\n        {replyShow && (\n          <ReplyTo\n            replyMessage={replyMessage}\n            clearReplyMessage={clearReplyMessage}\n          />\n        )}\n        {showFooter && (\n          <Resizable\n            size={{\n              width: \"100%\",\n              height: footerHeight,\n            }}\n            minHeight={8 * UNIT_HEIGHT}\n            maxHeight=\"80%\"\n            enable={{\n              top: true,\n            }}\n            onResizeStart={handleResizeStart}\n            onResizeStop={handleOnResizeStop}\n            onResize={handleOnResize}\n          >\n            <div css={resizeLineStyle} />\n            <div css={footerStyle}>\n              <RenderChildrenCanvas\n                displayName={childrenNode[0]}\n                columnNumber={columnNumber}\n                handleUpdateHeight={() => {}}\n              />\n            </div>\n          </Resizable>\n        )}\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nChatWidget.displayName = \"ChatWidget\"\nexport default ChatWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/baseChat.tsx",
    "content": "import { forwardRef } from \"react\"\nimport { Virtuoso, VirtuosoHandle } from \"react-virtuoso\"\nimport { MessageItem } from \"@/widgetLibrary/ChatWidget/components/messageItem\"\nimport { Receiving } from \"@/widgetLibrary/ChatWidget/components/receiving\"\nimport { BaseChatProps } from \"@/widgetLibrary/ChatWidget/interface\"\nimport { messageListContainerStyle } from \"@/widgetLibrary/ChatWidget/style\"\n\nexport const BaseChat = forwardRef<VirtuosoHandle, BaseChatProps>(\n  (props, ref) => {\n    const { value = [], leftMessageColor, showAvatar } = props\n    return (\n      <div css={messageListContainerStyle}>\n        <Virtuoso\n          ref={ref}\n          totalCount={value.length}\n          height=\"100%\"\n          data={value}\n          initialTopMostItemIndex={value.length - 1}\n          itemContent={(_, data) => (\n            <>\n              {data.loading ? (\n                <Receiving\n                  leftMessageColor={leftMessageColor}\n                  showAvatar={showAvatar}\n                />\n              ) : (\n                <MessageItem {...props} message={data} />\n              )}\n            </>\n          )}\n        />\n      </div>\n    )\n  },\n)\nBaseChat.displayName = \"BaseChat\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/messageItem.tsx",
    "content": "import { Avatar, Message } from \"@chatscope/chat-ui-kit-react\"\nimport \"@chatscope/chat-ui-kit-styles/dist/default/styles.min.css\"\nimport dayjs from \"dayjs\"\nimport { FC } from \"react\"\nimport { ReplyMessage } from \"@/widgetLibrary/ChatWidget/components/messageItems/replayMessage\"\nimport { SendMessage } from \"@/widgetLibrary/ChatWidget/components/messageItems/sendMessage\"\nimport { IMessageItem } from \"@/widgetLibrary/ChatWidget/interface\"\nimport {\n  messageContentStyle,\n  messageHeaderNameStyle,\n  messageHeaderStyle,\n  messageHeaderTimeStyle,\n} from \"../style\"\n\nexport const MessageItem: FC<IMessageItem> = (props) => {\n  const {\n    message,\n    currentSenderId = \"\",\n    leftMessageColor = \"grayBlue\",\n    rightMessageColor = \"blue\",\n    value = [],\n    timeFormat,\n    showAvatar,\n    showName,\n    showSendTime,\n    avatarPadding,\n  } = props\n  const {\n    message: content = \"\",\n    senderAvatar,\n    senderId,\n    senderName,\n    messageId,\n    sendTime,\n    messageType = \"text\",\n    replyMessageId,\n  } = message\n\n  const isOwnMessage = !!currentSenderId && senderId === currentSenderId\n  return (\n    <>\n      <Message\n        key={messageId}\n        model={{\n          direction: isOwnMessage ? \"outgoing\" : \"incoming\",\n          position: \"single\",\n        }}\n        avatarPosition={isOwnMessage ? \"tr\" : \"tl\"}\n        css={messageContentStyle(isOwnMessage, avatarPadding)}\n      >\n        {showAvatar && <Avatar src={senderAvatar} />}\n        <Message.Header>\n          <div css={messageHeaderStyle(isOwnMessage)}>\n            {showName && <span css={messageHeaderNameStyle}>{senderName}</span>}\n            {showSendTime && (\n              <span css={messageHeaderTimeStyle}>\n                {dayjs(sendTime).format(timeFormat)}\n              </span>\n            )}\n          </div>\n        </Message.Header>\n        <Message.CustomContent>\n          <SendMessage\n            {...props}\n            messageType={messageType}\n            isOwnMessage={isOwnMessage}\n            leftMessageColor={leftMessageColor}\n            rightMessageColor={rightMessageColor}\n            content={content}\n          />\n        </Message.CustomContent>\n        {value.length && replyMessageId && (\n          <Message.Footer\n            style={{\n              flexDirection: isOwnMessage ? \"row-reverse\" : \"row\",\n              width: \"100%\",\n            }}\n          >\n            <ReplyMessage messageId={replyMessageId} value={value} />\n          </Message.Footer>\n        )}\n      </Message>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/messageItems/audioMessage.tsx",
    "content": "import { FC, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport ReactPlayer from \"react-player\"\nimport { Loading, Trigger } from \"@illa-design/react\"\nimport { MessageSpecProps } from \"@/widgetLibrary/ChatWidget/interface\"\nimport {\n  audioStyle,\n  audioWrapperStyle,\n  loadingStyle,\n} from \"@/widgetLibrary/ChatWidget/style\"\nimport { Options } from \"../options\"\n\nexport const AudioMessage: FC<Partial<MessageSpecProps>> = (props) => {\n  const { content, isReply, toolbarDelete, toolbarReply, isOwnMessage } = props\n  const { t } = useTranslation()\n  const [loading, setLoading] = useState(true)\n  const [_error, setError] = useState(false)\n\n  if (content === \"\") {\n    return <div css={loadingStyle}>{t(\"widget.audio.no_audio\")}</div>\n  }\n\n  return (\n    <Trigger\n      bdRadius=\"4px\"\n      bg=\"white\"\n      content={<Options {...props} />}\n      colorScheme=\"transparent\"\n      disabled={!toolbarDelete && !toolbarReply}\n      position={isOwnMessage ? \"left-start\" : \"right-start\"}\n      showArrow={false}\n      autoFitPosition={false}\n      withoutPadding\n      trigger=\"hover\"\n      withoutShadow\n    >\n      <div css={audioStyle(isReply)}>\n        {loading ? (\n          <div css={loadingStyle}>\n            <Loading colorScheme=\"black\" />\n          </div>\n        ) : null}\n        <ReactPlayer\n          css={audioWrapperStyle}\n          style={loading ? { display: \"none\" } : undefined}\n          config={{\n            file: {\n              forceAudio: true,\n            },\n          }}\n          width=\"100%\"\n          height=\"100%\"\n          url={content}\n          controls={true}\n          draggable={false}\n          onReady={() => {\n            setLoading(false)\n            setError(false)\n          }}\n          onError={() => {\n            setLoading(false)\n            setError(true)\n          }}\n        />\n      </div>\n    </Trigger>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/messageItems/imageMessage.tsx",
    "content": "import { FC } from \"react\"\nimport { Trigger } from \"@illa-design/react\"\nimport { MessageSpecProps } from \"@/widgetLibrary/ChatWidget/interface\"\nimport {\n  replyImageStyle,\n  sendImageStyle,\n} from \"@/widgetLibrary/ChatWidget/style\"\nimport { Options } from \"../options\"\n\nexport const ImageMessage: FC<Partial<MessageSpecProps>> = (props) => {\n  const { content, isReply, toolbarDelete, toolbarReply, isOwnMessage } = props\n  return (\n    <Trigger\n      bdRadius=\"4px\"\n      bg=\"white\"\n      content={<Options {...props} />}\n      colorScheme=\"transparent\"\n      disabled={!toolbarDelete && !toolbarReply}\n      position={isOwnMessage ? \"left-start\" : \"right-start\"}\n      showArrow={false}\n      autoFitPosition={false}\n      withoutPadding\n      trigger=\"hover\"\n      withoutShadow\n    >\n      <div>\n        {isReply ? (\n          <div css={replyImageStyle}>\n            <img src={content} />\n          </div>\n        ) : (\n          <img src={content} alt=\"\" width=\"100%\" css={sendImageStyle} />\n        )}\n      </div>\n    </Trigger>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/messageItems/replayMessage.tsx",
    "content": "import { FC } from \"react\"\nimport { MessageContent } from \"@/widgetLibrary/ChatWidget/interface\"\nimport {\n  replyMessageStyle,\n  replyNameStyle,\n} from \"@/widgetLibrary/ChatWidget/style\"\nimport { AudioMessage } from \"./audioMessage\"\nimport { ImageMessage } from \"./imageMessage\"\nimport { TextMessage } from \"./textMessage\"\nimport { VideoMessage } from \"./videoMessage\"\n\nexport const ReplyMessage: FC<{\n  messageId: string\n  value: MessageContent[]\n}> = (props) => {\n  const { messageId, value } = props\n  const message = value.find((item) => item.messageId === messageId)\n  if (!message) return null\n  const { messageType, message: content, senderName } = message\n  return (\n    <div css={replyMessageStyle}>\n      <div>\n        <span css={replyNameStyle}>{senderName}: </span>\n        {messageType === \"text\" && <TextMessage content={content} isReply />}\n        {messageType === \"image\" && <ImageMessage content={content} isReply />}\n        {messageType === \"audio\" && <AudioMessage content={content} isReply />}\n        {messageType === \"video\" && <VideoMessage content={content} isReply />}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/messageItems/sendMessage.tsx",
    "content": "import { FC } from \"react\"\nimport {\n  MessageSpecProps,\n  MessageType,\n} from \"@/widgetLibrary/ChatWidget/interface\"\nimport { messageItemContainerStyle } from \"@/widgetLibrary/ChatWidget/style\"\nimport { AudioMessage } from \"./audioMessage\"\nimport { ImageMessage } from \"./imageMessage\"\nimport { TextMessage } from \"./textMessage\"\nimport { VideoMessage } from \"./videoMessage\"\n\nexport const SendMessage: FC<\n  MessageSpecProps & { messageType: MessageType }\n> = (props) => {\n  const { messageType, isOwnMessage = false } = props\n  return (\n    <div css={messageItemContainerStyle(isOwnMessage)}>\n      {messageType === \"text\" && <TextMessage {...props} />}\n      {messageType === \"image\" && <ImageMessage {...props} />}\n      {messageType === \"audio\" && <AudioMessage {...props} />}\n      {messageType === \"video\" && <VideoMessage {...props} />}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/messageItems/textMessage.tsx",
    "content": "import { FC } from \"react\"\nimport ReactMarkdown from \"react-markdown\"\nimport remarkGfm from \"remark-gfm\"\nimport { Paragraph, Trigger } from \"@illa-design/react\"\nimport { MessageSpecProps } from \"@/widgetLibrary/ChatWidget/interface\"\nimport {\n  messageTextStyle,\n  replyTextStyle,\n} from \"@/widgetLibrary/ChatWidget/style\"\nimport { Options } from \"../options\"\n\nexport const TextMessage: FC<Partial<MessageSpecProps>> = (props) => {\n  const {\n    content,\n    isReply,\n    isOwnMessage = false,\n    leftMessageColor = \"grayBlue\",\n    rightMessageColor = \"blue\",\n    toolbarDelete,\n    toolbarReply,\n  } = props\n  return (\n    <Trigger\n      bdRadius=\"4px\"\n      bg=\"white\"\n      content={<Options {...props} />}\n      colorScheme=\"transparent\"\n      disabled={!toolbarDelete && !toolbarReply}\n      position={isOwnMessage ? \"left-start\" : \"right-start\"}\n      showArrow={false}\n      autoFitPosition={false}\n      withoutPadding\n      trigger=\"hover\"\n      withoutShadow\n    >\n      <div\n        css={\n          isReply\n            ? replyTextStyle\n            : messageTextStyle(\n                isOwnMessage,\n                leftMessageColor,\n                rightMessageColor,\n              )\n        }\n      >\n        <ReactMarkdown\n          remarkPlugins={[remarkGfm]}\n          components={{\n            p: ({ children }) => <Paragraph>{children}</Paragraph>,\n            img: ({ src, alt }) => <img src={src} alt={alt} width=\"100%\" />,\n          }}\n        >\n          {content ?? \"\"}\n        </ReactMarkdown>\n      </div>\n    </Trigger>\n  )\n}\nTextMessage.displayName = \"TextMessage\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/messageItems/videoMessage.tsx",
    "content": "import { FC, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport ReactPlayer from \"react-player\"\nimport { Loading, Trigger } from \"@illa-design/react\"\nimport { MessageSpecProps } from \"@/widgetLibrary/ChatWidget/interface\"\nimport { loadingStyle, videoStyle } from \"@/widgetLibrary/ChatWidget/style\"\nimport { Options } from \"../options\"\n\nexport const VideoMessage: FC<Partial<MessageSpecProps>> = (props) => {\n  const { content, isReply, toolbarDelete, toolbarReply, isOwnMessage } = props\n  const { t } = useTranslation()\n  const [loading, setLoading] = useState(true)\n  const [error, setError] = useState(false)\n\n  if (content === \"\") {\n    return <div css={loadingStyle}>{t(\"widget.video.empty\")}</div>\n  }\n\n  return (\n    <Trigger\n      bdRadius=\"4px\"\n      bg=\"white\"\n      content={<Options {...props} />}\n      colorScheme=\"transparent\"\n      disabled={!toolbarDelete && !toolbarReply}\n      position={isOwnMessage ? \"left-start\" : \"right-start\"}\n      showArrow={false}\n      autoFitPosition={false}\n      withoutPadding\n      trigger=\"hover\"\n      withoutShadow\n    >\n      <div css={videoStyle(isReply)}>\n        {loading ? (\n          <div css={loadingStyle}>\n            <Loading colorScheme=\"white\" />\n          </div>\n        ) : error ? (\n          <div css={loadingStyle}>{t(\"widget.video.fail\")}</div>\n        ) : null}\n        <ReactPlayer\n          style={loading || error ? { display: \"none\" } : undefined}\n          fallback={\n            <div css={loadingStyle}>\n              <Loading colorScheme=\"white\" />\n            </div>\n          }\n          width=\"100%\"\n          height=\"100%\"\n          url={content}\n          draggable={false}\n          onReady={() => {\n            setLoading(false)\n            setError(false)\n          }}\n          onError={() => {\n            setLoading(false)\n            setError(true)\n          }}\n        />\n      </div>\n    </Trigger>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/options.tsx",
    "content": "import { FC } from \"react\"\nimport DeleteSvg from \"@/assets/chat/delete.svg?react\"\nimport ReplySvg from \"@/assets/chat/replay.svg?react\"\nimport { OptionsProps } from \"@/widgetLibrary/ChatWidget/interface\"\nimport { optionsStyle } from \"@/widgetLibrary/ChatWidget/style\"\n\nexport const Options: FC<Partial<OptionsProps>> = ({\n  message,\n  toolbarDelete,\n  handleOnReply,\n  toolbarReply,\n  handleOnDelete,\n}) => {\n  return (\n    <div css={optionsStyle(Boolean(toolbarReply && toolbarDelete))}>\n      {toolbarReply && (\n        <div\n          onClick={() => {\n            handleOnReply && handleOnReply(message)\n          }}\n        >\n          <ReplySvg />\n        </div>\n      )}\n      {toolbarDelete && (\n        <div\n          onClick={() => {\n            handleOnDelete && handleOnDelete(message)\n          }}\n        >\n          <DeleteSvg />\n        </div>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/receiving.tsx",
    "content": "import { FC } from \"react\"\nimport {\n  receivingAvatarStyle,\n  receivingContainerStyle,\n  receivingStyle,\n} from \"@/widgetLibrary/ChatWidget/style\"\n\nexport const Receiving: FC<{\n  leftMessageColor?: string\n  showAvatar?: boolean\n}> = (props) => {\n  const { leftMessageColor = \"grayBlue\", showAvatar } = props\n  return (\n    <div css={receivingContainerStyle}>\n      {showAvatar && <div css={receivingAvatarStyle} />}\n      <div css={receivingStyle(leftMessageColor)} />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/components/replyTo.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport CloseReplySvg from \"@/assets/chat/closeReplay.svg?react\"\nimport { MessageContent } from \"@/widgetLibrary/ChatWidget/interface\"\nimport {\n  replyContent,\n  replyToHeaderStyle,\n  replyToStyle,\n} from \"@/widgetLibrary/ChatWidget/style\"\n\nexport const ReplyTo: FC<{\n  replyMessage: MessageContent\n  clearReplyMessage: () => void\n}> = ({ replyMessage, clearReplyMessage }) => {\n  const { t } = useTranslation()\n  const { messageType, message, senderName } = replyMessage\n  return (\n    <div css={replyToStyle}>\n      <div css={replyToHeaderStyle}>\n        <span>{t(\"editor.inspect.widget.reply\")}</span>\n        <span onClick={clearReplyMessage}>\n          <CloseReplySvg />\n        </span>\n      </div>\n      <div css={replyContent}>\n        <span style={{ fontWeight: 500 }}>{senderName}:&nbsp;</span>\n        {messageType === \"audio\" && (\n          <span>{t(\"editor.inspect.widget.reply_audio\")}</span>\n        )}\n        {messageType === \"image\" && (\n          <span>{t(\"editor.inspect.widget.reply_image\")}</span>\n        )}\n        {messageType === \"video\" && (\n          <span>{t(\"editor.inspect.widget.reply_video\")}</span>\n        )}\n        {messageType === \"text\" && <span>{message}</span>}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/constants.ts",
    "content": "export const emptyMessage = {\n  messageId: \"\",\n  message: \"\",\n  sendTime: \"\",\n  replyMessageId: \"\",\n  senderName: \"\",\n  senderId: \"\",\n  senderAvatar: \"\",\n  messageType: \"\",\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const CHAT_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.select\",\n      ),\n      value: \"select\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.delete\",\n      ),\n      value: \"delete\",\n    },\n  ],\n  methods: [\"clearReplyMessage\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/index.ts",
    "content": "export { CHAT_PANEL_CONFIG } from \"./panelConfig\"\nexport { CHAT_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { CHAT_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/interface.ts",
    "content": "import { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport type MessageType = \"text\" | \"image\" | \"video\" | \"audio\"\n\nexport type Pluralize<T> = {\n  [K in keyof T as `${string & K}s`]: T[K][]\n}\n\nexport interface IMessageItem extends BaseChatProps {\n  message: MessageContent\n}\n\nexport interface OptionsProps\n  extends Partial<\n    Pick<\n      BaseChatProps,\n      \"toolbarDelete\" | \"handleOnDelete\" | \"handleOnReply\" | \"toolbarReply\"\n    >\n  > {\n  message: MessageContent | undefined\n}\n\nexport interface MessageContent {\n  messageId?: string\n  message?: string\n  sendTime?: string\n  replyMessageId?: string\n  senderName?: string\n  senderId?: string\n  senderAvatar?: string\n  messageType?: MessageType\n  loading?: boolean\n}\n\nexport interface BaseChatProps extends BaseWidgetProps {\n  value?: MessageContent[]\n  currentSenderId?: string\n  leftMessageColor?: string\n  rightMessageColor?: string\n  receiving?: boolean\n  selectedMessage?: MessageContent\n  timeFormat?: string\n  toolbarReply?: boolean\n  toolbarDelete?: boolean\n  showAvatar?: boolean\n  showName?: boolean\n  showSendTime?: boolean\n  showFooter?: boolean\n  backgroundColor?: string\n  avatarPadding?: string\n  handleOnReply?: (message: MessageContent | undefined) => void\n  handleOnDelete?: (message: MessageContent | undefined) => void\n}\n\nexport interface ChatWidgetProps\n  extends BaseChatProps,\n    Pick<TooltipWrapperProps, \"tooltipText\"> {\n  footerHeight?: number\n  mappedOption?: Pluralize<MessageContent>\n  columnNumber: number\n  replyMessage: MessageContent\n}\n\nexport interface MessageSpecProps extends OptionsProps {\n  content?: string\n  isReply?: boolean\n  isOwnMessage?: boolean\n  leftMessageColor?: string\n  rightMessageColor?: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/panelConfig.tsx",
    "content": "import AvatarPaddingIcon from \"@/assets/chat/avatarPadding.svg?react\"\nimport RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { CHAT_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/ChatWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"chat\"\nexport const CHAT_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-data`,\n    groupName: i18n.t(\"editor.inspect.setter_group.MESSAGE\"),\n    children: [\n      {\n        id: `${baseWidgetName}-data-source`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n      },\n      {\n        id: `${baseWidgetName}-option-mapped-event`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.map_data_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedOption\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-message-message_id`,\n            labelName: i18n.t(\"editor.inspect.setter_label.message_id\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.message_id\"),\n            attrName: \"messageIds\",\n            placeholder: \"{{item.messageId}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-message-message`,\n            labelName: i18n.t(\"editor.inspect.setter_label.message\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.message\"),\n            attrName: \"messages\",\n            placeholder: \"{{item.messages}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-message-message_type`,\n            labelName: i18n.t(\"editor.inspect.setter_label.message_type\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.message_type\"),\n            attrName: \"messageTypes\",\n            placeholder: \"{{item.messageTypes}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-message-replayMessageId`,\n            labelName: i18n.t(\"editor.inspect.setter_label.replayMessageId\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.replayMessageId\"),\n            attrName: \"replyMessageIds\",\n            placeholder: \"{{item.replyMessageIds}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-message-sendTime`,\n            labelName: i18n.t(\"editor.inspect.setter_label.sendTime\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.sendTime\"),\n            attrName: \"sendTimes\",\n            placeholder: \"{{item.sendTimes}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-message-senderName`,\n            labelName: i18n.t(\"editor.inspect.setter_label.senderName\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.senderName\"),\n            attrName: \"senderNames\",\n            placeholder: \"{{item.senderNames}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-message-senderId`,\n            labelName: i18n.t(\"editor.inspect.setter_label.senderId\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.senderId\"),\n            attrName: \"senderIds\",\n            placeholder: \"{{item.senderIds}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-message-senderAvatar`,\n            labelName: i18n.t(\"editor.inspect.setter_label.senderAvatar\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.senderAvatar\"),\n            attrName: \"senderAvatars\",\n            placeholder: \"{{item.senderAvatars}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-message-timeFormat`,\n        labelName: i18n.t(\"editor.inspect.setter_label.timeFormat\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.sendtimeFormatTime\"),\n        isSetterSingleRow: true,\n        attrName: \"timeFormat\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-message-currentSenderId`,\n        labelName: i18n.t(\"editor.inspect.setter_label.currentSenderId\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.currentSenderId\"),\n        isSetterSingleRow: true,\n        attrName: \"currentSenderId\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          CHAT_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-message-receiving`,\n        labelName: i18n.t(\"editor.inspect.setter_label.receiving\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.receiving\"),\n        attrName: \"receiving\",\n        isSetterSingleRow: true,\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-toolbar`,\n    groupName: i18n.t(\"editor.inspect.setter_group.Toolbar\"),\n    children: [\n      {\n        id: `${baseWidgetName}-toolbar-replay`,\n        labelName: i18n.t(\"editor.inspect.setter_label.toolbar-replay\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.toolbar-replay\"),\n        attrName: \"toolbarReply\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-toolbar-delete`,\n        labelName: i18n.t(\"editor.inspect.setter_label.toolbar-delete\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.toolbar-delete\"),\n        attrName: \"toolbarDelete\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-showAvatar`,\n        labelName: i18n.t(\"editor.inspect.setter_label.showAvatar\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.showAvatar\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"showAvatar\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-showName`,\n        labelName: i18n.t(\"editor.inspect.setter_label.showName\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.showName\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"showName\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-showSendTime`,\n        labelName: i18n.t(\"editor.inspect.setter_label.showSendTime\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.showSendTime\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"showSendTime\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-showFooter`,\n        labelName: i18n.t(\"editor.inspect.setter_label.showFooter\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.showFooter\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"showFooter\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"border\",\n      },\n      {\n        id: `${baseWidgetName}-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-colors-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"backgroundColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n          {\n            id: `${baseWidgetName}-colors-message-left-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.leftMessageColor\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.leftMessageColor\"),\n            attrName: \"leftMessageColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"grayBlue\",\n          },\n          {\n            id: `${baseWidgetName}-colors-right-message-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.rightMessageColor\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.rightMessageColor\"),\n            attrName: \"rightMessageColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            attrName: \"radius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n          {\n            id: `${baseWidgetName}-style-shadow`,\n            labelName: i18n.t(\"editor.inspect.setter_label.shadow.shadow\"),\n            attrName: \"shadow\",\n            setterType: \"SHADOW_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"small\",\n          },\n          {\n            id: `${baseWidgetName}-style-avatar-padding`,\n            labelName: i18n.t(\"editor.inspect.setter_group.padding\"),\n            attrName: \"avatarPadding\",\n            icon: <AvatarPaddingIcon />,\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"32px\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport {\n  getColor,\n  getSpecialThemeColor,\n  hasNineStepColor,\n} from \"@illa-design/react\"\n\nexport const resizeLineStyle = css`\n  width: 100%;\n  height: 1px;\n  background-color: #e5e5e5;\n  cursor: row-resize;\n  position: absolute;\n`\nexport const footerStyle = css`\n  width: 100%;\n  height: 100%;\n  // overflow: hidden;\n  display: flex;\n  flex-direction: row;\n`\nexport const chatContainerStyle = (backgroundColor: string) => css`\n  height: 100%;\n  padding-top: 16px;\n  display: flex;\n  overflow: hidden;\n  flex-direction: column;\n  background-color: ${getSpecialThemeColor(backgroundColor)};\n`\n\nexport const messageListContainerStyle = css`\n  height: 100%;\n  overflow: auto;\n`\n\nexport const messageHeaderStyle = (isOwn: boolean) => {\n  return css`\n    width: 100%;\n    display: flex;\n    flex-direction: ${isOwn ? \"row-reverse\" : \"row\"};\n    gap: 8px;\n    justify-content: flex-start;\n    align-items: center;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    margin-bottom: 4px;\n  `\n}\nexport const messageHeaderNameStyle = css`\n  font-weight: 500;\n  font-size: 14px;\n  line-height: 22px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const messageHeaderTimeStyle = css`\n  font-weight: 400;\n  font-size: 12px;\n  line-height: 20px;\n  color: ${getColor(\"grayBlue\", \"03\")};\n`\nexport const messageContentStyle = (isOwn: boolean, avatarPadding?: string) => {\n  const finalAvatarPadding = !avatarPadding ? \"32px\" : avatarPadding\n\n  return css`\n    .cs-message__content-wrapper {\n      margin-top: 12px;\n      width: 100%;\n    }\n    .cs-message__footer {\n      margin: 0;\n    }\n    .cs-message__content {\n      height: auto;\n      width: auto;\n      border-radius: 0;\n      padding: 0;\n      background-color: transparent !important;\n    }\n    .cs-message__avatar {\n      margin: ${isOwn\n        ? `12px ${finalAvatarPadding} 0 16px`\n        : `12px 16px 0 ${finalAvatarPadding}`} !important;\n      width: 32px;\n      .cs-avatar {\n        height: 32px;\n        width: 32px;\n        min-height: 32px;\n        min-width: 32px;\n      }\n    }\n    .cs-message__custom-content {\n      padding-bottom: 8px;\n      display: flex;\n    }\n  `\n}\n\nexport const messageFooterStyle = (isOwn: boolean) => css`\n  flex-direction: ${isOwn ? \"row-reverse\" : \"row\"};\n  width: 100%;\n  & > div {\n    width: 100%;\n  }\n`\n\nexport const messageItemContainerStyle = (isOwn: boolean) => css`\n  width: 100%;\n  flex-shrink: 1;\n  display: flex;\n  box-sizing: border-box;\n  justify-content: ${isOwn ? \"flex-end\" : \"flex-start\"};\n  padding-left: ${isOwn ? \"40px\" : \"0\"};\n  padding-right: ${isOwn ? \"0\" : \"40px\"};\n`\nexport const messageTextStyle = (\n  isOwn: boolean,\n  leftMessageColor: string,\n  rightMessageColor: string,\n) => {\n  const backgroundColor = isOwn\n    ? getSpecialThemeColor(rightMessageColor)\n    : getColor(\n        leftMessageColor,\n        hasNineStepColor(leftMessageColor) ? \"09\" : \"08\",\n      )\n  const color = isOwn ? getColor(\"white\", \"01\") : getColor(\"grayBlue\", \"02\")\n\n  return css`\n    background-color: ${backgroundColor};\n    color: ${color}!important;\n    padding: 8px 12px;\n    border-radius: 8px;\n    max-width: 344px;\n    word-wrap: break-word;\n    display: inline-block;\n    span,\n    a {\n      color: ${color};\n    }\n  `\n}\n\nexport const receivingStyle = (leftMessageColor: string) => {\n  const backgroundColor = getColor(\n    leftMessageColor,\n    hasNineStepColor(leftMessageColor) ? \"09\" : \"08\",\n  )\n  return css`\n    padding: 8px 12px;\n    border-radius: 8px;\n    width: 40px;\n    height: 33px;\n    background-color: ${backgroundColor};\n    color: ${getColor(\"grayBlue\", \"02\")}!important;\n    &:before {\n      content: \"\";\n      animation: dotAnimate 1s infinite;\n    }\n    @keyframes dotAnimate {\n      0%,\n      100% {\n        content: \"\";\n      }\n      25% {\n        content: \".\";\n      }\n      50% {\n        content: \"..\";\n      }\n      75% {\n        content: \"...\";\n      }\n    }\n  `\n}\n\nexport const contentContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  gap: 10px;\n  align-items: end;\n`\nexport const sendingStyle = css`\n  height: 16px;\n  width: 16px;\n  animation: sendAnimate 1s ease-in-out infinite;\n  @keyframes sendAnimate {\n    0% {\n      transform: rotate(0deg);\n    }\n    25% {\n      transform: rotate(90deg);\n    }\n    50% {\n      transform: rotate(180deg);\n    }\n    75% {\n      transform: rotate(270deg);\n    }\n    100% {\n      transform: rotate(360deg);\n    }\n  }\n`\n\nexport const replyMessageStyle = css`\n  padding-bottom: 8px;\n  & > div {\n    max-width: 344px;\n    width: 100%;\n    display: flex;\n    flex-direction: column;\n    flex-shrink: 1;\n    padding: 8px 12px;\n    gap: 4px;\n    border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n    border-radius: 8px;\n  }\n`\nexport const replyImageStyle = css`\n  width: 200px;\n  height: 100px;\n  background-color: ${getColor(\"grayBlue\", \"09\")};\n  img {\n    width: 100%;\n    height: 100%;\n    object-fit: scale-down;\n  }\n`\n\nexport const replyNameStyle = css`\n  font-weight: 400;\n  font-size: 14px;\n  line-height: 22px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\nexport const replyTextStyle = css`\n  max-height: 200px;\n  overflow-y: auto;\n  word-wrap: break-word;\n`\n\nexport const receivingContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  padding: 16px 40px 8px;\n`\n\nexport const receivingAvatarStyle = css`\n  height: 32px;\n  width: 32px;\n  margin-right: 16px;\n  background-color: ${getColor(\"grayBlue\", \"09\")};\n  border-radius: 50%;\n`\n\nexport const optionsStyle = (isAllShow: boolean) => {\n  return css`\n    background-color: ${getColor(\"white\", \"01\")};\n    font-weight: 400;\n    font-size: 14px;\n    line-height: 22px;\n    display: flex;\n    border-radius: 4px;\n    flex-direction: row;\n    border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n    & div {\n      padding: 6px;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      cursor: pointer;\n    }\n    & div:last-of-type {\n      border-left: ${isAllShow\n        ? `1px solid ${getColor(\"grayBlue\", \"08\")}`\n        : \"none\"};\n    }\n    & div:hover {\n      background-color: ${getColor(\"grayBlue\", \"08\")};\n    }\n  `\n}\n\nexport const loadingStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background-color: ${getColor(\"gray\", \"01\")}; // ??\n  color: ${getColor(\"black\", \"01\")};\n`\nexport const audioWrapperStyle = css`\n  & > audio {\n    &::-webkit-media-controls {\n      justify-content: center;\n    }\n  }\n`\n\nexport const audioStyle = (isReply?: boolean) => css`\n  height: 50px;\n  width: ${isReply ? \"200px\" : \"50%\"};\n  max-width: ${isReply ? 320 : 344}px;\n  min-width: 290px;\n`\n\nexport const videoStyle = (isReply?: boolean) => css`\n  height: 150px;\n  width: ${isReply ? \"200px\" : \"50%\"};\n  max-width: ${isReply ? 320 : 344}px;\n  min-width: 290px;\n`\n\nexport const sendImageStyle = css`\n  width: 50%;\n  max-width: 344px;\n  min-width: 290px;\n`\n\nexport const replyToStyle = css`\n  display: flex;\n  width: 100%;\n  flex-direction: column;\n  gap: 8px;\n  padding: 16px 24px;\n  box-shadow: 0px -4px 12px 0px rgba(0, 0, 0, 0.04);\n`\nexport const replyContent = css`\n  overflow: hidden;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 22px;\n  text-overflow: ellipsis;\n  display: -webkit-box;\n  -webkit-box-orient: vertical;\n  -webkit-line-clamp: 2;\n`\n\nexport const replyToHeaderStyle = css`\n  display: flex;\n  flex-direction: row;\n  flex-wrap: nowrap;\n  justify-content: space-between;\n  align-items: center;\n  color: ${getColor(\"blue\", \"03\")};\n  text-align: justify;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 22px;\n  & > span:last-of-type {\n    cursor: pointer;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/useSizeChange.ts",
    "content": "import { useCallback, useEffect, useRef } from \"react\"\nimport { VirtuosoHandle } from \"react-virtuoso\"\n\nexport const useSizeChange = (length: number) => {\n  const containerRef = useRef<HTMLDivElement>(null)\n  const messageListRef = useRef<VirtuosoHandle | null>(null)\n  const containerHeight = useRef(0)\n\n  const setContainerHight = useCallback((height: number) => {\n    containerHeight.current = height\n  }, [])\n\n  const handleOnSizeChange = useCallback(() => {\n    Promise.resolve().then(() => {\n      messageListRef.current?.scrollToIndex({\n        index: length ? length - 1 : 0,\n      })\n    })\n  }, [length])\n  useEffect(() => {\n    if (containerRef.current) {\n      containerHeight.current = containerRef.current.clientHeight\n    }\n  }, [containerRef])\n\n  useEffect(() => {\n    let observe: HTMLDivElement | null\n    const resizeObserver = new ResizeObserver((entries) => {\n      for (let entry of entries) {\n        if (entry.target === containerRef.current) {\n          const { height } = entry.contentRect\n          if (height !== containerHeight.current) {\n            handleOnSizeChange()\n            setContainerHight(height)\n          }\n        }\n      }\n    })\n\n    if (containerRef.current) {\n      resizeObserver.observe(containerRef.current)\n      observe = containerRef.current\n    }\n\n    return () => {\n      if (observe) {\n        resizeObserver.unobserve(observe)\n        observe = null\n      }\n    }\n  })\n\n  useEffect(() => {\n    handleOnSizeChange()\n  }, [handleOnSizeChange, length])\n  return {\n    messageListRef,\n    containerRef,\n    handleOnSizeChange,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/utils.ts",
    "content": "import DefaultAvatar from \"@/assets/chat/empty.svg\"\nimport { MessageContent, Pluralize } from \"@/widgetLibrary/ChatWidget/interface\"\n\nexport const formatEventOptions = (\n  mappedOption: Pluralize<MessageContent> = {\n    messageIds: [],\n    messages: [],\n    messageTypes: [],\n    senderAvatars: [],\n    replyMessageIds: [],\n    senderIds: [],\n    senderNames: [],\n    sendTimes: [],\n  },\n) => {\n  const messageId = mappedOption.messageIds ?? []\n  const message = mappedOption.messages ?? []\n  const messageType = mappedOption.messageTypes ?? []\n  const senderAvatar = mappedOption.senderAvatars ?? []\n  const replyMessageId = mappedOption.replyMessageIds ?? []\n  const senderId = mappedOption.senderIds ?? []\n  const senderName = mappedOption.senderNames ?? []\n  const sendTime = mappedOption.sendTimes ?? []\n  const maxLength = Math.max(\n    messageId.length,\n    message.length,\n    messageType.length,\n    senderAvatar.length,\n    replyMessageId.length,\n    senderId.length,\n    senderName.length,\n    sendTime.length,\n  )\n  const messageList: MessageContent[] = []\n  for (let i = 0; i < maxLength; i++) {\n    const messageIdItem = messageId[i] || `${i + 1}`\n    const messageItem = message[i] || \"\"\n    const messageTypeItem = messageType[i] || \"text\"\n    const senderAvatarItem = senderAvatar[i] || DefaultAvatar\n    const replyMessageIdtem = replyMessageId[i] || \"\"\n    const senderIdItem = senderId[i] || \"\"\n    const senderNameItem = senderName[i] ?? \"\"\n    const sendTimeItem = sendTime[i] ?? \"\"\n    messageList.push({\n      messageId: messageIdItem,\n      message: safeNodeValue(messageItem),\n      messageType: messageTypeItem,\n      senderAvatar: senderAvatarItem,\n      replyMessageId: replyMessageIdtem,\n      senderId: senderIdItem,\n      senderName: safeNodeValue(senderNameItem),\n      sendTime: safeNodeValue(sendTimeItem),\n    })\n  }\n  return messageList\n}\nconst safeNodeValue = (value: unknown) => {\n  return typeof value === \"string\" ? value : \"\"\n}\n\nexport const addOrDelLoading = (\n  receiving: boolean,\n  messageList: MessageContent[],\n  updateLoading: (messageList: MessageContent[]) => void,\n  handleOnSizeChange: () => void,\n) => {\n  if (!messageList.length) return\n  if (receiving) {\n    updateLoading([...messageList, { loading: true }])\n  } else {\n    updateLoading(messageList)\n    handleOnSizeChange()\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ChatWidget/widgetConfig.tsx",
    "content": "import ChatWidgetIcon from \"@/assets/widgetCover/chat.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { BasicContainerConfig } from \"@/widgetLibrary/BasicContainer/BasicContainer\"\nimport { BUTTON_WIDGET_CONFIG } from \"@/widgetLibrary/ButtonWidget\"\nimport { INPUT_WIDGET_CONFIG } from \"@/widgetLibrary/InputWidget\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\nimport { emptyMessage } from \"./constants\"\n\nexport const CHAT_WIDGET_CONFIG: WidgetConfig = {\n  version: 0,\n  type: \"CHAT_WIDGET\",\n  displayName: \"chat\",\n  widgetName: i18n.t(\"widget.chat.name\"),\n  icon: <ChatWidgetIcon />,\n  keywords: [\"chat\", \"聊天\"],\n  sessionType: \"PRESENTATION\",\n  resizeDirection: RESIZE_DIRECTION.ALL,\n  w: 18,\n  h: 50,\n  childrenNode: [\n    {\n      ...BasicContainerConfig,\n      childrenNode: [\n        {\n          ...INPUT_WIDGET_CONFIG,\n          w: 28,\n          h: 5,\n          x: 0,\n          y: 1,\n          defaults: {\n            ...INPUT_WIDGET_CONFIG.defaults,\n            labelHidden: true,\n            showVisibleButton: false,\n            value: \"\",\n          },\n        },\n        {\n          ...BUTTON_WIDGET_CONFIG,\n          w: 3,\n          h: 5,\n          x: 29,\n          y: 1,\n          defaults: {\n            ...BUTTON_WIDGET_CONFIG.defaults,\n            text: \"Send\",\n          },\n        },\n      ],\n    },\n  ],\n  defaults: {\n    dataSources: `{{[\n      {\n        messageId: \"001\",\n        message: \"What is ILLA Cloud?\",\n        sendTime: \"2022-12-31 23:59:59\",\n        replyMessageId: \"\",\n        senderName: \"James\",\n        senderId: \"1\",\n        senderAvatar:\n          \"https://images.pexels.com/photos/6045220/pexels-photo-6045220.jpeg?auto=compress&cs=tinysrgb&w=800\",\n        messageType: \"text\",\n      },\n      {\n        messageId: \"002\",\n        message: \"ILLA Cloud is a low-code platform for developers to build internal tools in minutes.\",\n        replyMessageId: \"001\",\n        sendTime: \"2023-01-01 00:00:00\",\n        senderName: \"Tom\",\n        senderId: \"2\",\n        senderAvatar:\n          \"https://images.pexels.com/photos/1888403/pexels-photo-1888403.jpeg?auto=compress&cs=tinysrgb&w=800\",\n        messageType: \"text\",\n      },\n    ]}}`,\n    backgroundColor: \"white\",\n    leftMessageColor: \"grayBlue\",\n    rightMessageColor: \"blue\",\n    enableMessageSelection: \"{{true}}\",\n    toolbarReply: \"{{true}}\",\n    toolbarDelete: \"{{true}}\",\n    showAvatar: \"{{true}}\",\n    showName: \"{{true}}\",\n    showSendTime: \"{{true}}\",\n    showFooter: \"{{true}}\",\n    timeFormat: \"YYYY-MM-DD hh:mm:ss\",\n    selectionType: \"rightClick\",\n    selectedMessage: emptyMessage,\n    replyMessage: emptyMessage,\n    radius: \"4px\",\n    shadow: \"small\",\n    avatarPadding: \"32px\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CheckboxGroupWidget/checkboxGroup.tsx",
    "content": "import { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { CheckboxGroup, CheckboxOption } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyCenterLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { formatSelectOptions } from \"@/widgetLibrary/PublicSector/utils/formatSelectOptions\"\nimport {\n  CheckboxGroupWidgetProps,\n  WrappedCheckboxGroupProps,\n} from \"./interface\"\n\nexport const WrappedCheckbox: FC<WrappedCheckboxGroupProps> = (props) => {\n  const {\n    value,\n    disabled,\n    direction,\n    colorScheme,\n    options,\n    handleOnChange,\n    getValidateMessage,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  } = props\n\n  const changeValue = (value?: unknown) => {\n    new Promise((resolve) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value: value || \"\",\n            validateMessage: message,\n          },\n        },\n      ])\n      resolve(true)\n    }).then(() => {\n      handleOnChange?.()\n    })\n  }\n\n  return (\n    <CheckboxGroup\n      value={value}\n      disabled={disabled}\n      options={options}\n      direction={direction}\n      colorScheme={colorScheme}\n      onChange={changeValue}\n    />\n  )\n}\n\nWrappedCheckbox.displayName = \"WrappedCheckbox\"\n\nexport const CheckboxWidget: FC<CheckboxGroupWidgetProps> = (props) => {\n  const {\n    value,\n    optionConfigureMode,\n    manualOptions,\n    mappedOption,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    customRule,\n    hideValidationMessage,\n    validateMessage,\n    updateComponentHeight,\n    triggerEventHandler,\n  } = props\n\n  const finalOptions = useMemo(() => {\n    return formatSelectOptions(optionConfigureMode, manualOptions, mappedOption)\n  }, [optionConfigureMode, manualOptions, mappedOption])\n\n  const getValidateMessage = useCallback(\n    (value?: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required],\n  )\n\n  const handleValidate = useCallback(\n    (value?: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [getValidateMessage, handleUpdateDsl],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: any) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: undefined })\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {},\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    handleValidate,\n    updateComponentRuntimeProps,\n    value,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyCenterLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedCheckbox\n            {...props}\n            options={finalOptions as CheckboxOption[]}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\n\nCheckboxWidget.displayName = \"CheckboxWidget\"\nexport default CheckboxWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CheckboxGroupWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const CHECK_BOX_GROUP_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CheckboxGroupWidget/index.tsx",
    "content": "export { CHECKBOX_GROUP_PANEL_CONFIG } from \"./panelConfig\"\nexport { CHECKBOX_GROUP_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { CHECK_BOX_GROUP_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CheckboxGroupWidget/interface.ts",
    "content": "import { CheckboxGroupProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedCheckboxGroupProps\n  extends Pick<\n    CheckboxGroupProps,\n    \"value\" | \"disabled\" | \"options\" | \"direction\" | \"colorScheme\"\n  > {\n  handleUpdateDsl: (value: any) => void\n  displayName: string\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n}\n\nexport interface CheckboxGroupWidgetProps\n  extends Omit<WrappedCheckboxGroupProps, \"handleOnChange\">,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    ValidateMessageOldProps {\n  optionConfigureMode?: \"dynamic\" | \"static\"\n  manualOptions?: {\n    label: string\n    value: string | number\n    disabled?: boolean\n    extra?: any\n  }[]\n  mappedOption?: {\n    labels: string[]\n    values: any[]\n    disables: boolean[]\n  }\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CheckboxGroupWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { CHECK_BOX_GROUP_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/CheckboxGroupWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"checkboxGroup\"\nexport const CHECKBOX_GROUP_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-options`,\n    groupName: i18n.t(\"editor.inspect.setter_group.options\"),\n    children: [\n      {\n        id: `${baseWidgetName}-options-mode`,\n        attrName: \"optionConfigureMode\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: i18n.t(\"widget.public.select_options.manual\"),\n            value: \"static\",\n          },\n          {\n            label: i18n.t(\"widget.public.select_options.mapped\"),\n            value: \"dynamic\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-options`,\n        useCustomLayout: true,\n        attrName: \"manualOptions\",\n        setterType: \"OPTION_LIST_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => !value || value === \"static\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-options-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"value\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-options-data-sources`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_sources\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        expectedType: VALIDATION_TYPES.ARRAY,\n        shown: (value) => value === \"dynamic\",\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-options-mapped`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedOption\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => value === \"dynamic\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-mappedOption-labels`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"labels\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-values`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"values\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-disables`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disables\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-options-default-value`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          CHECK_BOX_GROUP_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-direction`,\n        labelName: i18n.t(\"editor.inspect.setter_label.group_layout\"),\n        setterType: \"RADIO_GROUP_SETTER\",\n        attrName: \"direction\",\n        options: [\n          {\n            label: \"horizontal\",\n            value: \"horizontal\",\n          },\n          {\n            label: \"vertical\",\n            value: \"vertical\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-styles`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-coloScheme`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CheckboxGroupWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport CheckboxWidgetIcon from \"@/assets/widgetCover/checkBox.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const CHECKBOX_GROUP_WIDGET_CONFIG: WidgetConfig = {\n  type: \"CHECKBOX_GROUP_WIDGET\",\n  widgetName: i18n.t(\"widget.check_box_group.name\"),\n  displayName: \"checkboxGroup\",\n  icon: <CheckboxWidgetIcon />,\n  keywords: [\"Checkbox Group\", \"复选框组\"],\n  sessionType: \"SELECT\",\n  w: 10,\n  h: 5,\n  version: 0,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  defaults: {\n    optionConfigureMode: \"static\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    manualOptions: [\n      { id: `option-${v4()}`, label: \"Option 1\", value: \"Option 1\" },\n      { id: `option-${v4()}`, label: \"Option 2\", value: \"Option 2\" },\n      { id: `option-${v4()}`, label: \"Option 3\", value: \"Option 3\" },\n    ],\n    dataSources: \"{{[]}}\",\n    direction: \"horizontal\",\n    colorScheme: \"blue\",\n    formDataKey: \"radioButton\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CircleProgressWidget/circleProgress.tsx",
    "content": "import { FC, useEffect, useMemo } from \"react\"\nimport useMeasure from \"react-use-measure\"\nimport { Progress } from \"@illa-design/react\"\nimport { applyContainerCss } from \"@/widgetLibrary/CircleProgressWidget/style\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  CircleProgressWidgetProps,\n  WrappedCircleProgressProps,\n} from \"./interface\"\n\nexport const WrappedCircleProgress: FC<WrappedCircleProgressProps> = (\n  props,\n) => {\n  const {\n    value,\n    showText,\n    color,\n    trailColor,\n    strokeWidth,\n    finalWidth,\n    finalHeight,\n  } = props\n\n  const _strokeWidth = useMemo(() => {\n    return !isNaN(Number(strokeWidth)) ? strokeWidth + \"px\" : strokeWidth\n  }, [strokeWidth])\n\n  // delete scale square padding\n  const progressWidth = Math.min(finalWidth, finalHeight) - 8 + \"px\"\n\n  return (\n    <Progress\n      type=\"circle\"\n      percent={value}\n      showText={!showText}\n      w={progressWidth}\n      color={color}\n      trailColor={trailColor}\n      strokeWidth={_strokeWidth}\n    />\n  )\n}\n\nWrappedCircleProgress.displayName = \"WrappedCircleProgress\"\n\nexport const CircleProgressWidget: FC<CircleProgressWidgetProps> = (props) => {\n  const {\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    alignment,\n    tooltipText,\n  } = props\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: number) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: 0 })\n      },\n    })\n\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n  ])\n\n  const [wrapperRef, bounds] = useMeasure()\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div css={applyContainerCss(alignment)} ref={wrapperRef}>\n        <WrappedCircleProgress\n          {...props}\n          finalHeight={bounds.height}\n          finalWidth={bounds.width}\n        />\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nCircleProgressWidget.displayName = \"CircleProgressWidget\"\nexport default CircleProgressWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CircleProgressWidget/eventHandlerConfig.ts",
    "content": "import { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const CIRCLE_PROGRESS_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [],\n  methods: [\"setValue\", \"clearValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CircleProgressWidget/index.tsx",
    "content": "export { CIRCLE_PROGRESS_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { CIRCLE_PROGRESS_PANEL_CONFIG } from \"./panelConfig\"\nexport { CIRCLE_PROGRESS_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CircleProgressWidget/interface.tsx",
    "content": "import { ProgressProps } from \"@illa-design/react\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport {\n  BaseComponentNodeProps,\n  BaseWidgetProps,\n} from \"@/widgetLibrary/interface\"\n\nexport type Alignment = \"start\" | \"center\" | \"end\"\nexport interface WrappedCircleProgressProps\n  extends Pick<\n      ProgressProps,\n      \"showText\" | \"color\" | \"trailColor\" | \"strokeWidth\"\n    >,\n    BaseComponentNodeProps {\n  value?: number\n  alignment?: \"start\" | \"center\" | \"end\"\n  finalHeight: number\n  finalWidth: number\n}\n\nexport interface CircleProgressWidgetProps\n  extends WrappedCircleProgressProps,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps {}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CircleProgressWidget/panelConfig.tsx",
    "content": "import {\n  HorizontalCenterIcon,\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n} from \"@illa-design/react\"\nimport StrokeWidthIcon from \"@/assets/stroke-width-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst baseWidgetName = \"circle-progress\"\nexport const CIRCLE_PROGRESS_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-Value`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.progress_percentage\"),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-showText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hide_value_label\"),\n        attrName: \"showText\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-alignment`,\n        setterType: \"RADIO_GROUP_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"alignment\",\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"start\",\n          },\n          {\n            label: <HorizontalCenterIcon />,\n            value: \"center\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"end\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-color-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.styles\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"color\",\n            defaultValue: \"blue\",\n          },\n          {\n            id: `${baseWidgetName}-trailColor`,\n            labelName: i18n.t(\"editor.inspect.setter_label.trail_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"trailColor\",\n            defaultValue: \"gray\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.styles\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-strokeWidth`,\n            labelName: i18n.t(\"editor.inspect.setter_label.stroke_width\"),\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <StrokeWidthIcon />,\n            attrName: \"strokeWidth\",\n            defaultValue: \"4px\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CircleProgressWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { Alignment } from \"./interface\"\n\nexport function applyContainerCss(alignment: Alignment = \"center\") {\n  return css`\n    width: 100%;\n    height: 100%;\n    display: flex;\n    justify-content: ${alignment};\n    align-items: center;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CircleProgressWidget/widgetConfig.tsx",
    "content": "import CircleProgressWidgetIcon from \"@/assets/widgetCover/circleProgress.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const CIRCLE_PROGRESS_WIDGET_CONFIG: WidgetConfig = {\n  type: \"CIRCLE_PROGRESS_WIDGET\",\n  displayName: \"circleProgress\",\n  widgetName: i18n.t(\"widget.circle_progress.name\"),\n  keywords: [\"Circle Progress\", \"圆形进度条\"],\n  icon: <CircleProgressWidgetIcon />,\n  sessionType: \"PRESENTATION\",\n  w: 3,\n  h: 12,\n  version: 0,\n  defaults: {\n    value: \"50\",\n    alignment: \"center\",\n    color: \"blue\",\n    trailColor: \"gray\",\n    strokeWidth: \"4px\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CodeScannerWidget/codeModal.tsx",
    "content": "import { CameraDevice } from \"html5-qrcode\"\nimport { FC } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  CloseIcon,\n  Modal,\n  Select,\n  SelectValue,\n  TriggerProvider,\n} from \"@illa-design/react\"\nimport {\n  containerStyle,\n  iconStyle,\n  modalStyle,\n  readerContainer,\n  readerStyle,\n  successContentStyle,\n} from \"./style\"\n\ninterface CodeModalProps {\n  displayName: string\n  errorShow: boolean\n  colorScheme: string\n  devices: CameraDevice[]\n  selectDeviceID: string\n  handleCancel: () => void\n  handleSwitchDevice: (value?: SelectValue) => void\n}\n\ninterface SuccessModalProps {\n  colorScheme: string\n  value: string\n  onOK: () => void\n  onClose: () => void\n}\n\nconst SCAN_MODAL_INDEX = 1000\nconst SUCCESS_MODAL_INDEX = 1005\n\nexport const CodeModal: FC<CodeModalProps> = ({\n  displayName,\n  errorShow,\n  devices,\n  colorScheme,\n  selectDeviceID,\n  handleCancel,\n  handleSwitchDevice,\n}) => {\n  const { t } = useTranslation()\n  return createPortal(\n    <TriggerProvider zIndex={SCAN_MODAL_INDEX}>\n      <Modal\n        visible\n        _css={modalStyle}\n        onCancel={handleCancel}\n        footer={false}\n        withoutPadding\n        closable\n      >\n        <div css={containerStyle}>\n          <span css={iconStyle} onClick={handleCancel}>\n            <CloseIcon />\n          </span>\n          {errorShow ? (\n            <span>\n              {t(\"editor.inspect.setter_message.qr_code.startup_failed\")}\n            </span>\n          ) : (\n            <div css={readerContainer}>\n              <div id={`${displayName}-reader`} css={readerStyle} />\n              <Select\n                colorScheme={colorScheme}\n                options={devices.map((item) => {\n                  return {\n                    label: item.label,\n                    value: item.id,\n                  }\n                })}\n                value={selectDeviceID}\n                onChange={handleSwitchDevice}\n              />\n            </div>\n          )}\n        </div>\n      </Modal>\n    </TriggerProvider>,\n    document.body,\n  )\n}\n\nexport const SuccessModal: FC<SuccessModalProps> = ({\n  value,\n  colorScheme,\n  onClose,\n  onOK,\n}) => {\n  const { t } = useTranslation()\n  return createPortal(\n    <TriggerProvider zIndex={SUCCESS_MODAL_INDEX}>\n      <Modal\n        visible\n        _css={modalStyle}\n        title={t(\"editor.inspect.setter_message.scan.title\")}\n        okText={t(\"editor.inspect.setter_message.scan.rescan\")}\n        cancelText={t(\"editor.inspect.setter_message.scan.close\")}\n        onOk={onOK}\n        onCancel={onClose}\n        okButtonProps={{\n          colorScheme,\n        }}\n      >\n        <span css={successContentStyle}>\n          {t(\"editor.inspect.setter_message.scan.desc\", {\n            scanValue: value,\n          })}\n        </span>\n      </Modal>\n    </TriggerProvider>,\n    document.body,\n  )\n}\nexport default CodeModal\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CodeScannerWidget/codeScanner.tsx",
    "content": "import { AnimatePresence } from \"framer-motion\"\nimport { CameraDevice, Html5Qrcode } from \"html5-qrcode\"\nimport { t } from \"i18next\"\nimport { FC, useCallback, useEffect, useRef, useState } from \"react\"\nimport { Button, SelectValue } from \"@illa-design/react\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { AutoHeightContainer } from \"../PublicSector/AutoHeightContainer\"\nimport { CodeModal, SuccessModal } from \"./codeModal\"\nimport { CodeScannerWidgetProps, WrappedCodeScannerProps } from \"./interface\"\nimport { fullStyle } from \"./style\"\n\nconst WrappedCodeScanner: FC<WrappedCodeScannerProps> = ({\n  displayName,\n  errorShow,\n  showScanner,\n  showSuccessModal,\n  selectDeviceID,\n  devices,\n  value = \"\",\n  variant = \"fill\",\n  disabled,\n  buttonText = \"Scanner\",\n  colorScheme = \"blue\",\n  handleCancel,\n  handleOpenScanner,\n  handleSwitchDevice,\n  handleResumeScan,\n}) => {\n  return (\n    <>\n      <Button\n        disabled={disabled}\n        variant={variant}\n        colorScheme={colorScheme}\n        fullWidth\n        fullHeight\n        onClick={handleOpenScanner}\n      >\n        {buttonText}\n      </Button>\n      <AnimatePresence>\n        {showScanner && (\n          <CodeModal\n            displayName={displayName}\n            errorShow={errorShow}\n            colorScheme={colorScheme}\n            devices={devices}\n            selectDeviceID={selectDeviceID}\n            handleCancel={handleCancel}\n            handleSwitchDevice={handleSwitchDevice}\n          />\n        )}\n      </AnimatePresence>\n      <AnimatePresence>\n        {showSuccessModal && (\n          <SuccessModal\n            value={value}\n            colorScheme={colorScheme}\n            onClose={handleCancel}\n            onOK={handleResumeScan}\n          />\n        )}\n      </AnimatePresence>\n    </>\n  )\n}\n\nWrappedCodeScanner.displayName = \"WrappedCodeScanner\"\n\nexport const CodeScannerWidget: FC<CodeScannerWidgetProps> = (props) => {\n  const {\n    displayName,\n    tooltipText,\n    closeAfterScan,\n    triggerEventHandler,\n    updateComponentHeight,\n    updateComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    deleteComponentRuntimeProps,\n  } = props\n\n  const [errorShow, setErrorShow] = useState(false)\n  const [showScanner, setShowScanner] = useState(false)\n  const [devices, setDevices] = useState<CameraDevice[]>([])\n  const [selectDeviceID, setSelectDeviceID] = useState(\"\")\n  const html5QrCodeRef = useRef<Html5Qrcode | null>()\n  const [showSuccessModal, setShowSuccessModal] = useState(false)\n\n  const handleCancel = useCallback(() => {\n    setShowScanner(false)\n    setShowSuccessModal(false)\n    html5QrCodeRef.current?.stop()\n    html5QrCodeRef.current = null\n    triggerEventHandler(\"closeScanner\")\n  }, [triggerEventHandler])\n\n  const handleShowSuccessModal = useCallback(() => {\n    html5QrCodeRef.current?.pause()\n    setShowSuccessModal(true)\n  }, [])\n\n  const handleResumeScan = () => {\n    html5QrCodeRef.current?.resume()\n    setShowSuccessModal(false)\n  }\n\n  const handleScan = useCallback(\n    (id: string, withoutCameraId?: boolean) => {\n      if (!html5QrCodeRef.current) {\n        html5QrCodeRef.current = new Html5Qrcode(`${displayName}-reader`, false)\n      }\n      const cameraIdOrConfig = withoutCameraId ? { facingMode: id } : id\n      html5QrCodeRef.current.start(\n        cameraIdOrConfig,\n        {\n          fps: 2,\n        },\n        (decodedText) => {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                value: decodedText,\n              },\n            },\n          ])\n          triggerEventHandler(\"scanSuccessful\")\n          !closeAfterScan && handleShowSuccessModal()\n          closeAfterScan && handleCancel()\n        },\n        () => {},\n      )\n    },\n    [\n      closeAfterScan,\n      displayName,\n      handleCancel,\n      handleShowSuccessModal,\n      handleUpdateMultiExecutionResult,\n      triggerEventHandler,\n    ],\n  )\n\n  const handleStartScanner = useCallback((): Promise<CameraDevice[]> => {\n    return new Promise((resolve, reject) => {\n      Html5Qrcode.getCameras()\n        .then((devices: CameraDevice[]) => {\n          setErrorShow(false)\n          resolve(devices)\n        })\n        .catch((e) => {\n          setErrorShow(true)\n          reject(e)\n        })\n    })\n  }, [])\n\n  const handleOpenScanner = useCallback(() => {\n    setShowScanner(true)\n    handleStartScanner().then((devices: CameraDevice[]) => {\n      triggerEventHandler(\"openScanner\")\n      if (!devices || !Array.isArray(devices) || devices.length === 0) return\n      if (devices.length > 1) {\n        const withoutIDDevices = [\n          {\n            id: \"user\",\n            label: t(\"editor.inspect.setter_label.scan.front\"),\n          },\n          {\n            id: \"environment\",\n            label: t(\"editor.inspect.setter_label.scan.rear\"),\n          },\n        ]\n        setDevices(withoutIDDevices)\n        handleScan(withoutIDDevices[1].id, true)\n        setSelectDeviceID(withoutIDDevices[1].id)\n      } else {\n        setDevices(devices)\n        handleScan(devices[0].id)\n        setSelectDeviceID(devices[0].id)\n      }\n    })\n  }, [handleScan, handleStartScanner, triggerEventHandler])\n\n  const handleSwitchDevice = async (id?: SelectValue) => {\n    await html5QrCodeRef.current?.stop()\n    handleStartScanner().then(() => {\n      handleScan(id as string, true)\n      setSelectDeviceID(id as string)\n    })\n  }\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      clearValue: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: undefined,\n            },\n          },\n        ])\n      },\n      openScanner: handleOpenScanner,\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    handleOpenScanner,\n    deleteComponentRuntimeProps,\n    displayName,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n  ])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={fullStyle}>\n          <WrappedCodeScanner\n            {...props}\n            errorShow={errorShow}\n            showScanner={showScanner}\n            devices={devices}\n            selectDeviceID={selectDeviceID}\n            handleCancel={handleCancel}\n            handleOpenScanner={handleOpenScanner}\n            handleSwitchDevice={handleSwitchDevice}\n            showSuccessModal={showSuccessModal}\n            handleResumeScan={handleResumeScan}\n          />\n        </div>\n      </TooltipWrapper>\n    </AutoHeightContainer>\n  )\n}\n\nCodeScannerWidget.displayName = \"CodeScannerWidget\"\nexport default CodeScannerWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CodeScannerWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const CODE_SCANNER_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.scanSuccessful\",\n      ),\n      value: \"scanSuccessful\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.openScanner\",\n      ),\n      value: \"openScanner\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.closeScanner\",\n      ),\n      value: \"closeScanner\",\n    },\n  ],\n  methods: [\"clearValue\", \"openScanner\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CodeScannerWidget/index.ts",
    "content": "export { CODE_SCANNER_PANEL_CONFIG } from \"./panelConfig\"\nexport { CODE_SCANNER_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { CODE_SCANNER_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CodeScannerWidget/interface.ts",
    "content": "import { CameraDevice } from \"html5-qrcode\"\nimport { ButtonVariant, SelectValue } from \"@illa-design/react\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedCodeScannerProps extends CodeScannerWidgetProps {\n  errorShow: boolean\n  showScanner: boolean\n  showSuccessModal: boolean\n  devices: CameraDevice[]\n  selectDeviceID: string\n  handleCancel: () => void\n  handleOpenScanner: () => void\n  handleSwitchDevice: (value?: SelectValue) => void\n  handleResumeScan: () => void\n}\n\nexport interface CodeScannerWidgetProps\n  extends BaseWidgetProps,\n    TooltipWrapperProps {\n  value?: string\n  disabled?: boolean\n  closeAfterScan?: boolean\n  buttonText?: string\n  hidden?: boolean\n  variant?: ButtonVariant\n  colorScheme?: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CodeScannerWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"../PublicSector/utils/generatorEventHandlerConfig\"\nimport { CODE_SCANNER_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n\nconst baseWidgetName = \"scanner\"\nexport const CODE_SCANNER_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          CODE_SCANNER_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-close-after-scan`,\n        labelName: i18n.t(\"editor.inspect.setter_label.scan.close_after_scan\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"closeAfterScan\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"false\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-start-text`,\n        labelName: i18n.t(\"editor.inspect.setter_label.scan.button_text\"),\n        attrName: \"buttonText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"false\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-variant`,\n        setterType: \"RADIO_GROUP_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.variant\"),\n        attrName: \"variant\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_default_value.fill\"),\n            value: \"fill\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_default_value.outline\"),\n            value: \"outline\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-style-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-colors-theme-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CodeScannerWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const fullStyle = css`\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n  display: flex;\n  align-items: center;\n`\n\nexport const containerStyle = css`\n  display: flex;\n  flex-direction: column;\n  align-items: flex-start;\n  gap: 24px;\n  padding: 24px;\n  position: relative;\n`\n\nexport const iconStyle = css`\n  position: absolute;\n  top: 8px;\n  right: 8px;\n  width: 24px;\n  height: 24px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  border-radius: 4px;\n  font-size: 12px;\n  :hover {\n    background-color: ${getColor(\"grayBlue\", \"09\")};\n  }\n`\n\nexport const modalStyle = css`\n  border: unset;\n  width: 486px;\n  min-width: 486px;\n  background: ${getColor(\"white\", \"01\")};\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  box-shadow: 0 4px 16px rgb(0 0 0 / 8%);\n  border-radius: 8px;\n  overflow: hidden;\n\n  ${applyMobileStyle(css`\n    width: 358px;\n    min-width: 358px;\n    border-radius: 8px;\n  `)}\n`\n\nexport const readerContainer = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n  padding-top: 24px;\n`\n\nexport const readerStyle = css`\n  position: relative;\n  overflow: hidden;\n  box-sizing: border-box;\n  width: 100%;\n  min-height: 328px;\n  border-radius: 8px;\n  background-color: ${getColor(\"grayBlue\", \"08\")};\n  & video {\n    max-width: 100%;\n    width: 100%;\n    min-height: 232px;\n  }\n`\n\nexport const successContentStyle = css`\n  width: 100%;\n  text-align: center;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 400;\n  word-wrap: break-word;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/CodeScannerWidget/widgetConfig.tsx",
    "content": "import CodeScannerWidgetIcon from \"@/assets/widgetCover/code-scanner.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const CODE_SCANNER_WIDGET_CONFIG: WidgetConfig = {\n  type: \"CODE_SCANNER_WIDGET\",\n  widgetName: i18n.t(\"widget.scanner.name\"),\n  displayName: \"scanner\",\n  w: 6,\n  h: 5,\n  icon: <CodeScannerWidgetIcon />,\n  keywords: [\n    \"Scanner\",\n    \"QR Scanner\",\n    \"Code Scanner\",\n    \"扫码器\",\n    \"二维码扫描器\",\n    \"条形码扫描器\",\n  ],\n  sessionType: \"PRESENTATION\",\n  version: 0,\n  defaults: {\n    value: undefined,\n    buttonText: \"Scanner\",\n    variant: \"fill\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ContainerWidget/container.tsx",
    "content": "import { FC, useCallback, useEffect, useMemo, useRef } from \"react\"\nimport { ContainerProps } from \"@/widgetLibrary/ContainerWidget/interface\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport RenderChildrenCanvas from \"../PublicSector/RenderChildrenCanvas\"\nimport { ContainerEmptyState } from \"./emptyState\"\nimport { applyContainerWrapperStyle } from \"./style\"\n\nexport const ContainerWidget: FC<ContainerProps> = (props) => {\n  const {\n    currentIndex,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    viewList,\n    tooltipText,\n    childrenNode,\n    columnNumber,\n    dynamicHeight = \"fixed\",\n    triggerEventHandler,\n    updateComponentHeight,\n    linkWidgetDisplayName,\n    padding,\n    displayName,\n    handleUpdateMultiExecutionResult,\n  } = props\n  const preCurrentViewIndex = useRef<number>(currentIndex)\n\n  useEffect(() => {\n    if (typeof preCurrentViewIndex.current !== \"number\") {\n      preCurrentViewIndex.current = currentIndex\n    }\n    if (preCurrentViewIndex.current !== currentIndex) {\n      triggerEventHandler(\"change\")\n      preCurrentViewIndex.current = currentIndex\n    }\n  }, [currentIndex, triggerEventHandler])\n\n  const handleOnClick = useCallback(() => {\n    triggerEventHandler(\"click\")\n  }, [triggerEventHandler])\n\n  const enableAutoHeight = useMemo(() => {\n    switch (dynamicHeight) {\n      case \"auto\":\n        return true\n      case \"limited\":\n        return true\n      case \"fixed\":\n      default:\n        return false\n    }\n  }, [dynamicHeight])\n\n  const handleUpdateHeight = useCallback(\n    (height: number) => {\n      if (!updateComponentHeight || !enableAutoHeight) return\n      updateComponentHeight(height + 2)\n    },\n    [enableAutoHeight, updateComponentHeight],\n  )\n\n  const handleUpdateOriginalDSLAttrs = useCallback(\n    (updateSlice: Record<string, any>) => {\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: updateSlice,\n        },\n      ])\n      if (linkWidgetDisplayName && linkWidgetDisplayName.length > 0) {\n        const curUpdateSlice = linkWidgetDisplayName.map((name) => ({\n          displayName: name,\n          value: updateSlice,\n        }))\n\n        handleUpdateMultiExecutionResult(curUpdateSlice)\n      }\n    },\n    [displayName, handleUpdateMultiExecutionResult, linkWidgetDisplayName],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps?.({\n      setCurrentViewKey: (key: string) => {\n        const index = viewList.findIndex((viewItem) => viewItem.key === key)\n        if (index === -1) return\n        handleUpdateOriginalDSLAttrs({\n          currentIndex: index,\n          currentKey: key,\n        })\n      },\n      setCurrentViewIndex: (index: string) => {\n        const numberIndex = parseInt(index)\n        const view = viewList[numberIndex]\n        if (!view) return\n        handleUpdateOriginalDSLAttrs({\n          currentIndex: numberIndex,\n          currentKey: view.key,\n        })\n      },\n      showNextView: (loop: boolean) => {\n        let newCurrentIndex = currentIndex + 1\n        if (newCurrentIndex >= viewList.length) {\n          if (!loop) return\n          newCurrentIndex = 0\n        }\n        const currentView = viewList[newCurrentIndex]\n        handleUpdateOriginalDSLAttrs({\n          currentIndex: newCurrentIndex,\n          currentKey: currentView.key,\n        })\n      },\n      showNextVisibleView: (loop: boolean) => {\n        let newCurrentIndex = currentIndex + 1\n        if (newCurrentIndex >= viewList.length) {\n          if (!loop) return\n          newCurrentIndex = 0\n        }\n        let currentView = viewList[newCurrentIndex]\n        while (currentView.hidden || currentView.disabled) {\n          newCurrentIndex++\n          currentView = viewList[newCurrentIndex]\n          if (newCurrentIndex >= viewList.length) {\n            if (!loop) return\n            newCurrentIndex = 0\n          }\n        }\n        handleUpdateOriginalDSLAttrs({\n          currentIndex: newCurrentIndex,\n          currentKey: currentView.key,\n        })\n      },\n      showPreviousView: (loop: boolean) => {\n        let newCurrentIndex = currentIndex - 1\n\n        if (newCurrentIndex < 0) {\n          if (!loop) return\n          newCurrentIndex = viewList.length - 1\n        }\n        const currentView = viewList[newCurrentIndex]\n        handleUpdateOriginalDSLAttrs({\n          currentIndex: newCurrentIndex,\n          currentKey: currentView.key,\n        })\n      },\n      showPreviousVisibleView: (loop: boolean) => {\n        let newCurrentIndex = currentIndex - 1\n\n        if (newCurrentIndex < 0) {\n          if (!loop) return\n          newCurrentIndex = viewList.length - 1\n        }\n        let currentView = viewList[newCurrentIndex]\n        while (currentView.hidden || currentView.disabled) {\n          newCurrentIndex--\n          currentView = viewList[newCurrentIndex]\n          if (newCurrentIndex < 0) {\n            if (!loop) return\n            newCurrentIndex = viewList.length - 1\n          }\n        }\n        handleUpdateOriginalDSLAttrs({\n          currentIndex: newCurrentIndex,\n          currentKey: currentView.key,\n        })\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    updateComponentRuntimeProps,\n    handleUpdateOriginalDSLAttrs,\n    viewList,\n    currentIndex,\n  ])\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div css={applyContainerWrapperStyle} onClick={handleOnClick}>\n        {Array.isArray(childrenNode) && currentIndex < childrenNode.length ? (\n          <RenderChildrenCanvas\n            displayName={childrenNode[currentIndex]}\n            columnNumber={columnNumber}\n            handleUpdateHeight={handleUpdateHeight}\n            canResizeCanvas={enableAutoHeight}\n            containerPadding={padding?.size}\n          />\n        ) : (\n          <ContainerEmptyState />\n        )}\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nexport default ContainerWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ContainerWidget/emptyState.tsx",
    "content": "import { FC, useEffect } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getPaddingShape } from \"@/utils/styleUtils/padding\"\nimport {\n  applyEmptyStateWrapperStyle,\n  emptyStateStyle,\n} from \"@/widgetLibrary/ContainerWidget/style\"\n\nexport const ContainerEmptyState: FC<{\n  isInner?: boolean\n  containerPadding?: string\n  handleUpdateHeight?: (height: number) => void\n}> = ({ handleUpdateHeight, isInner, containerPadding = \"0\" }) => {\n  const { t } = useTranslation()\n\n  const paddings = getPaddingShape(containerPadding)\n\n  const paddingTopBottom = paddings.paddingTop + paddings.paddingBottom\n\n  useEffect(() => {\n    if (handleUpdateHeight) {\n      handleUpdateHeight(13 * UNIT_HEIGHT + paddingTopBottom)\n    }\n  }, [handleUpdateHeight, paddingTopBottom])\n\n  return (\n    <div css={applyEmptyStateWrapperStyle(isInner, paddingTopBottom)}>\n      <span css={emptyStateStyle}>{t(\"widget.container.empty\")}</span>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ContainerWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const CONTAINER_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.click\",\n      ),\n      value: \"click\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\n    \"setCurrentViewKey\",\n    \"setCurrentViewIndex\",\n    \"showNextView\",\n    \"showNextVisibleView\",\n    \"showPreviousView\",\n    \"showPreviousVisibleView\",\n  ],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ContainerWidget/index.tsx",
    "content": "export { CONTAINER_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { CONTAINER_PANEL_CONFIG } from \"./panelConfig\"\nexport { CONTAINER_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ContainerWidget/interface.ts",
    "content": "import { ComponentMapNode, PADDING_MODE } from \"@illa-public/public-types\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface viewListItemShaper {\n  id: string\n  key: string\n  label: string\n  disabled?: boolean\n  hidden?: boolean\n}\n\nexport interface ContainerProps extends BaseWidgetProps {\n  currentIndex: number\n  componentNode: ComponentMapNode\n  viewList: viewListItemShaper[]\n  tooltipText?: string\n  h: number\n  linkWidgetDisplayName?: string[]\n  unitH: number\n  columnNumber: number\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  dynamicMinHeight?: number\n  dynamicMaxHeight?: number\n  padding?: {\n    size: string\n    mode: PADDING_MODE\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ContainerWidget/panelConfig.tsx",
    "content": "import RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { CONTAINER_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/ContainerWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"container\"\nexport const CONTAINER_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-views`,\n    groupName: i18n.t(\"editor.inspect.setter_group.views\"),\n    children: [\n      {\n        id: `${baseWidgetName}-views-list`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        useCustomLayout: true,\n        attrName: \"viewList\",\n        setterType: \"CONTAINER_VIEW_SETTER\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-viewList-key`,\n            labelName: i18n.t(\"editor.inspect.setter_label.key\"),\n            attrName: \"key\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-viewList-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-viewList-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n          {\n            id: `${baseWidgetName}-viewList-hidden`,\n            labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n            attrName: \"hidden\",\n            setterType: \"DYNAMIC_SWITCH_SETTER\",\n            useCustomLayout: true,\n            openDynamic: true,\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-views-default`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_views\"),\n        attrName: \"defaultView\",\n        setterType: \"CONTAINER_DEFAULT_VIEW_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          CONTAINER_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-height`,\n        labelName: i18n.t(\"editor.inspect.setter_label.height\"),\n        attrName: \"dynamicHeight\",\n        setterType: \"HEIGHT_MODE_SELECT\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.fixed\"),\n            value: \"fixed\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_limited\"),\n            value: \"limited\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_height\"),\n            value: \"auto\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        attrName: \"hidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-styles`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"border\",\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            attrName: \"radius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n          {\n            id: `${baseWidgetName}-style-shadow`,\n            labelName: i18n.t(\"editor.inspect.setter_label.shadow.shadow\"),\n            attrName: \"shadow\",\n            setterType: \"SHADOW_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"small\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-color`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.color\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-background`,\n            labelName: i18n.t(\"editor.inspect.setter_label.background\"),\n            attrName: \"backgroundColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"#ffffffff\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-padding`,\n        setterType: \"PADDING_INPUT_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_group.padding\"),\n        attrName: \"padding\",\n        useCustomLayout: true,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ContainerWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\nimport {\n  SCROLL_CONTAINER_PADDING,\n  UNIT_HEIGHT,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\n\nexport const emptyStateStyle = css`\n  font-size: 14px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n  text-align: center;\n`\n\nexport const applyEmptyStateWrapperStyle = (\n  isInner: boolean = false,\n  paddingTopBottom: number,\n) => css`\n  height: 100%;\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  min-height: ${isInner\n    ? \"100%\"\n    : 15 * UNIT_HEIGHT - 2 * SCROLL_CONTAINER_PADDING + paddingTopBottom};\n`\n\nexport const applyContainerWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ContainerWidget/widgetConfig.tsx",
    "content": "import { PADDING_MODE } from \"@illa-public/public-types\"\nimport { v4 } from \"uuid\"\nimport ContainerWidgetIcon from \"@/assets/widgetCover/container.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { BasicContainerConfig } from \"@/widgetLibrary/BasicContainer/BasicContainer\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nconst defaultListView = [\n  { id: v4(), key: \"View 1\", label: \"View 1\" },\n  { id: v4(), key: \"View 2\", label: \"View 2\" },\n  { id: v4(), key: \"View 3\", label: \"View 3\" },\n]\n\nexport const CONTAINER_WIDGET_CONFIG: WidgetConfig = {\n  type: \"CONTAINER_WIDGET\",\n  displayName: \"container\",\n  widgetName: i18n.t(\"widget.container.name\"),\n  keywords: [\"container\", \"容器\"],\n  icon: <ContainerWidgetIcon />,\n  sessionType: \"CONTAINER\",\n  w: 10,\n  h: 18,\n  version: 0,\n  childrenNode: [\n    BasicContainerConfig,\n    BasicContainerConfig,\n    BasicContainerConfig,\n  ],\n  defaults: {\n    viewList: defaultListView,\n    currentIndex: 0,\n    currentKey: \"View 1\",\n    backgroundColor: \"#ffffffff\",\n    radius: \"4px\",\n    shadow: \"small\",\n    dynamicHeight: \"auto\",\n    resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n    padding: {\n      mode: PADDING_MODE.ALL,\n      size: \"24\",\n    },\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/ExportAllSetting/index.tsx",
    "content": "import SaveAltIcon from \"@mui/icons-material/SaveAlt\"\nimport { Button, Menu, MenuItem } from \"@mui/material\"\nimport {\n  gridSortedRowIdsSelector,\n  useGridApiContext,\n} from \"@mui/x-data-grid-premium\"\nimport { FC, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\n\nexport const ExportAllSetting: FC = () => {\n  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)\n\n  const apiRef = useGridApiContext()\n\n  const open = Boolean(anchorEl)\n  const handleClose = () => {\n    setAnchorEl(null)\n  }\n\n  const { t } = useTranslation()\n\n  return (\n    <>\n      <Button\n        startIcon={<SaveAltIcon />}\n        size=\"small\"\n        id=\"basic-button\"\n        aria-controls={open ? \"basic-menu\" : undefined}\n        aria-haspopup=\"true\"\n        aria-expanded={open ? \"true\" : undefined}\n        onClick={(event) => {\n          setAnchorEl(event.currentTarget)\n        }}\n      >\n        {t(\"widget.table.export_all_data\")}\n      </Button>\n      <Menu\n        id=\"basic-menu\"\n        anchorEl={anchorEl}\n        open={open}\n        onClose={handleClose}\n        MenuListProps={{\n          \"aria-labelledby\": \"basic-button\",\n        }}\n      >\n        <MenuItem\n          onClick={() => {\n            apiRef.current.exportDataAsCsv({\n              getRowsToExport: (params) =>\n                gridSortedRowIdsSelector(params.apiRef),\n            })\n          }}\n        >\n          {t(\"widget.table.export.csv\")}\n        </MenuItem>\n        <MenuItem\n          onClick={() => {\n            apiRef.current.exportDataAsExcel({\n              getRowsToExport: (params) =>\n                gridSortedRowIdsSelector(params.apiRef),\n            })\n          }}\n        >\n          {t(\"widget.table.export.excel\")}\n        </MenuItem>\n      </Menu>\n    </>\n  )\n}\n\nExportAllSetting.displayName = \"ExportAllSetting\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/Toolbar/index.tsx",
    "content": "import FilterAltIcon from \"@mui/icons-material/FilterAlt\"\nimport RefreshIcon from \"@mui/icons-material/Refresh\"\nimport { Button } from \"@mui/material\"\nimport {\n  GridToolbarColumnsButton,\n  GridToolbarContainer,\n  GridToolbarDensitySelector,\n  GridToolbarExport,\n  GridToolbarFilterButton,\n  GridToolbarQuickFilter,\n} from \"@mui/x-data-grid-premium\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { ExportAllSetting } from \"../ExportAllSetting\"\nimport { ToolbarProps } from \"./interface\"\n\nexport const Toolbar: FC<ToolbarProps> = (props) => {\n  const {\n    columnSetting,\n    filterSetting,\n    densitySetting,\n    exportSetting,\n    exportAllSetting,\n    refreshSetting,\n    quickFilterSetting,\n    onRefresh,\n  } = props\n\n  const { t } = useTranslation()\n\n  return (\n    <GridToolbarContainer>\n      {columnSetting && <GridToolbarColumnsButton />}\n      {filterSetting && (\n        <GridToolbarFilterButton\n          componentsProps={{\n            button: {\n              startIcon: <FilterAltIcon />,\n            },\n          }}\n        />\n      )}\n      {densitySetting && <GridToolbarDensitySelector />}\n      {exportSetting && <GridToolbarExport />}\n      {exportAllSetting && <ExportAllSetting />}\n      {refreshSetting && (\n        <Button\n          startIcon={<RefreshIcon />}\n          size=\"small\"\n          onClick={() => {\n            onRefresh()\n          }}\n        >\n          {t(\"widget.table.refresh\")}\n        </Button>\n      )}\n      {quickFilterSetting && <GridToolbarQuickFilter />}\n    </GridToolbarContainer>\n  )\n}\n\nToolbar.displayName = \"Toolbar\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/Toolbar/interface.ts",
    "content": "export interface ToolbarProps {\n  columnSetting?: boolean\n  refreshSetting?: boolean\n  quickFilterSetting?: boolean\n  exportSetting?: boolean\n  exportAllSetting?: boolean\n  filterSetting?: boolean\n  densitySetting?: boolean\n  onRefresh: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/columnDeal.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport {\n  GridRenderCellParams,\n  GridValueGetterParams,\n} from \"@mui/x-data-grid-premium\"\nimport dayjs from \"dayjs\"\nimport {\n  get,\n  isArray,\n  isBoolean,\n  isDate,\n  isNumber,\n  isObject,\n  isString,\n  toPath,\n} from \"lodash-es\"\nimport ReactMarkdown from \"react-markdown\"\nimport rehypeRaw from \"rehype-raw\"\nimport rehypeSanitize from \"rehype-sanitize\"\nimport remarkGfm from \"remark-gfm\"\nimport {\n  Button,\n  ButtonGroup,\n  Image,\n  Link,\n  Paragraph,\n  Rate,\n  SingleDatePicker,\n  Tag,\n} from \"@illa-design/react\"\nimport { GroupButton } from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnButtonGroupSetter/interface\"\nimport {\n  ColumnConfig,\n  ColumnType,\n} from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter/interface\"\nimport {\n  CurrencyCode,\n  getHashCode,\n  getPreColor,\n  getValueFromMappedValue,\n  isValidLocale,\n} from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/utils\"\nimport { AvatarType, WrapperAvatar } from \"@/widgetLibrary/AvatarWidget\"\nimport {\n  cellContainer,\n  currencyContainerStyle,\n} from \"@/widgetLibrary/DataGridWidget/style\"\nimport { HTMLTags } from \"@/widgetLibrary/TextWidget/constans\"\n\nfunction formatDataGridColumnEvent(path: string, prefix: string) {\n  return convertPathToString(toPath(path.replace(prefix, \"\")).slice(1))\n}\n\nexport function getColumnFromType(\n  column: ColumnConfig,\n  triggerEventHandler: (\n    eventType: string,\n    path?: string,\n    otherCalcContext?: Record<string, any>,\n    formatPath?: (path: string) => string,\n  ) => void,\n): ColumnConfig {\n  const commonValueGetter = (params: GridValueGetterParams) => {\n    const index = params.api.getAllRowIds().findIndex((id) => id === params.id)\n    if (index !== -1) {\n      const mappedValue = get(params.colDef, \"mappedValue\")\n      if (mappedValue === undefined) {\n        return params.value\n      }\n      if (isArray(mappedValue)) {\n        return isObject(mappedValue[index])\n          ? JSON.stringify(mappedValue[index])\n          : mappedValue[index]\n      } else {\n        return isObject(mappedValue) ? JSON.stringify(mappedValue) : mappedValue\n      }\n    } else {\n      return params.value\n    }\n  }\n\n  const commonDateValueGetter = (params: GridValueGetterParams) => {\n    const index = params.api.getAllRowIds().findIndex((id) => id === params.id)\n    let v = params.value\n    if (index !== -1) {\n      const mappedValue = get(params.colDef, \"mappedValue\")\n      if (mappedValue !== undefined) {\n        if (isArray(mappedValue)) {\n          v = isObject(mappedValue[index])\n            ? JSON.stringify(mappedValue[index])\n            : mappedValue[index]\n        } else {\n          v = isObject(mappedValue) ? JSON.stringify(mappedValue) : mappedValue\n        }\n      }\n    }\n    return dayjs(v).toDate()\n  }\n\n  switch (column.columnType) {\n    case \"button\":\n      return {\n        ...column,\n        type: \"string\",\n        renderCell: (params: GridRenderCellParams) => {\n          const disabled = isBoolean(get(params.colDef, \"disabled\"))\n            ? get(params.colDef, \"disabled\")\n            : false\n          const colorScheme = get(params.colDef, \"colorScheme\") ?? \"blue\"\n          const renderValue = isObject(params.value)\n            ? JSON.stringify(params.value)\n            : params.value\n          return (\n            <Button\n              fullWidth\n              disabled={disabled}\n              colorScheme={colorScheme}\n              onClick={() => {\n                setTimeout(() => {\n                  triggerEventHandler(\n                    \"click\",\n                    `columns[${params.api.getColumnIndex(\n                      params.field,\n                      false,\n                    )}].events`,\n                    {},\n                    (path) => {\n                      return formatDataGridColumnEvent(\n                        path,\n                        `columns[${params.api.getColumnIndex(\n                          params.field,\n                          false,\n                        )}].`,\n                      )\n                    },\n                  )\n                }, 1)\n              }}\n            >\n              {renderValue}\n            </Button>\n          )\n        },\n        valueGetter: commonValueGetter,\n      }\n    case \"buttongroup\":\n      return {\n        ...column,\n        type: \"string\",\n        renderCell: (params: GridRenderCellParams) => {\n          const buttonGroup: GroupButton[] =\n            get(params.colDef, \"buttonGroup\") ?? []\n          return (\n            <ButtonGroup css={cellContainer} spacing=\"8px\">\n              {buttonGroup.map((button, buttonIndex) => {\n                let label = button.mappedValue\n                const index = params.api\n                  .getAllRowIds()\n                  .findIndex((id) => id === params.id)\n                if (isArray(label) && index !== -1) {\n                  label = isObject(label[index])\n                    ? JSON.stringify(label[index])\n                    : label[index]\n                }\n                if (isObject(label)) {\n                  label = JSON.stringify(label)\n                }\n                const disabled = isBoolean(get(button, \"disabled\"))\n                  ? get(button, \"disabled\")\n                  : false\n                return (\n                  <Button\n                    key={button.id}\n                    colorScheme={button.colorScheme}\n                    disabled={disabled}\n                    onClick={() => {\n                      setTimeout(() => {\n                        triggerEventHandler(\n                          \"click\",\n                          `columns[${params.api.getColumnIndex(\n                            params.field,\n                            false,\n                          )}].buttonGroup[${buttonIndex}].events`,\n                          {},\n                          (path) => {\n                            return formatDataGridColumnEvent(\n                              path,\n                              `columns[${params.api.getColumnIndex(\n                                params.field,\n                                false,\n                              )}].buttonGroup[${buttonIndex}].`,\n                            )\n                          },\n                        )\n                      }, 1)\n                    }}\n                  >\n                    {label}\n                  </Button>\n                )\n              })}\n            </ButtonGroup>\n          )\n        },\n        valueGetter: commonValueGetter,\n      }\n    case \"rating\":\n      return {\n        ...column,\n        type: \"number\",\n        renderCell: (params: GridRenderCellParams) => {\n          const maxCount = isNumber(get(params.colDef, \"maxCount\"))\n            ? get(params.colDef, \"maxCount\")\n            : 5\n          const num = isNumber(params.value) ? params.value : 0\n          return <Rate count={maxCount} allowHalf readonly value={num} />\n        },\n        valueGetter: commonValueGetter,\n      }\n    case \"percent\":\n      return {\n        ...column,\n        type: \"number\",\n        renderCell: (params: GridRenderCellParams) => {\n          const decimalPlaces = get(params.colDef, \"decimalPlaces\")\n          const locale = isValidLocale(get(params.colDef, \"locale\") ?? \"en-US\")\n            ? get(params.colDef, \"locale\")\n            : \"en-US\"\n          const showThousandsSeparator = get(\n            params.colDef,\n            \"showThousandsSeparator\",\n          )\n          let finalResult = \"\"\n          if (isNumber(decimalPlaces)) {\n            finalResult = showThousandsSeparator\n              ? `${Number(params.value * 100).toLocaleString(locale, {\n                  minimumFractionDigits: decimalPlaces,\n                })}%`\n              : `${Number(params.value * 100).toFixed(decimalPlaces)}%`\n          } else {\n            finalResult = showThousandsSeparator\n              ? `${Number(params.value * 100).toLocaleString(locale)}%`\n              : `${params.value * 100}%`\n          }\n          return <span css={currencyContainerStyle}>{finalResult}</span>\n        },\n        valueGetter: commonValueGetter,\n      }\n    case \"html\":\n    case \"markdown\":\n      return {\n        ...column,\n        type: \"string\",\n        renderCell: (params: GridRenderCellParams) => {\n          return (\n            <ReactMarkdown\n              remarkPlugins={[remarkGfm]}\n              rehypePlugins={[\n                rehypeRaw,\n                [\n                  rehypeSanitize,\n                  {\n                    allowedTags: HTMLTags,\n                  },\n                ],\n              ]}\n              components={{\n                a: ({ href, children }) => (\n                  <Link href={href} target=\"_blank\" colorScheme=\"blue\">\n                    {children}\n                  </Link>\n                ),\n                p: ({ children }) => <Paragraph>{children}</Paragraph>,\n              }}\n            >\n              {isObject(params.value)\n                ? JSON.stringify(params.value)\n                : params.value}\n            </ReactMarkdown>\n          )\n        },\n        valueGetter: commonValueGetter,\n      }\n    case \"currency\":\n      return {\n        ...column,\n        type: \"number\",\n        renderCell: (params: GridRenderCellParams) => {\n          const decimalPlaces = get(params.colDef, \"decimalPlaces\")\n          const locale = isValidLocale(get(params.colDef, \"locale\") ?? \"en-US\")\n            ? get(params.colDef, \"locale\")\n            : \"en-US\"\n          const currencyCode = get(params.colDef, \"currencyCode\") ?? \"USD\"\n          const showThousandsSeparator = get(\n            params.colDef,\n            \"showThousandsSeparator\",\n          )\n          let finalResult = \"\"\n          if (isNumber(decimalPlaces)) {\n            finalResult = showThousandsSeparator\n              ? `${CurrencyCode[currencyCode] ?? \"USD\"}${Number(\n                  params.value,\n                ).toLocaleString(locale, {\n                  minimumFractionDigits: decimalPlaces,\n                })}`\n              : `${CurrencyCode[currencyCode ?? \"USD\"]}${Number(\n                  params.value,\n                ).toFixed(decimalPlaces)}`\n          } else {\n            finalResult = showThousandsSeparator\n              ? `${CurrencyCode[currencyCode ?? \"USD\"]}${Number(\n                  params.value,\n                ).toLocaleString(locale)}`\n              : `${CurrencyCode[currencyCode ?? \"USD\"]}${params.value}`\n          }\n          return <span css={currencyContainerStyle}>{finalResult}</span>\n        },\n        valueGetter: commonValueGetter,\n      }\n    case \"tag\":\n      return {\n        ...column,\n        type: \"string\",\n        renderCell: (params: GridRenderCellParams) => {\n          const tagColor = get(params.colDef, \"tagColor\")\n\n          let tagLabelArray: any[] = params.value\n\n          if (typeof params.value === \"string\") {\n            try {\n              tagLabelArray = JSON.parse(params.value)\n            } catch (e) {\n              tagLabelArray = [params.value]\n            }\n          }\n\n          if (!isArray(tagLabelArray)) {\n            tagLabelArray = [tagLabelArray]\n          }\n\n          const tagColorMap = isObject(tagColor) ? tagColor : {}\n          return (\n            <div css={cellContainer}>\n              {tagLabelArray.map((label, index) => {\n                const l = isObject(label) ? JSON.stringify(label) : label\n                const c = get(tagColorMap, l) ?? getPreColor(getHashCode(l))\n                return (\n                  <Tag key={`${l}:${index}`} colorScheme={c}>\n                    {l}\n                  </Tag>\n                )\n              })}\n            </div>\n          )\n        },\n        valueGetter: commonValueGetter,\n      }\n    case \"image\":\n      return {\n        ...column,\n        type: \"string\",\n        renderCell: (params: GridRenderCellParams) => {\n          const objectFit = get(params.colDef, \"objectFit\")\n          return <Image src={params.value} objectFit={objectFit} />\n        },\n        valueGetter: (params: GridValueGetterParams) => {\n          return get(params.colDef, \"mappedValue\") ?? params.value\n        },\n      }\n    case \"avatar\":\n      return {\n        ...column,\n        type: \"string\",\n        renderCell: (params: GridRenderCellParams) => {\n          const index = params.api\n            .getAllRowIds()\n            .findIndex((id) => id === params.id)\n\n          return (\n            <WrapperAvatar\n              avatarType={\n                getValueFromMappedValue(\n                  get(params.colDef, \"avatarType\", \"image\"),\n                  index,\n                  \"image\",\n                ) as AvatarType\n              }\n              imageSrc={getValueFromMappedValue(\n                get(params.colDef, \"imageSrc\"),\n                index,\n              )}\n              text={getValueFromMappedValue(get(params.colDef, \"text\"), index)}\n              icon={get(params.colDef, \"icon\")}\n              label={getValueFromMappedValue(\n                get(params.colDef, \"label\"),\n                index,\n              )}\n              labelCaption={getValueFromMappedValue(\n                get(params.colDef, \"labelCaption\"),\n                index,\n              )}\n              labelHidden={get(params.colDef, \"labelHidden\")}\n              colorScheme={get(params.colDef, \"colorScheme\")}\n            />\n          )\n        },\n      }\n    case \"number\":\n      return {\n        ...column,\n        type: \"number\",\n        renderCell: (params: GridRenderCellParams) => {\n          const decimalPlaces = get(params.colDef, \"decimalPlaces\")\n          const locale = isValidLocale(get(params.colDef, \"locale\") ?? \"en-US\")\n            ? get(params.colDef, \"locale\")\n            : \"en-US\"\n          const showThousandsSeparator = get(\n            params.colDef,\n            \"showThousandsSeparator\",\n          )\n          if (isNumber(decimalPlaces)) {\n            return showThousandsSeparator\n              ? Number(params.value).toLocaleString(locale, {\n                  minimumFractionDigits: decimalPlaces,\n                })\n              : Number(params.value).toFixed(decimalPlaces)\n          } else {\n            return showThousandsSeparator\n              ? Number(params.value).toLocaleString(locale)\n              : params.value\n          }\n        },\n        valueGetter: commonValueGetter,\n      }\n    case \"boolean\":\n      return {\n        ...column,\n        type: \"boolean\",\n        valueGetter: commonValueGetter,\n      }\n    case \"date\":\n      return {\n        ...column,\n        type: \"date\",\n        renderCell: (params: GridRenderCellParams) => {\n          return (\n            <SingleDatePicker\n              readonly\n              showTime={false}\n              colorScheme=\"techPurple\"\n              editable={false}\n              allowClear={false}\n              value={params.value}\n              format={get(params.colDef, \"format\")}\n            />\n          )\n        },\n        valueGetter: commonDateValueGetter,\n      }\n    case \"datetime\":\n      return {\n        ...column,\n        type: \"datetime\",\n        renderCell: (params: GridRenderCellParams) => {\n          return (\n            <SingleDatePicker\n              readonly\n              colorScheme=\"techPurple\"\n              editable={false}\n              showTime={true}\n              allowClear={false}\n              value={params.value}\n              format={get(params.colDef, \"format\")}\n            />\n          )\n        },\n        valueGetter: commonDateValueGetter,\n      }\n    case \"link\":\n      return {\n        ...column,\n        type: \"string\",\n        renderCell: (params: GridRenderCellParams) => {\n          return (\n            <Link href={params.value} target=\"_blank\">\n              {params.value}\n            </Link>\n          )\n        },\n        valueGetter: commonValueGetter,\n      }\n    case \"text\":\n    default:\n      return {\n        ...column,\n        type: \"string\",\n        valueGetter: commonValueGetter,\n        renderCell: undefined,\n      }\n  }\n}\n\nexport function getSafeColumn(column: ColumnConfig): ColumnConfig {\n  const newColum = { ...column }\n\n  if (!isString(newColum.headerName)) {\n    newColum.headerName = JSON.stringify(newColum.headerName)\n  }\n\n  if (!isNumber(newColum.width)) {\n    newColum.width = 150\n  }\n  if (!isString(newColum.description)) {\n    newColum.description = \"\"\n  }\n  if (!isBoolean(newColum.sortable)) {\n    newColum.sortable = true\n  }\n  if (!isBoolean(newColum.pinnable)) {\n    newColum.pinnable = true\n  }\n  if (!isBoolean(newColum.filterable)) {\n    newColum.filterable = true\n  }\n  if (!isBoolean(newColum.hideable)) {\n    newColum.hideable = true\n  }\n  if (!isBoolean(newColum.aggregable)) {\n    newColum.aggregable = true\n  }\n  if (!isBoolean(newColum.groupable)) {\n    newColum.groupable = true\n  }\n  if (!isBoolean(newColum.resizable)) {\n    newColum.resizable = true\n  }\n  if (!isBoolean(newColum.disableReorder)) {\n    newColum.disableReorder = false\n  }\n\n  newColum.align = newColum.headerAlign\n\n  return newColum\n}\n\nexport function getColumnTypeFromValue(value: unknown): ColumnType {\n  if (isNumber(value)) {\n    return \"number\"\n  } else if (isBoolean(value)) {\n    return \"boolean\"\n  } else if (isDate(value)) {\n    return \"date\"\n  } else if (isArray(value)) {\n    return \"tag\"\n  } else {\n    return \"text\"\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/constants.ts",
    "content": "export const UNIQUE_ID_NAME = \"$uniqueID\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/dataGrid.tsx",
    "content": "import { StyledEngineProvider, ThemeProvider, createTheme } from \"@mui/material\"\nimport {\n  DataGridPremium,\n  GridAggregationModel,\n  GridColDef,\n  GridColumnVisibilityModel,\n  GridEventListener,\n  GridFilterModel,\n  GridPaginationModel,\n  GridRowIdGetter,\n  GridRowSelectionModel,\n  GridSortModel,\n} from \"@mui/x-data-grid-premium\"\nimport { GridApiPremium } from \"@mui/x-data-grid-premium/models/gridApiPremium\"\nimport { get, isArray, isNumber, isPlainObject } from \"lodash-es\"\nimport {\n  FC,\n  MutableRefObject,\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n} from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { getColor } from \"@illa-design/react\"\nimport { dealRawData2ArrayData } from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/utils\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport {\n  getColumnFromType,\n  getColumnTypeFromValue,\n  getSafeColumn,\n} from \"@/widgetLibrary/DataGridWidget/columnDeal\"\nimport { Toolbar } from \"./Toolbar\"\nimport { UNIQUE_ID_NAME } from \"./constants\"\nimport { BaseDataGridProps } from \"./interface\"\nimport { getDataGridLocalization } from \"./utils\"\n\nexport const DataGridWidget: FC<BaseDataGridProps> = (props) => {\n  const {\n    loading,\n    triggerEventHandler,\n    dataSource,\n    dataSourceJS,\n    dataSourceMode,\n    sortKey,\n    sortOrder,\n    handleUpdateMultiExecutionResult,\n    displayName,\n    rowSelection,\n    rowSelectionMode,\n    pageSize,\n    page,\n    pageSizeOptions,\n    columnSetting,\n    densitySetting,\n    refreshSetting,\n    quickFilterSetting,\n    exportSetting,\n    exportAllSetting,\n    filterSetting,\n    enableServerSidePagination,\n    totalRowCount,\n    primaryKey,\n    filterModel,\n    selectedRowsPrimaryKeys,\n    excludeHiddenColumns,\n    columnVisibilityModel,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    columns,\n    enablePagination,\n  } = props\n\n  const rawData = dataSourceMode === \"dynamic\" ? dataSourceJS : dataSource\n  const serverSideOffset = (page ?? 0) * (pageSize ?? 10)\n\n  const arrayData: object[] = useMemo(\n    () =>\n      dealRawData2ArrayData(\n        rawData,\n        enableServerSidePagination,\n        serverSideOffset,\n      ),\n    [rawData, enableServerSidePagination, serverSideOffset],\n  )\n\n  const ref = useRef<GridApiPremium>(null) as MutableRefObject<GridApiPremium>\n\n  const dispatch = useDispatch()\n\n  const handleAggregationModelChange = (modal: GridAggregationModel) => {\n    if (!columns || !Array.isArray(columns)) return\n    let curColumns = [...(columns || [])]\n    Object.keys(modal).forEach((key) => {\n      const index = columns.findIndex((column) => {\n        return column?.field === key\n      })\n      if (!columns || index === -1) return\n      curColumns = [\n        ...curColumns.slice(0, index),\n        {\n          ...columns[index],\n          aggregationModel: modal[key],\n        },\n        ...curColumns.slice(index + 1),\n      ]\n    })\n\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          columns: curColumns,\n        },\n      },\n    ])\n  }\n\n  const isInnerDragging = useRef(false)\n\n  const toolbar = useCallback(\n    () => (\n      <Toolbar\n        columnSetting={columnSetting}\n        densitySetting={densitySetting}\n        exportSetting={exportSetting}\n        exportAllSetting={exportAllSetting}\n        filterSetting={filterSetting}\n        quickFilterSetting={quickFilterSetting}\n        refreshSetting={refreshSetting}\n        onRefresh={() => {\n          triggerEventHandler(\"onRefresh\")\n        }}\n      />\n    ),\n    [\n      columnSetting,\n      densitySetting,\n      exportAllSetting,\n      exportSetting,\n      filterSetting,\n      quickFilterSetting,\n      refreshSetting,\n      triggerEventHandler,\n    ],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      refresh: () => {\n        triggerEventHandler(\"onRefresh\")\n      },\n      setFilterModel: (model: unknown) => {\n        if (\n          isPlainObject(model) &&\n          (model as Record<string, unknown>).hasOwnProperty(\"items\") &&\n          Array.isArray((model as Record<string, unknown>).items)\n        ) {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                filterModel: model,\n              },\n            },\n          ])\n          triggerEventHandler(\"onFilterModelChange\")\n        }\n      },\n      setColumnVisibilityModel: (model: unknown) => {\n        if (isPlainObject(model)) {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                columnVisibilityModel: model,\n              },\n            },\n          ])\n          triggerEventHandler(\"onColumnVisibilityModelChange\")\n        }\n      },\n      setPage: (page: unknown) => {\n        if (isNumber(page)) {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                page,\n              },\n            },\n          ])\n          triggerEventHandler(\"onPaginationModelChange\")\n        }\n      },\n      setPageSize: (pageSize: unknown) => {\n        if (isNumber(pageSize)) {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                pageSize,\n              },\n            },\n          ])\n          triggerEventHandler(\"onPaginationModelChange\")\n        }\n      },\n      setRowSelection: (rows: unknown) => {\n        if (isArray(rows) && rows.every((row) => !isNaN(row))) {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                selectedRowsPrimaryKeys: rows,\n                selectedRows: rows.map((id) =>\n                  ref.current.getRowModels().get(id),\n                ),\n              },\n            },\n          ])\n          triggerEventHandler(\"onRowSelectionModelChange\")\n        }\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    triggerEventHandler,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  ])\n\n  const renderColumns = useMemo(() => {\n    if (!columns) return []\n    return columns.map((column) => {\n      const safeColumn = getSafeColumn(column)\n      return safeColumn.columnType === \"auto\"\n        ? getColumnFromType(\n            {\n              ...safeColumn,\n              columnType: getColumnTypeFromValue(\n                get(arrayData[0], safeColumn.field),\n              ),\n            },\n            triggerEventHandler,\n          )\n        : getColumnFromType(safeColumn, triggerEventHandler)\n    })\n  }, [arrayData, columns, triggerEventHandler])\n\n  const aggregationModel = useMemo(() => {\n    const curAggregationModel: GridAggregationModel = {}\n    columns?.forEach((column) => {\n      if (column?.aggregationModel) {\n        curAggregationModel[column.field] = column.aggregationModel\n      }\n    })\n    return curAggregationModel\n  }, [columns])\n\n  const innerFilterModel =\n    filterModel !== undefined\n      ? {\n          ...filterModel,\n          quickFilterExcludeHiddenColumns:\n            filterModel.quickFilterExcludeHiddenColumns ?? excludeHiddenColumns,\n        }\n      : undefined\n\n  const sortModel =\n    sortKey != undefined && sortOrder != undefined\n      ? [\n          {\n            field: sortKey,\n            sort: sortOrder === \"default\" ? null : sortOrder,\n          },\n        ]\n      : []\n\n  const innerRowSelection =\n    rowSelection &&\n    (rowSelectionMode === \"multiple\" || rowSelectionMode === \"single\")\n\n  /**\n   *\n   * Data Grid Pagination Attributes Start\n   *\n   */\n\n  const paginationModel =\n    pageSize !== undefined\n      ? {\n          pageSize: pageSize ?? 0,\n          page: page ?? 0,\n        }\n      : undefined\n  const paginationMode = enablePagination\n    ? enableServerSidePagination\n      ? \"server\"\n      : \"client\"\n    : undefined\n\n  /**\n   *\n   * Data Grid Pagination Attributes End\n   *\n   */\n\n  const getRowID: GridRowIdGetter<any> = (row) => {\n    if (\n      primaryKey === undefined ||\n      primaryKey === \"—\" ||\n      !(primaryKey in row)\n    ) {\n      return get(row, UNIQUE_ID_NAME)\n    } else {\n      return get(row, primaryKey)\n    }\n  }\n\n  /**\n   *\n   * DATA GRID Event Listeners Start\n   *\n   */\n\n  const onRowClick: GridEventListener<\"rowClick\"> = (params) => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          clickedRow: params.row,\n        },\n      },\n    ])\n    triggerEventHandler(\"onRowClick\")\n  }\n\n  const onFilterModelChange = (model: GridFilterModel) => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          filterModel: model,\n        },\n      },\n    ])\n    triggerEventHandler(\"onFilterModelChange\")\n  }\n\n  const onColumnVisibilityModelChange = (model: GridColumnVisibilityModel) => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          columnVisibilityModel: model,\n        },\n      },\n    ])\n    triggerEventHandler(\"onColumnVisibilityModelChange\")\n  }\n\n  const onRowSelectionModelChange = (model: GridRowSelectionModel) => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          selectedRowsPrimaryKeys: model,\n          selectedRows: model.map((id) => ref.current.getRowModels().get(id)),\n        },\n      },\n    ])\n    triggerEventHandler(\"onRowSelectionModelChange\")\n  }\n\n  const onPaginationModelChange = (model: GridPaginationModel) => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          page: model.page,\n          pageSize: model.pageSize,\n        },\n      },\n    ])\n    triggerEventHandler(\"onPaginationModelChange\")\n  }\n\n  const onSortModelChange = (model: GridSortModel) => {\n    if (model.length > 0) {\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            sortKey: model[0].field,\n            sortOrder: model[0].sort,\n          },\n        },\n      ])\n    } else {\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            sortKey: undefined,\n            sortOrder: undefined,\n          },\n        },\n      ])\n    }\n    triggerEventHandler(\"onSortModelChange\")\n  }\n\n  const onColumnHeaderEnter = () => {\n    dispatch(\n      configActions.setResizingNodeIDsReducer([\n        `${displayName}-column-header-resize`,\n      ]),\n    )\n    isInnerDragging.current = true\n  }\n\n  const onColumnHeaderLeave = () => {\n    dispatch(configActions.setResizingNodeIDsReducer([]))\n    isInnerDragging.current = false\n  }\n\n  /**\n   *\n   * DATA GRID Event Listeners End\n   *\n   */\n\n  return (\n    <StyledEngineProvider injectFirst>\n      <ThemeProvider\n        theme={createTheme({\n          palette: {\n            primary: { main: getColor(\"blue\", \"03\") },\n          },\n        })}\n      >\n        <DataGridPremium\n          localeText={getDataGridLocalization()}\n          key={displayName + \":\" + primaryKey}\n          apiRef={ref}\n          getRowId={getRowID}\n          aggregationModel={aggregationModel}\n          filterModel={innerFilterModel}\n          rowSelectionModel={\n            innerRowSelection ? selectedRowsPrimaryKeys : undefined\n          }\n          rowSelection={innerRowSelection}\n          columnVisibilityModel={{\n            [UNIQUE_ID_NAME]: false,\n            ...columnVisibilityModel,\n          }}\n          sortModel={sortModel}\n          pagination={enablePagination}\n          pageSizeOptions={isArray(pageSizeOptions) ? pageSizeOptions : []}\n          autoPageSize={pageSize === undefined}\n          disableMultipleRowSelection={\n            rowSelectionMode === \"single\" || !innerRowSelection\n          }\n          checkboxSelection={\n            innerRowSelection && rowSelectionMode === \"multiple\"\n          }\n          rows={arrayData}\n          columns={(renderColumns as GridColDef[]) ?? []}\n          rowCount={\n            enablePagination && enableServerSidePagination && totalRowCount\n              ? totalRowCount\n              : arrayData.length\n          }\n          keepNonExistentRowsSelected={enableServerSidePagination}\n          loading={loading}\n          slots={{\n            toolbar: toolbar,\n          }}\n          paginationModel={paginationModel}\n          paginationMode={paginationMode}\n          // Event listeners\n          onAggregationModelChange={handleAggregationModelChange}\n          onFilterModelChange={onFilterModelChange}\n          onColumnVisibilityModelChange={onColumnVisibilityModelChange}\n          onRowSelectionModelChange={onRowSelectionModelChange}\n          onRowClick={onRowClick}\n          onPaginationModelChange={onPaginationModelChange}\n          onSortModelChange={onSortModelChange}\n          onColumnHeaderEnter={onColumnHeaderEnter}\n          onColumnHeaderLeave={onColumnHeaderLeave}\n        />\n      </ThemeProvider>\n    </StyledEngineProvider>\n  )\n}\n\nDataGridWidget.displayName = \"DataGridWidget\"\nexport default DataGridWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"i18next\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const DATA_GRID_BUTTON_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.click\",\n      ),\n      value: \"click\",\n    },\n  ],\n  methods: [],\n}\n\nexport const DATA_GRID_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onSortModelChange\",\n      ),\n      value: \"onSortModelChange\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onPaginationModelChange\",\n      ),\n      value: \"onPaginationModelChange\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onRefresh\",\n      ),\n      value: \"onRefresh\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onFilterModelChange\",\n      ),\n      value: \"onFilterModelChange\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onRowSelectionModelChange\",\n      ),\n      value: \"onRowSelectionModelChange\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onColumnVisibilityModelChange\",\n      ),\n      value: \"onColumnVisibilityModelChange\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onRowClick\",\n      ),\n      value: \"onRowClick\",\n    },\n  ],\n  methods: [\n    \"setFilterModel\",\n    \"setColumnVisibilityModel\",\n    \"setPage\",\n    \"setPageSize\",\n    \"setRowSelection\",\n  ],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/index.ts",
    "content": "export { DATA_GRID_PANEL_CONFIG } from \"./panelConfig\"\nexport { DATA_GRID_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { DATA_GRID_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/interface.ts",
    "content": "import {\n  GridAggregationModel,\n  GridColumnVisibilityModel,\n  GridFilterModel,\n  GridInputRowSelectionModel,\n} from \"@mui/x-data-grid-premium\"\nimport i18n from \"i18next\"\nimport { ColumnConfig } from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface BaseDataGridProps extends BaseWidgetProps {\n  dataSource?: any\n  dataSourceJS?: any\n  dataSourceMode?: \"dynamic\" | \"static\"\n  loading?: boolean\n  emptyState?: string\n  sortKey?: string\n  sortOrder?: \"asc\" | \"desc\" | \"default\"\n  rowSelection?: boolean\n  rowSelectionMode?: \"single\" | \"multiple\"\n  pageSize?: number\n  page?: number\n  pageSizeOptions?: number[]\n  refreshSetting?: boolean\n  quickFilterSetting?: boolean\n  exportSetting?: boolean\n  exportAllSetting?: boolean\n  filterSetting?: boolean\n  columnSetting?: boolean\n  densitySetting?: boolean\n  enableServerSidePagination?: boolean\n  excludeHiddenColumns?: boolean\n  totalRowCount?: number\n  primaryKey?: string\n  filterModel?: GridFilterModel\n  columnVisibilityModel?: GridColumnVisibilityModel\n  selectedRowsPrimaryKeys?: GridInputRowSelectionModel\n  columns?: ColumnConfig[]\n  enablePagination?: boolean\n  aggregationModel?: GridAggregationModel\n}\n\nexport const ColumnTypeList = [\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.auto\"),\n    value: \"auto\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.text\"),\n    value: \"text\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.date\"),\n    value: \"date\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.tag\"),\n    value: \"tag\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.datetime\"),\n    value: \"datetime\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.number\"),\n    value: \"number\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.percent\"),\n    value: \"percent\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.currency\"),\n    value: \"currency\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.link\"),\n    value: \"link\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.button\"),\n    value: \"button\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.buttongroup\"),\n    value: \"buttongroup\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.boolean\"),\n    value: \"boolean\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.image\"),\n    value: \"image\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.avatar\"),\n    value: \"avatar\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.rating\"),\n    value: \"rating\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.markdown\"),\n    value: \"markdown\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.column_type.html\"),\n    value: \"html\",\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/panelConfig.tsx",
    "content": "import {\n  HorizontalCenterIcon,\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n} from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { ColumnType } from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter/interface\"\nimport {\n  PanelConfig,\n  PanelFieldConfig,\n} from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport {\n  DATA_GRID_BUTTON_EVENT_HANDLER_CONFIG,\n  DATA_GRID_EVENT_HANDLER_CONFIG,\n} from \"@/widgetLibrary/DataGridWidget/eventHandlerConfig\"\nimport { ColumnTypeList } from \"@/widgetLibrary/DataGridWidget/interface\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"dataGrid\"\n\nexport const getAggregationSetter = (type: ColumnType): PanelFieldConfig => {\n  let aggregationOptions = [\n    {\n      label: i18n.t(\"editor.inspect.setter_option.aggregation.size\"),\n      value: \"size\",\n    },\n  ]\n\n  switch (type) {\n    case \"number\":\n      aggregationOptions = [\n        {\n          label: i18n.t(\"editor.inspect.setter_option.aggregation.sum\"),\n          value: \"sum\",\n        },\n        {\n          label: i18n.t(\"editor.inspect.setter_option.aggregation.avg\"),\n          value: \"avg\",\n        },\n        {\n          label: i18n.t(\"editor.inspect.setter_option.aggregation.min\"),\n          value: \"min\",\n        },\n        {\n          label: i18n.t(\"editor.inspect.setter_option.aggregation.max\"),\n          value: \"max\",\n        },\n        ...aggregationOptions,\n      ]\n      break\n    case \"date\":\n    case \"datetime\":\n      aggregationOptions = [\n        {\n          label: i18n.t(\"editor.inspect.setter_option.aggregation.min\"),\n          value: \"min\",\n        },\n        {\n          label: i18n.t(\"editor.inspect.setter_option.aggregation.max\"),\n          value: \"max\",\n        },\n        ...aggregationOptions,\n      ]\n      break\n  }\n  aggregationOptions.unshift({\n    label: \"—\",\n    value: \"\",\n  })\n  return {\n    id: `${baseWidgetName}-column-aggregationModel`,\n    labelName: i18n.t(\"editor.inspect.setter_label.aggregation\"),\n    attrName: \"aggregationModel\",\n    bindAttrName: [\"aggregable\"],\n    shown: (value) => value,\n    setterType: \"BASE_SELECT_SETTER\",\n    options: aggregationOptions,\n  }\n}\n\nexport function getColumnsTypeSetter(\n  type: ColumnType,\n  defaultValueType: ColumnType,\n): PanelFieldConfig[] {\n  return [\n    ...DATA_GRID_COMMON_COLUMN_SETTER_CONFIG.slice(0, 4),\n    ...getColumnsTypeSubSetter(type),\n    getAggregationSetter(type !== \"auto\" ? type : defaultValueType),\n    ...DATA_GRID_COMMON_COLUMN_SETTER_CONFIG.slice(\n      4,\n      DATA_GRID_COMMON_COLUMN_SETTER_CONFIG.length,\n    ),\n  ]\n}\n\nexport function getColumnsTypeSubSetter(type: ColumnType): PanelFieldConfig[] {\n  switch (type) {\n    case \"auto\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n      ]\n    case \"text\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n      ]\n    case \"date\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-column-format`,\n          labelName: i18n.t(\"editor.inspect.setter_label.format\"),\n          attrName: \"format\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          defaultValue: \"YYYY-MM-DD\",\n          expectedType: VALIDATION_TYPES.STRING,\n        },\n      ]\n    case \"tag\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-column-tagColor`,\n          labelName: i18n.t(\"editor.inspect.setter_label.table.tag_color\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tips.table.tag_color\"),\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          attrName: \"tagColor\",\n        },\n      ]\n    case \"datetime\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-column-format`,\n          labelName: i18n.t(\"editor.inspect.setter_label.format\"),\n          attrName: \"format\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          defaultValue: \"YYYY-MM-DD HH:mm:ss\",\n          expectedType: VALIDATION_TYPES.STRING,\n        },\n      ]\n    case \"number\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-column-decimalPlaces`,\n          labelName: i18n.t(\"editor.inspect.setter_label.decimal_places\"),\n          attrName: \"decimalPlaces\",\n          placeholder: \"{{ 0 }}\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          expectedType: VALIDATION_TYPES.NUMBER,\n        },\n        {\n          id: `${baseWidgetName}-column-showThousandsSeparator`,\n          labelName: i18n.t(\n            \"editor.inspect.setter_label.table.show_thousands_separ\",\n          ),\n          labelDesc: i18n.t(\n            \"editor.inspect.setter_tips.table.show_thousands_separ\",\n          ),\n          attrName: \"showThousandsSeparator\",\n          setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n          expectedType: VALIDATION_TYPES.BOOLEAN,\n          openDynamic: true,\n          useCustomLayout: true,\n        },\n        {\n          id: `${baseWidgetName}-column-locale`,\n          labelName: i18n.t(\"editor.inspect.setter_label.table.locale\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tips.table.locale\"),\n          attrName: \"locale\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          expectedType: VALIDATION_TYPES.STRING,\n          openDynamic: true,\n        },\n      ]\n    case \"percent\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-column-decimalPlaces`,\n          labelName: i18n.t(\"editor.inspect.setter_label.decimal_places\"),\n          attrName: \"decimalPlaces\",\n          placeholder: \"{{ 0 }}\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          expectedType: VALIDATION_TYPES.NUMBER,\n        },\n        {\n          id: `${baseWidgetName}-column-showThousandsSeparator`,\n          labelName: i18n.t(\n            \"editor.inspect.setter_label.table.show_thousands_separ\",\n          ),\n          labelDesc: i18n.t(\n            \"editor.inspect.setter_tips.table.show_thousands_separ\",\n          ),\n          attrName: \"showThousandsSeparator\",\n          setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n          expectedType: VALIDATION_TYPES.BOOLEAN,\n          openDynamic: true,\n          useCustomLayout: true,\n        },\n        {\n          id: `${baseWidgetName}-column-locale`,\n          labelName: i18n.t(\"editor.inspect.setter_label.table.locale\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tips.table.locale\"),\n          attrName: \"locale\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          expectedType: VALIDATION_TYPES.STRING,\n          bindAttrName: [\"showThousandsSeparator\"],\n          shown: (value) => value,\n          openDynamic: true,\n        },\n      ]\n    case \"html\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n      ]\n    case \"link\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n      ]\n    case \"button\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          ...generatorEventHandlerConfig(\n            baseWidgetName,\n            DATA_GRID_BUTTON_EVENT_HANDLER_CONFIG.events,\n          ),\n        },\n        {\n          id: `${baseWidgetName}-column-disabled`,\n          labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n          placeholder: \"{{false}}\",\n          attrName: \"disabled\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          expectedType: VALIDATION_TYPES.BOOLEAN,\n        },\n        {\n          id: `${baseWidgetName}-column-colorScheme`,\n          labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n          setterType: \"COLOR_PICKER_SETTER\",\n          labelSize: \"medium\",\n          attrName: \"colorScheme\",\n          defaultValue: \"blue\",\n        },\n      ]\n    case \"buttongroup\":\n      return [\n        {\n          id: `${baseWidgetName}-column-buttonGroup`,\n          attrName: \"buttonGroup\",\n          setterType: \"DATA_GRID_COLUMN_BUTTON_GROUP_SETTER\",\n          openDynamic: true,\n          useCustomLayout: true,\n          childrenSetter: [\n            {\n              id: `${baseWidgetName}-column-mappedValue`,\n              labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n              labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n              attrName: \"mappedValue\",\n              setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n              placeholder: \"{{currentRow}}\",\n            },\n            {\n              ...generatorEventHandlerConfig(\n                baseWidgetName,\n                DATA_GRID_BUTTON_EVENT_HANDLER_CONFIG.events,\n              ),\n            },\n            {\n              id: `${baseWidgetName}-column-disabled`,\n              labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n              labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n              placeholder: \"{{false}}\",\n              attrName: \"disabled\",\n              setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n              expectedType: VALIDATION_TYPES.BOOLEAN,\n            },\n            {\n              id: `${baseWidgetName}-column-colorScheme`,\n              labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n              setterType: \"COLOR_PICKER_SETTER\",\n              labelSize: \"medium\",\n              attrName: \"colorScheme\",\n              defaultValue: \"blue\",\n            },\n          ],\n        },\n      ]\n    case \"boolean\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n      ]\n    case \"image\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-column-scaleType`,\n          labelName: i18n.t(\"editor.inspect.setter_label.scale_type\"),\n          attrName: \"objectFit\",\n          defaultValue: \"scale-down\",\n          setterType: \"SEARCH_SELECT_SETTER\",\n          options: [\"container\", \"cover\", \"fill\", \"none\", \"scale-down\"],\n        },\n      ]\n    case \"avatar\":\n      return [\n        {\n          id: `${baseWidgetName}-label-avatar-type`,\n          labelName: i18n.t(\"editor.inspect.setter_label.avatar_type\"),\n          attrName: \"avatarType\",\n          setterType: \"DATA_GRID_MAPPED_SELECT_SETTER\",\n          defaultValue: \"image\",\n          options: [\n            {\n              label: i18n.t(\n                \"editor.inspect.setter_label.avatar_type_options.image\",\n              ),\n              value: \"image\",\n            },\n            {\n              label: i18n.t(\n                \"editor.inspect.setter_label.avatar_type_options.icon\",\n              ),\n              value: \"icon\",\n            },\n            {\n              label: i18n.t(\n                \"editor.inspect.setter_label.avatar_type_options.text\",\n              ),\n              value: \"text\",\n            },\n          ],\n        },\n        {\n          id: `${baseWidgetName}-label-image`,\n          labelName: i18n.t(\"editor.inspect.setter_label.imageSrc\"),\n          attrName: \"imageSrc\",\n          isSetterSingleRow: true,\n          bindAttrName: [\"avatarType\"],\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-label-text`,\n          labelName: i18n.t(\"editor.inspect.setter_label.text\"),\n          attrName: \"text\",\n          bindAttrName: [\"avatarType\"],\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-label-icon`,\n          labelName: i18n.t(\"editor.inspect.setter_label.icon\"),\n          attrName: \"icon\",\n          bindAttrName: [\"avatarType\"],\n          expectedType: VALIDATION_TYPES.STRING,\n          setterType: \"ICON_SETTER\",\n        },\n        {\n          id: `${baseWidgetName}-label-label`,\n          labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.label\"),\n          attrName: \"label\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-label-caption`,\n          labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.caption\"),\n          attrName: \"labelCaption\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-label-hidden`,\n          labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.hide_label\"),\n          attrName: \"labelHidden\",\n          setterType: \"DYNAMIC_SWITCH_SETTER\",\n          useCustomLayout: true,\n        },\n        {\n          id: `${baseWidgetName}-colors-color`,\n          labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n          attrName: \"colorScheme\",\n          setterType: \"CUSTOM_BG_SELECT_SETTER\",\n        },\n      ]\n    case \"rating\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-column-maxCount`,\n          labelName: i18n.t(\"editor.inspect.setter_label.max_count\"),\n          attrName: \"maxCount\",\n          placeholder: \"{{ 5 }}\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          expectedType: VALIDATION_TYPES.NUMBER,\n        },\n      ]\n    case \"markdown\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n      ]\n    case \"currency\":\n      return [\n        {\n          id: `${baseWidgetName}-column-mappedValue`,\n          labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n          attrName: \"mappedValue\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          placeholder: \"{{currentRow}}\",\n        },\n        {\n          id: `${baseWidgetName}-column-currencyCode`,\n          labelName: i18n.t(\"editor.inspect.setter_label.table.currency_code\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tips.table.currency_code\"),\n          placeholder: i18n.t(\n            \"editor.inspect.setter_placeholder.table.currency_code\",\n          ),\n          attrName: \"currencyCode\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          expectedType: VALIDATION_TYPES.STRING,\n        },\n        {\n          id: `${baseWidgetName}-column-decimalPlaces`,\n          labelName: i18n.t(\"editor.inspect.setter_label.decimal_places\"),\n          attrName: \"decimalPlaces\",\n          placeholder: \"{{ 0 }}\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          expectedType: VALIDATION_TYPES.NUMBER,\n        },\n        {\n          id: `${baseWidgetName}-column-showThousandsSeparator`,\n          labelName: i18n.t(\n            \"editor.inspect.setter_label.table.show_thousands_separ\",\n          ),\n          labelDesc: i18n.t(\n            \"editor.inspect.setter_tips.table.show_thousands_separ\",\n          ),\n          attrName: \"showThousandsSeparator\",\n          setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n          expectedType: VALIDATION_TYPES.BOOLEAN,\n          openDynamic: true,\n          useCustomLayout: true,\n        },\n        {\n          id: `${baseWidgetName}-column-locale`,\n          labelName: i18n.t(\"editor.inspect.setter_label.table.locale\"),\n          labelDesc: i18n.t(\"editor.inspect.setter_tips.table.locale\"),\n          attrName: \"locale\",\n          setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n          expectedType: VALIDATION_TYPES.STRING,\n          bindAttrName: [\"showThousandsSeparator\"],\n          shown: (value) => value,\n          openDynamic: true,\n        },\n      ]\n    default:\n      return []\n  }\n}\n\nexport const DATA_GRID_COMMON_COLUMN_SETTER_CONFIG: PanelFieldConfig[] = [\n  {\n    id: `${baseWidgetName}-column-headerName`,\n    labelName: i18n.t(\"editor.inspect.setter_label.column_title\"),\n    attrName: \"headerName\",\n    setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    id: `${baseWidgetName}-column-columnType`,\n    labelName: i18n.t(\"editor.inspect.setter_label.column_type\"),\n    attrName: \"columnType\",\n    setterType: \"DATA_GRID_TYPE_SELECT_SETTER\",\n    options: ColumnTypeList,\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    id: `${baseWidgetName}-column-description`,\n    labelName: i18n.t(\"editor.inspect.setter_label.column_description\"),\n    labelDesc: i18n.t(\"editor.inspect.setter_tips.column_description\"),\n    attrName: \"description\",\n    setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n    expectedType: VALIDATION_TYPES.STRING,\n  },\n  {\n    id: `${baseWidgetName}-column-width`,\n    labelName: i18n.t(\"editor.inspect.setter_label.width\"),\n    labelDesc: i18n.t(\"editor.inspect.setter_tips.width\"),\n    attrName: \"width\",\n    setterType: \"DATA_GRID_MAPPED_INPUT_SETTER\",\n    expectedType: VALIDATION_TYPES.NUMBER,\n  },\n  {\n    id: `${baseWidgetName}-column-sortable`,\n    labelName: i18n.t(\"editor.inspect.setter_label.enable_users_to_sort\"),\n    labelDesc: i18n.t(\"editor.inspect.setter_tips.enable_users_to_sort\"),\n    attrName: \"sortable\",\n    setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n    expectedType: VALIDATION_TYPES.BOOLEAN,\n    defaultValue: true,\n    openDynamic: true,\n    useCustomLayout: true,\n  },\n  {\n    id: `${baseWidgetName}-column-pinnable`,\n    labelName: i18n.t(\"editor.inspect.setter_label.enable_users_to_pin\"),\n    labelDesc: i18n.t(\"editor.inspect.setter_tips.enable_users_to_pin\"),\n    attrName: \"pinnable\",\n    setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n    expectedType: VALIDATION_TYPES.BOOLEAN,\n    defaultValue: true,\n    openDynamic: true,\n    useCustomLayout: true,\n  },\n  {\n    id: `${baseWidgetName}-column-filterable`,\n    labelName: i18n.t(\"editor.inspect.setter_label.enable_users_to_filter\"),\n    labelDesc: i18n.t(\"editor.inspect.setter_tips.enable_users_to_filter\"),\n    attrName: \"filterable\",\n    setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n    expectedType: VALIDATION_TYPES.BOOLEAN,\n    defaultValue: true,\n    openDynamic: true,\n    useCustomLayout: true,\n  },\n  {\n    id: `${baseWidgetName}-column-hideable`,\n    labelName: i18n.t(\"editor.inspect.setter_label.enable_users_to_hide\"),\n    labelDesc: i18n.t(\"editor.inspect.setter_tips.enable_users_to_hide\"),\n    attrName: \"hideable\",\n    setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n    expectedType: VALIDATION_TYPES.BOOLEAN,\n    defaultValue: true,\n    openDynamic: true,\n    useCustomLayout: true,\n  },\n  {\n    id: `${baseWidgetName}-column-aggregable`,\n    labelName: i18n.t(\"editor.inspect.setter_label.enable_users_to_aggregate\"),\n    labelDesc: i18n.t(\"editor.inspect.setter_tips.enable_users_to_aggregate\"),\n    attrName: \"aggregable\",\n    setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n    expectedType: VALIDATION_TYPES.BOOLEAN,\n    defaultValue: true,\n    openDynamic: true,\n    useCustomLayout: true,\n  },\n  {\n    id: `${baseWidgetName}-column-groupable`,\n    labelName: i18n.t(\n      \"editor.inspect.setter_label.enable_users_to_set_group_by\",\n    ),\n    labelDesc: i18n.t(\n      \"editor.inspect.setter_tips.enable_users_to_set_group_by\",\n    ),\n    attrName: \"groupable\",\n    setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n    expectedType: VALIDATION_TYPES.BOOLEAN,\n    defaultValue: true,\n    openDynamic: true,\n    useCustomLayout: true,\n  },\n  {\n    id: `${baseWidgetName}-column-resizable`,\n    labelName: i18n.t(\"editor.inspect.setter_label.enable_users_to_resize\"),\n    labelDesc: i18n.t(\"editor.inspect.setter_tips.enable_users_to_resize\"),\n    attrName: \"resizable\",\n    setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n    expectedType: VALIDATION_TYPES.BOOLEAN,\n    defaultValue: true,\n    openDynamic: true,\n    useCustomLayout: true,\n  },\n  {\n    id: `${baseWidgetName}-column-disableReorder`,\n    labelName: i18n.t(\"editor.inspect.setter_label.disable_users_to_reorder\"),\n    labelDesc: i18n.t(\"editor.inspect.setter_tips.disable_users_to_reorder\"),\n    attrName: \"disableReorder\",\n    setterType: \"DATA_GRID_COLUMN_SWITCH_SETTER\",\n    expectedType: VALIDATION_TYPES.BOOLEAN,\n    openDynamic: true,\n    useCustomLayout: true,\n  },\n  {\n    id: `${baseWidgetName}-column-headerAlign`,\n    setterType: \"RADIO_GROUP_SETTER\",\n    labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n    attrName: \"headerAlign\",\n    defaultValue: \"left\",\n    options: [\n      {\n        label: <HorizontalStartIcon />,\n        value: \"left\",\n      },\n      {\n        label: <HorizontalCenterIcon />,\n        value: \"center\",\n      },\n      {\n        label: <HorizontalEndIcon />,\n        value: \"right\",\n      },\n    ],\n  },\n]\nexport const DATA_GRID_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-data`,\n    groupName: i18n.t(\"editor.inspect.setter_group.data\"),\n    children: [\n      {\n        id: `${baseWidgetName}-data-source`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        useCustomLayout: true,\n        attrName: \"dataSource\",\n        setterType: \"DATA_SOURCE_SELECT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-loading`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n        attrName: \"loading\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-primaryKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.primary_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.primary_key\"),\n        attrName: \"primaryKey\",\n        setterType: \"DATA_GRID_COLUMNS_SELECT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        openDynamic: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-column`,\n    groupName: i18n.t(\"editor.inspect.setter_group.column\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-columns`,\n        useCustomLayout: true,\n        attrName: \"columns\",\n        setterType: \"DATA_GRID_COLUMN_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-sort`,\n    groupName: i18n.t(\"editor.inspect.setter_group.sort\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-sortKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_sort_key\"),\n        attrName: \"sortKey\",\n        setterType: \"DATA_GRID_COLUMNS_SELECT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        openDynamic: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-sortOrder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_sort_order\"),\n        attrName: \"sortOrder\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        isSetterSingleRow: true,\n        bindAttrName: [\"sortKey\"],\n        shown: (value) => value !== \"default\",\n        options: [\n          { label: i18n.t(\"widget.table.ascend\"), value: \"asc\" },\n          { label: i18n.t(\"widget.table.descend\"), value: \"desc\" },\n          { label: i18n.t(\"widget.table.default\"), value: \"default\" },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-rowSelection`,\n    groupName: i18n.t(\"editor.inspect.setter_group.row_selection\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-rowSelection`,\n        labelName: i18n.t(\"editor.inspect.setter_label.allow_users_select\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.allow_users_select\"),\n        attrName: \"rowSelection\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-rowSelectionMode`,\n        labelName: i18n.t(\"editor.inspect.setter_label.selection_mode\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.selection_mode\"),\n        attrName: \"rowSelectionMode\",\n        setterType: \"DYNAMIC_SELECT_SETTER\",\n        defaultValue: \"single\",\n        isSetterSingleRow: true,\n        useCustomLayout: true,\n        openDynamic: true,\n        bindAttrName: [\"rowSelection\"],\n        shown: (value) => value,\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_options.single_row_selection\"),\n            value: \"single\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_options.multiple_row_selection\",\n            ),\n            value: \"multiple\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-PAGINATION`,\n    groupName: i18n.t(\"editor.inspect.setter_group.pagination\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-enable_pagination`,\n        labelName: i18n.t(\"editor.inspect.setter_label.enable_pagination\"),\n        attrName: \"enablePagination\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        useCustomLayout: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-enableServerSidePagination`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.table.enable_server_side_p\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.table.enable_server_side_p\",\n        ),\n        bindAttrName: [\"enablePagination\"],\n        shown: (value) => value,\n        attrName: \"enableServerSidePagination\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-totalRowCount`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.total_row_count\"),\n        attrName: \"totalRowCount\",\n        setterType: \"INPUT_SETTER\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\"enablePagination\", \"enableServerSidePagination\"],\n        shown: (enablePagination, enableServerSidePagination) =>\n          enablePagination && enableServerSidePagination,\n      },\n      {\n        id: `${baseWidgetName}-basic-pageSize`,\n        labelName: i18n.t(\"editor.inspect.setter_label.pageSize\"),\n        placeholder: \"{{30}}\",\n        attrName: \"pageSize\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"enablePagination\"],\n        shown: (enablePagination) => enablePagination,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-basic-page`,\n        labelName: i18n.t(\"editor.inspect.setter_label.page\"),\n        placeholder: \"{{0}}\",\n        attrName: \"page\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"enablePagination\"],\n        shown: (enablePagination) => enablePagination,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-basic-pageSizeOptions`,\n        labelName: i18n.t(\"editor.inspect.setter_label.page_size_options\"),\n        placeholder: \"{{[5, 10, 25]}}\",\n        attrName: \"pageSizeOptions\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"enablePagination\"],\n        shown: (enablePagination) => enablePagination,\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.ARRAY,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-toolbar`,\n    groupName: i18n.t(\"editor.inspect.setter_group.toolbar\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-densitySetting`,\n        labelName: i18n.t(\"editor.inspect.setter_content.density_setting\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.density_setting\"),\n        attrName: \"densitySetting\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-columnSetting`,\n        labelName: i18n.t(\"editor.inspect.setter_content.column_setting\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.column_setting\"),\n        attrName: \"columnSetting\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-refreshSetting`,\n        labelName: i18n.t(\"editor.inspect.setter_content.refresh_setting\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.refresh_setting\"),\n        attrName: \"refreshSetting\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-exportSetting`,\n        labelName: i18n.t(\"editor.inspect.setter_label.export_setting\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.export_setting\"),\n        attrName: \"exportSetting\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-exportAllSetting`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.table.export_all_data_setting\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.table.export_all_data_setting\",\n        ),\n        attrName: \"exportAllSetting\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-filterSetting`,\n        labelName: i18n.t(\"editor.inspect.setter_label.filter_setting\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.filter_setting\"),\n        attrName: \"filterSetting\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-quickFilterSetting`,\n        labelName: i18n.t(\"editor.inspect.setter_label.quick_filter_setting\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.quick_filter_setting\"),\n        attrName: \"quickFilterSetting\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-excludeHiddenColumns`,\n        labelName: i18n.t(\"editor.inspect.setter_label.exclude_hidden_columns\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.exclude_hidden_columns\",\n        ),\n        attrName: \"excludeHiddenColumns\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"quickFilterSetting\"],\n        shown: (value) => value,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          DATA_GRID_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const cellContainer = css`\n  display: flex;\n  flex-direction: row;\n  overflow-x: auto;\n  gap: 8px;\n  ::-webkit-scrollbar {\n    display: none;\n  }\n  scrollbar-width: none;\n`\n\nexport const currencyContainerStyle = css`\n  text-overflow: ellipsis;\n  overflow: hidden;\n  white-space: nowrap;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/utils.ts",
    "content": "import {\n  csCZ,\n  daDK,\n  deDE,\n  elGR,\n  enUS,\n  esES,\n  fiFI,\n  frFR,\n  itIT,\n  jaJP,\n  koKR,\n  nlNL,\n  plPL,\n  ptPT,\n  roRO,\n  ruRU,\n  svSE,\n  ukUA,\n  zhCN,\n} from \"@mui/x-data-grid-premium\"\n\nexport function getDataGridLocalization() {\n  const currentLng = window.localStorage.getItem(\"i18nextLng\") ?? \"en-US\"\n  const localizationMap = {\n    \"en-US\": enUS,\n    \"zh-CN\": zhCN,\n    \"ja-JP\": jaJP,\n    \"ko-KR\": koKR,\n    \"cs-CZ\": csCZ,\n    \"da-DK\": daDK,\n    \"de-DE\": deDE,\n    \"el-GR\": elGR,\n    \"es-ES\": esES,\n    \"fi-FI\": fiFI,\n    \"fr-FR\": frFR,\n    \"it-IT\": itIT,\n    \"nl-NL\": nlNL,\n    \"pl-PL\": plPL,\n    \"pt-PT\": ptPT,\n    \"ro-RO\": roRO,\n    \"ru-RU\": ruRU,\n    \"sv-SE\": svSE,\n    \"uk-UA\": ukUA,\n  }\n  return (localizationMap[currentLng as keyof typeof localizationMap] || enUS)\n    .components.MuiDataGrid.defaultProps.localeText\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DataGridWidget/widgetConfig.tsx",
    "content": "import TableWidgetIcon from \"@/assets/widgetCover/table.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { generateCalcColumnConfig } from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/ColumnSetter\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\nimport { UNIQUE_ID_NAME } from \"./constants\"\n\nconst originData = [\n  {\n    id: 1,\n    name: \"Elvera Sleite\",\n    email: \"hboshers50@narod.ru\",\n    type: \"product manager\",\n    age: 30,\n    paid: true,\n  },\n  {\n    id: 2,\n    name: \"Richardo Durrett\",\n    email: \"mhamsleyt@ask.com\",\n    type: \"UX/UI\",\n    age: 18,\n    paid: false,\n  },\n  {\n    id: 3,\n    name: \"Ellwood Halsted\",\n    email: \"amccardle5h@godaddy.com\",\n    type: \"designer\",\n    age: 14,\n    paid: true,\n  },\n  {\n    id: 4,\n    name: \"Tyson Anersen\",\n    email: \"hstrettell3c@list-manage.com\",\n    type: \"UX/UI\",\n    age: 32,\n    paid: true,\n  },\n  {\n    id: 5,\n    name: \"Tobey Mordy\",\n    email: \"gfraschetti54@independent.co.uk\",\n    type: \"designer\",\n    age: 22,\n    paid: true,\n  },\n  {\n    id: 6,\n    name: \"Leena Stovine\",\n    email: \"prawlingson4w@phoca.cz\",\n    type: \"designer\",\n    age: 17,\n    paid: false,\n  },\n  {\n    id: 7,\n    name: \"Erinn Olenchenko\",\n    email: \"cmeddows1q@aboutads.info\",\n    type: \"UX/UI\",\n    age: 17,\n    paid: false,\n  },\n  {\n    id: 8,\n    name: \"Jilly Aldiss\",\n    email: \"radamik2b@hubpages.com\",\n    type: \"marketing\",\n    age: 22,\n    paid: false,\n  },\n  {\n    id: 9,\n    name: \"Erinn Reasce\",\n    email: \"aduckeru@scribd.com\",\n    type: \"designer\",\n    age: 24,\n    paid: false,\n  },\n  {\n    id: 10,\n    name: \"Sargent Guy\",\n    email: \"jmaccafferky57@archive.org\",\n    type: \"marketing\",\n    age: 19,\n    paid: false,\n  },\n  {\n    id: 11,\n    name: \"Gay Craiker\",\n    email: \"ddurrett42@yahoo.com\",\n    type: [\"UX/UI\", \"designer\"],\n    age: 27,\n    paid: false,\n  },\n  {\n    id: 12,\n    name: \"Piper Sorey\",\n    email: \"dscanterburyx@topsy.com\",\n    type: \"designer\",\n    age: 25,\n    paid: true,\n  },\n  {\n    id: 13,\n    name: \"Renato Benjefield\",\n    email: \"dmayfield27@seattletimes.com\",\n    type: \"marketing\",\n    age: 27,\n    paid: true,\n  },\n  {\n    id: 14,\n    name: \"Adelind Loache\",\n    email: \"vhessel2w@sciencedirect.com\",\n    type: [\"designer\", \"UX/UI\"],\n    age: 14,\n    paid: true,\n  },\n  {\n    id: 15,\n    name: \"Pepi Corssen\",\n    email: \"bfifield2v@amazonaws.com\",\n    type: [\"product manager\", \"designer\"],\n    age: 27,\n    paid: false,\n  },\n]\n\nexport const DATA_GRID_WIDGET_CONFIG: WidgetConfig = {\n  version: 0,\n  type: \"DATA_GRID_WIDGET\",\n  displayName: \"dataGrid\",\n  widgetName: i18n.t(\"widget.data_grid.name\"),\n  icon: <TableWidgetIcon />,\n  keywords: [\"dataGrid\", \"数据表格\", \"table\", \"表格\"],\n  sessionType: \"DATA\",\n  resizeDirection: RESIZE_DIRECTION.ALL,\n  w: 18,\n  h: 50,\n  defaults: {\n    dataSourceMode: \"dynamic\",\n    excludeHiddenColumns: true,\n    dataSourceJS: `{{${JSON.stringify(originData, null, \"  \")}}}`,\n    dataSource: [],\n    enablePagination: false,\n    sortOrder: \"default\",\n    columns: Object.keys(originData[0])\n      .map((key) => {\n        return generateCalcColumnConfig(key, true, false)\n      })\n      .concat(generateCalcColumnConfig(UNIQUE_ID_NAME, true, false)),\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateRangeWidget/dateRange.tsx",
    "content": "import dayjs, { Dayjs } from \"dayjs\"\nimport { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { RangeDatePicker } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { handleValidateCheck } from \"../PublicSector/InvalidMessage/utils\"\nimport { DateWidgetProps, WrappedDateRangeProps } from \"./interface\"\n\nexport const WrappedDateRange: FC<WrappedDateRangeProps> = (props) => {\n  const {\n    startValue,\n    endValue,\n    dateFormat,\n    startPlaceholder,\n    endPlaceholder,\n    showClear,\n    minDate,\n    disabled,\n    maxDate,\n    colorScheme,\n    handleOnChange,\n    getValidateMessage,\n    handleUpdateMultiExecutionResult,\n    displayName,\n    readOnly,\n  } = props\n\n  const changeValue = (value?: string[]) => {\n    new Promise((resolve) => {\n      const startMessage = getValidateMessage(value?.[0])\n      const endMessage = getValidateMessage(value?.[1])\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            startValue: value?.[0] || \"\",\n            endValue: value?.[1] || \"\",\n            validateMessage: startMessage || endMessage,\n          },\n        },\n      ])\n      resolve(true)\n    }).then(() => {\n      handleOnChange?.()\n    })\n  }\n\n  const _placeholder = [startPlaceholder ?? \"\", endPlaceholder ?? \"\"]\n\n  const dateRangeValue = useMemo(() => {\n    return !startValue && !endValue ? undefined : [startValue, endValue]\n  }, [startValue, endValue])\n\n  const checkRange = useCallback(\n    (current?: Dayjs) => {\n      const beforeMinDate = minDate\n        ? !!current?.isBefore(dayjs(minDate))\n        : false\n      const afterMaxDate = maxDate ? !!current?.isAfter(dayjs(maxDate)) : false\n      return beforeMinDate || afterMaxDate\n    },\n    [minDate, maxDate],\n  )\n\n  return (\n    <RangeDatePicker\n      w=\"100%\"\n      editable={!readOnly}\n      colorScheme={colorScheme}\n      format={dateFormat}\n      value={dateRangeValue}\n      disabled={disabled}\n      placeholder={_placeholder}\n      allowClear={showClear}\n      disabledDate={checkRange}\n      onClear={() => {\n        changeValue([\"\", \"\"])\n      }}\n      onChange={changeValue}\n    />\n  )\n}\n\nWrappedDateRange.displayName = \"WrappedDateRange\"\n\nexport const DateRangeWidget: FC<DateWidgetProps> = (props) => {\n  const {\n    startValue,\n    endValue,\n    endPlaceholder,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    updateComponentHeight,\n    validateMessage,\n    customRule,\n    hideValidationMessage,\n    triggerEventHandler,\n  } = props\n\n  const getValidateMessage = useCallback(\n    (value?: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required],\n  )\n\n  const handleValidate = useCallback(\n    (value?: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [getValidateMessage, handleUpdateDsl],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setStartValue: (startValue: string) => {\n        handleUpdateDsl({ startValue })\n      },\n      setEndValue: (endValue: string) => {\n        handleUpdateDsl({ endValue })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ startValue: undefined, endValue: undefined })\n      },\n      validate: () => {\n        const startValueChecked = handleValidate(startValue)\n        if (startValueChecked) {\n          return startValueChecked\n        }\n        const endValueChecked = handleValidate(endValue)\n        if (endPlaceholder) {\n          return endValueChecked\n        }\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    endPlaceholder,\n    endValue,\n    handleUpdateDsl,\n    handleValidate,\n    startValue,\n    updateComponentRuntimeProps,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedDateRange\n            {...props}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nDateRangeWidget.displayName = \"DateRangeWidget\"\nexport default DateRangeWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateRangeWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const DATE_RANGE_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\n    \"setStartValue\",\n    \"setEndValue\",\n    \"clearValue\",\n    \"validate\",\n    \"clearValidation\",\n  ],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateRangeWidget/index.tsx",
    "content": "export { DATE_RANGE_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { DATE_RANGE_PANEL_CONFIG } from \"./panelConfig\"\nexport { DATE_RANGE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateRangeWidget/interface.tsx",
    "content": "import { ReactNode } from \"react\"\nimport { RangeDatePickerProps } from \"@illa-design/react\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedDateRangeProps\n  extends Pick<RangeDatePickerProps, \"disabled\" | \"colorScheme\"> {\n  readOnly?: RangeDatePickerProps[\"editable\"]\n  startValue: string\n  endValue: string\n  startPlaceholder?: string\n  endPlaceholder?: string\n  dateFormat?: string\n  showClear?: RangeDatePickerProps[\"allowClear\"]\n  beforeIcon?: ReactNode // TODO: not support yet\n  afterIcon?: ReactNode // TODO: not support yet\n  beforeText?: string // TODO: not support yet\n  afterText?: string // TODO: not support yet\n  minDate?: string\n  maxDate?: string\n  handleUpdateDsl: (value: any) => void\n  displayName: string\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n}\n\nexport interface DateWidgetProps\n  extends Omit<WrappedDateRangeProps, \"handleOnChange\">,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps {\n  customRule?: string\n  hideValidationMessage?: boolean\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateRangeWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { DATE_RANGE_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/DateRangeWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"date-range\"\nexport const DATE_RANGE_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-start-date`,\n        labelName: i18n.t(\"editor.inspect.setter_label.start_date\"),\n        attrName: \"startValue\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-end-date`,\n        labelName: i18n.t(\"editor.inspect.setter_label.end_data\"),\n        attrName: \"endValue\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-format`,\n        labelName: i18n.t(\"editor.inspect.setter_label.format\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.date_format\"),\n        attrName: \"dateFormat\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-start-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.start_placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        isSetterSingleRow: true,\n        attrName: \"startPlaceholder\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-end-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.end_placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        isSetterSingleRow: true,\n        attrName: \"endPlaceholder\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-max-date`,\n        labelName: i18n.t(\"editor.inspect.setter_label.max_date\"),\n        attrName: \"maxDate\",\n        placeholder: \"2032-01-01\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-min-date`,\n        labelName: i18n.t(\"editor.inspect.setter_label.min_date\"),\n        attrName: \"minDate\",\n        placeholder: \"2022-01-01\",\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          DATE_RANGE_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readonly\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        attrName: \"showClear\",\n        useCustomLayout: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        isSetterSingleRow: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-styles-colorScheme`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateRangeWidget/widgetConfig.tsx",
    "content": "import DateRangeWidgetIcon from \"@/assets/widgetCover/dateRange.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { TEMPLATE_DISPLAYNAME_KEY } from \"@/utils/generators/generateComponentNode\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const DATE_RANGE_WIDGET_CONFIG: WidgetConfig = {\n  type: \"DATE_RANGE_WIDGET\",\n  displayName: \"dateRange\",\n  widgetName: i18n.t(\"widget.date_range.name\"),\n  icon: <DateRangeWidgetIcon />,\n  keywords: [\"Date Range\", \"日期范围选择器\"],\n  sessionType: \"CALENDAR\",\n  w: 8,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    dateFormat: \"YYYY-MM-DD\",\n    startPlaceholder: \"Start date\",\n    endPlaceholder: \"End date\",\n    colorScheme: \"blue\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    hidden: false,\n    formDataKey: \"radioButton\",\n    value: [\n      `{{${TEMPLATE_DISPLAYNAME_KEY}.startValue}}`,\n      `{{${TEMPLATE_DISPLAYNAME_KEY}.endValue}}`,\n    ],\n    $dynamicAttrPaths: [\"value[0]\", \"value[1]\"],\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateTimeWidget/dateTime.tsx",
    "content": "import dayjs, { Dayjs } from \"dayjs\"\nimport { FC, useCallback, useEffect } from \"react\"\nimport { SingleDatePicker } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { DateTimeWidgetProps, WrappedDateTimeProps } from \"./interface\"\n\nexport const WrappedDateTime: FC<WrappedDateTimeProps> = (props) => {\n  const {\n    value,\n    format,\n    placeholder,\n    showClear,\n    minDate,\n    disabled,\n    maxDate,\n    minuteStep,\n    colorScheme,\n    handleOnChange,\n    getValidateMessage,\n    handleUpdateMultiExecutionResult,\n    displayName,\n    readOnly,\n  } = props\n\n  const changeValue = (value?: unknown) => {\n    new Promise((resolve) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value: value || \"\",\n            validateMessage: message,\n          },\n        },\n      ])\n      resolve(true)\n    }).then(() => {\n      handleOnChange?.()\n    })\n  }\n\n  const checkRange = useCallback(\n    (current?: Dayjs) => {\n      const beforeMinDate = minDate\n        ? !!current?.isBefore(dayjs(minDate))\n        : false\n      const afterMaxDate = maxDate ? !!current?.isAfter(dayjs(maxDate)) : false\n      return beforeMinDate || afterMaxDate\n    },\n    [minDate, maxDate],\n  )\n\n  return (\n    <SingleDatePicker\n      w=\"100%\"\n      showTime={{ step: { minute: minuteStep }, format }}\n      colorScheme={colorScheme}\n      format={format}\n      value={value}\n      disabled={disabled}\n      placeholder={placeholder}\n      allowClear={showClear}\n      disabledDate={checkRange}\n      onClear={() => {\n        changeValue(\"\")\n      }}\n      onChange={changeValue}\n      editable={!readOnly}\n    />\n  )\n}\n\nWrappedDateTime.displayName = \"WrappedDateTime\"\n\nexport const DateTimeWidget: FC<DateTimeWidgetProps> = (props) => {\n  const {\n    value,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    pattern,\n    regex,\n    customRule,\n    hideValidationMessage,\n    updateComponentHeight,\n    validateMessage,\n    triggerEventHandler,\n  } = props\n\n  const getValidateMessage = useCallback(\n    (value?: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n          pattern,\n          regex,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, pattern, regex, required],\n  )\n\n  const handleValidate = useCallback(\n    (value?: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [getValidateMessage, handleUpdateDsl],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: string) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: \"\" })\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    handleValidate,\n    updateComponentRuntimeProps,\n    value,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedDateTime\n            {...props}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\n\nDateTimeWidget.displayName = \"DateTimeWidget\"\nexport default DateTimeWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateTimeWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const DATE_TIME_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateTimeWidget/index.tsx",
    "content": "export { DATE_TIME_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { DATE_TIME_PANEL_CONFIG } from \"./panelConfig\"\nexport { DATE_TIME_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateTimeWidget/interface.tsx",
    "content": "import { SingleDatePickerProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedDateTimeProps\n  extends Pick<\n    SingleDatePickerProps,\n    \"placeholder\" | \"disabled\" | \"colorScheme\"\n  > {\n  readOnly?: SingleDatePickerProps[\"editable\"]\n  value?: string\n  format?: string\n  minuteStep?: number\n  tooltipText?: string\n  loading?: boolean\n  showClear?: SingleDatePickerProps[\"allowClear\"]\n  minDate?: string\n  maxDate?: string\n  displayName: string\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n}\n\nexport interface DateTimeWidgetProps\n  extends Omit<WrappedDateTimeProps, \"handleOnChange\">,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateTimeWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { DATE_TIME_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/DateTimeWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"date-time\"\nexport const DATE_TIME_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-DefaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-date-format`,\n        labelName: i18n.t(\"editor.inspect.setter_label.format\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.date_format\"),\n        attrName: \"format\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"placeholder\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-max-date`,\n        labelName: i18n.t(\"editor.inspect.setter_label.max_date\"),\n        attrName: \"maxDate\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"2032-01-01\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-min-date`,\n        labelName: i18n.t(\"editor.inspect.setter_label.min_date\"),\n        attrName: \"minDate\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"2022-01-01\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-minute-step`,\n        labelName: i18n.t(\"editor.inspect.setter_label.step_size\"),\n        attrName: \"minuteStep\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\", \"labelPosition\"],\n        shown: (hidden, position) => !hidden && position !== \"top\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          DATE_TIME_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      // {\n      //   id: `${baseWidgetName}-interaction-loading`,\n      //   labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n      //   labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n      //   attrName: \"loading\",\n      //   setterType: \"INPUT_SETTER\",\n      //   expectedType: VALIDATION_TYPES.BOOLEAN,\n      // },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readonly\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        attrName: \"showClear\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        isSetterSingleRow: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-bg`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateTimeWidget/widgetConfig.tsx",
    "content": "import DateTimeWidgetIcon from \"@/assets/widgetCover/dateTime.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const DATE_TIME_WIDGET_CONFIG: WidgetConfig = {\n  type: \"DATE_TIME_WIDGET\",\n  displayName: \"dateTime\",\n  widgetName: i18n.t(\"widget.date_time.name\"),\n  keywords: [\"Date Time\", \"日期时间选择器\"],\n  icon: <DateTimeWidgetIcon />,\n  sessionType: \"CALENDAR\",\n  w: 10,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    placeholder: i18n.t(\"widget.date_time.placeholder\"),\n    format: \"YYYY-MM-DD HH:mm:ss\",\n    minuteStep: \"{{1}}\",\n    colorScheme: \"blue\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    hidden: false,\n    formDataKey: \"radioButton\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateWidget/date.tsx",
    "content": "import dayjs, { Dayjs } from \"dayjs\"\nimport { FC, useCallback, useEffect } from \"react\"\nimport { SingleDatePicker } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport {\n  getValidateVFromString,\n  handleValidateCheck,\n} from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { DateWidgetProps, WrappedDateProps } from \"./interface\"\n\nexport const WrappedDate: FC<WrappedDateProps> = (props) => {\n  const {\n    value,\n    dateFormat,\n    placeholder,\n    showClear,\n    minDate,\n    disabled,\n    maxDate,\n    colorScheme,\n    getValidateMessage,\n    handleUpdateMultiExecutionResult,\n    handleOnChange,\n    displayName,\n    readOnly,\n  } = props\n\n  const changeValue = (value?: unknown) => {\n    new Promise((resolve) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value: value || \"\",\n            validateMessage: message,\n          },\n        },\n      ])\n      resolve(true)\n    }).then(() => {\n      handleOnChange?.()\n    })\n  }\n\n  const checkRange = useCallback(\n    (current?: Dayjs) => {\n      const beforeMinDate = minDate\n        ? !!current?.isBefore(dayjs(minDate))\n        : false\n      const afterMaxDate = maxDate ? !!current?.isAfter(dayjs(maxDate)) : false\n      return beforeMinDate || afterMaxDate\n    },\n    [minDate, maxDate],\n  )\n\n  return (\n    <SingleDatePicker\n      w=\"100%\"\n      editable={!readOnly}\n      colorScheme={colorScheme}\n      format={dateFormat}\n      value={value}\n      disabled={disabled}\n      placeholder={placeholder}\n      allowClear={showClear}\n      disabledDate={checkRange}\n      onClear={() => {\n        changeValue(\"\")\n      }}\n      onChange={changeValue}\n    />\n  )\n}\n\nWrappedDate.displayName = \"WrappedDate\"\n\nexport const DateWidget: FC<DateWidgetProps> = (props) => {\n  const {\n    value,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    pattern,\n    regex,\n    customRule,\n    hideValidationMessage,\n    updateComponentHeight,\n    validateMessage,\n    triggerEventHandler,\n  } = props\n\n  const getValidateMessage = useCallback(\n    (value?: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value: getValidateVFromString(value),\n          required,\n          customRule,\n          pattern,\n          regex,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, pattern, regex, required],\n  )\n\n  const handleValidate = useCallback(\n    (value?: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [getValidateMessage, handleUpdateDsl],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: string) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: \"\" })\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    handleUpdateDsl,\n    deleteComponentRuntimeProps,\n    handleValidate,\n    value,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedDate\n            {...props}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nDateWidget.displayName = \"DateWidget\"\n\nexport default DateWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const DATE_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateWidget/index.tsx",
    "content": "export { DATE_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { DATE_PANEL_CONFIG } from \"./panelConfig\"\nexport { DATE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateWidget/interface.tsx",
    "content": "import { SingleDatePickerProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedDateProps\n  extends Pick<\n    SingleDatePickerProps,\n    \"value\" | \"disabled\" | \"placeholder\" | \"colorScheme\"\n  > {\n  readOnly?: SingleDatePickerProps[\"editable\"]\n  dateFormat?: string\n  loading?: boolean\n  showClear?: SingleDatePickerProps[\"allowClear\"]\n  minDate?: string\n  maxDate?: string\n  handleUpdateDsl: (value: any) => void\n  displayName: string\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n}\n\nexport interface DateWidgetProps\n  extends Omit<WrappedDateProps, \"handleOnChange\">,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { DATE_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/DateWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"date\"\nexport const DATE_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-DefaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-Format`,\n        labelName: i18n.t(\"editor.inspect.setter_label.format\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.date_format\"),\n        attrName: \"dateFormat\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"placeholder\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-max-date`,\n        labelName: i18n.t(\"editor.inspect.setter_label.max_date\"),\n        attrName: \"maxDate\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"2032-01-01\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-min-date`,\n        labelName: i18n.t(\"editor.inspect.setter_label.min_date\"),\n        attrName: \"minDate\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"2022-01-01\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\", \"labelPosition\"],\n        shown: (hidden, position) => !hidden && position !== \"top\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          DATE_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      // {\n      //   id: `${baseWidgetName}-interaction-loading`,\n      //   labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n      //   labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n      //   attrName: \"loading\",\n      //   setterType: \"INPUT_SETTER\",\n      //   expectedType: VALIDATION_TYPES.BOOLEAN,\n      // },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readOnly\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        attrName: \"showClear\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        isSetterSingleRow: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-colorScheme`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DateWidget/widgetConfig.tsx",
    "content": "import dayjs from \"dayjs\"\nimport DateWidgetIcon from \"@/assets/widgetCover/date.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const DATE_WIDGET_CONFIG: WidgetConfig = {\n  type: \"DATE_WIDGET\",\n  displayName: \"date\",\n  widgetName: i18n.t(\"widget.date.name\"),\n  icon: <DateWidgetIcon />,\n  keywords: [\"Date\", \"日期选择器\"],\n  sessionType: \"CALENDAR\",\n  w: 6,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    value: dayjs().format(\"YYYY-MM-DD\"),\n    dateFormat: \"YYYY-MM-DD\",\n    colorScheme: \"blue\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    hidden: false,\n    formDataKey: \"radioButton\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DividerWidget/divider.tsx",
    "content": "import { FC, useEffect, useMemo } from \"react\"\nimport { Divider } from \"@illa-design/react\"\nimport { DividerWidgetProps, WrappedDividerProps } from \"./interface\"\nimport { dividerContainerStyle } from \"./style\"\n\nexport const WrappedDivider: FC<WrappedDividerProps> = (props) => {\n  const { text, fs, textAlign } = props\n\n  const _textSize = useMemo(() => {\n    return !isNaN(Number(fs)) ? fs + \"px\" : fs?.toString()\n  }, [fs])\n\n  return <Divider w=\"100%\" textAlign={textAlign} text={text} fs={_textSize} />\n}\n\nWrappedDivider.displayName = \"WrappedDivider\"\n\nexport const DividerWidget: FC<DividerWidgetProps> = (props) => {\n  const {\n    text,\n    fs,\n    textAlign,\n    displayName,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n  } = props\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: string) => {\n        handleUpdateDsl({ text: value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ text: \"\" })\n      },\n    })\n\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    text,\n    fs,\n    textAlign,\n    displayName,\n    updateComponentRuntimeProps,\n    handleUpdateDsl,\n    deleteComponentRuntimeProps,\n  ])\n\n  return (\n    <div css={dividerContainerStyle}>\n      <WrappedDivider {...props} />\n    </div>\n  )\n}\n\nDividerWidget.displayName = \"DividerWidget\"\nexport default DividerWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DividerWidget/eventHandlerConfig.ts",
    "content": "import { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const DIVIDER_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [],\n  methods: [\"setValue\", \"clearValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DividerWidget/index.tsx",
    "content": "export { DIVIDER_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { DIVIDER_PANEL_CONFIG } from \"./panelConfig\"\nexport { DIVIDER_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DividerWidget/interface.tsx",
    "content": "import { DividerTextAlign } from \"@illa-design/react\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedDividerProps {\n  text: string\n  fs: string\n  textAlign: DividerTextAlign\n}\n\nexport interface DividerWidgetProps\n  extends WrappedDividerProps,\n    BaseWidgetProps {}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DividerWidget/panelConfig.tsx",
    "content": "import {\n  HorizontalCenterIcon,\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n} from \"@illa-design/react\"\nimport TextSizeIcon from \"@/assets/text-size-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst baseWidgetName = \"divider\"\nexport const DIVIDER_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-text`,\n        labelName: i18n.t(\"editor.inspect.setter_label.text\"),\n        attrName: \"text\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-text-align`,\n        labelName: i18n.t(\"editor.inspect.setter_label.text_align\"),\n        attrName: \"textAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"start\",\n          },\n          {\n            label: <HorizontalCenterIcon />,\n            value: \"center\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"end\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        attrName: \"styles\",\n        labelName: i18n.t(\"editor.inspect.setter_label.styles\"),\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-text-size`,\n            labelName: i18n.t(\"editor.inspect.setter_label.text_size\"),\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            attrName: \"fs\",\n            icon: <TextSizeIcon />,\n            defaultValue: \"14px\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DividerWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const dividerContainerStyle = css`\n  display: flex;\n  flex-direction: row;\n  height: 100%;\n  width: 100%;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DividerWidget/widgetConfig.tsx",
    "content": "import DividerWidgetIcon from \"@/assets/widgetCover/divider.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const DIVIDER_WIDGET_CONFIG: WidgetConfig = {\n  type: \"DIVIDER_WIDGET\",\n  displayName: \"divider\",\n  widgetName: i18n.t(\"widget.divider_progress.name\"),\n  icon: <DividerWidgetIcon />,\n  keywords: [\"Divider\", \"分割线\"],\n  sessionType: \"PRESENTATION\",\n  w: 8,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    colorScheme: \"grayBlue\",\n    fs: \"14px\",\n    hidden: false,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DrivePickerWidget/constants.ts",
    "content": "export const PAGESIZE = 10\nexport const DEFAULT_EXPIRED_TIME = 300\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DrivePickerWidget/drivePicker.tsx",
    "content": "import { EXPIRATION_TYPE } from \"@illa-public/public-types\"\nimport { useUpgradeModal } from \"@illa-public/upgrade-modal\"\nimport { isSubscribeForUseDrive } from \"@illa-public/upgrade-modal/utils\"\nimport { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { FC, useCallback } from \"react\"\nimport { forwardRef, useContext } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Button } from \"@illa-design/react\"\nimport FilesModal from \"@/components/DriveFileSelect\"\nimport { DriveFileSelectContext } from \"@/components/DriveFileSelect/context\"\nimport { FileToPanel } from \"@/components/DriveFileSelect/interface\"\nimport { getIsILLAProductMode } from \"@/redux/config/configSelector\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { DEFAULT_EXPIRED_TIME } from \"./constants\"\nimport {\n  DrivePickerWidgetProps,\n  SelectItemValue,\n  WrappedDrivePickerProps,\n} from \"./interface\"\nimport { DrivePickerProvider } from \"./provider\"\nimport { wrapperStyle } from \"./style\"\n\nexport const WrappedDrivePicker = forwardRef<\n  HTMLDivElement,\n  WrappedDrivePickerProps\n>((props, ref) => {\n  const { text, variant, colorScheme, disabled } = props\n  const { setModalVisible } = useContext(DriveFileSelectContext)\n  const teamInfo = useSelector(getCurrentTeamInfo)!\n  const isProductionMode = useSelector(getIsILLAProductMode)\n  const upgradeModal = useUpgradeModal()\n\n  const openLicenseDrawer = useCallback(() => {\n    upgradeModal({\n      modalType: \"upgrade\",\n      from: \"drive_picker\",\n    })\n  }, [upgradeModal])\n\n  const handleClick = () => {\n    if (isProductionMode || isSubscribeForUseDrive(teamInfo)) {\n      setModalVisible(true)\n    } else {\n      openLicenseDrawer()\n    }\n  }\n\n  return (\n    <div ref={ref} css={wrapperStyle}>\n      <Button\n        fullWidth\n        fullHeight\n        colorScheme={colorScheme}\n        disabled={disabled}\n        variant={variant}\n        onClick={handleClick}\n      >\n        {text}\n      </Button>\n      <FilesModal />\n    </div>\n  )\n})\nWrappedDrivePicker.displayName = \"WrappedDrivePicker\"\n\nexport const DrivePickerWidget: FC<DrivePickerWidgetProps> = (props) => {\n  const {\n    ILLADriveFolder,\n    displayName,\n    tooltipText,\n    expirationType = EXPIRATION_TYPE.PERSISTENT,\n    expiredTime = DEFAULT_EXPIRED_TIME,\n    useHotlink = false,\n    minSize,\n    maxSize,\n    minFileNum,\n    maxFileNum,\n    sizeType = \"kb\",\n    allowAnonymousUse,\n    colorScheme = \"blue\",\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n  } = props\n\n  const handleUpdateMultiExecution = useCallback(\n    (value: SelectItemValue[], files: Partial<FileToPanel>[]) => {\n      return new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value,\n              files,\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler && triggerEventHandler(\"change\")\n      })\n    },\n    [displayName, handleUpdateMultiExecutionResult, triggerEventHandler],\n  )\n\n  return (\n    <DrivePickerProvider\n      path={ILLADriveFolder}\n      handleUpdateResult={handleUpdateMultiExecution}\n      expirationType={expirationType}\n      expiredTime={expiredTime}\n      useHotlink={useHotlink}\n      minFileNum={minFileNum}\n      maxFileNum={maxFileNum}\n      minSize={minSize}\n      maxSize={maxSize}\n      sizeType={sizeType}\n      allowAnonymousUse={allowAnonymousUse}\n      colorScheme={colorScheme}\n    >\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <WrappedDrivePicker {...props} />\n      </TooltipWrapper>\n    </DrivePickerProvider>\n  )\n}\n\nDrivePickerWidget.displayName = \"DrivePickerWidget\"\nexport default DrivePickerWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DrivePickerWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const DRIVE_PICKER_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DrivePickerWidget/index.ts",
    "content": "export { DRIVE_PICKER_PANEL_CONFIG } from \"./panelConfig\"\nexport { DRIVE_PICKER_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { DRIVE_PICKER_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DrivePickerWidget/interface.ts",
    "content": "import { EXPIRATION_TYPE } from \"@illa-public/public-types\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedDrivePickerProps extends BaseWidgetProps {\n  allowAnonymousUse?: boolean\n  ILLADriveFolder?: string\n  generateSignedURL?: boolean\n  expirationType?: EXPIRATION_TYPE\n  expiredTime?: number\n  useHotlink?: boolean\n  text?: string\n  selectionType?: \"single\" | \"multiple\"\n  allowFileTypes?: string[]\n  showFileList?: boolean\n  minSize?: number\n  maxSize?: number\n  sizeType?: \"kb\" | \"mb\"\n  minFileNum?: number\n  maxFileNum?: number\n  disabled?: boolean\n  variant?: \"text\" | \"light\" | \"fill\" | \"outline\" | \"dashed\"\n  colorScheme?: string\n}\n\nexport interface DrivePickerWidgetProps\n  extends WrappedDrivePickerProps,\n    Pick<TooltipWrapperProps, \"tooltipText\"> {}\n\nexport interface SelectItemValue {\n  fileURL: string\n  tinyURL: string\n  fileID: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DrivePickerWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { DRIVE_PICKER_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/DrivePickerWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"drivePicker\"\nexport const DRIVE_PICKER_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-text`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.button_text\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.button_text\",\n        ),\n        attrName: \"text\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-allowAnonymousUse`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.allow_public_use\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.allow_public_use\",\n        ),\n        attrName: \"allowAnonymousUse\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        setterType: \"DRIVE_WITH_STATUS_SWITCH_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-ILLADriveFolder`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.illa_drive_folder\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.illa_drive_folder\",\n        ),\n        attrName: \"ILLADriveFolder\",\n        isSetterSingleRow: true,\n        placeholder: \"/root/folder/folder\",\n        bindAttrName: [\"allowAnonymousUse\"],\n        shown: (value) => !value,\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-expiredTimeSelect`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.expired_time\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.expired_time\",\n        ),\n        attrName: \"expirationType\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.drive_builder.expired_time.never\",\n            ),\n            value: \"persistent\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.drive_builder.expired_time.customer\",\n            ),\n            value: \"custom\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-expiredTime`,\n        labelName: i18n.t(\"editor.inspect.setter_label.drive_builder.time\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.drive_builder.time\"),\n        attrName: \"expiredTime\",\n        bindAttrName: [\"expirationType\"],\n        isSetterSingleRow: true,\n        shown: (value) => value === \"custom\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-Hotlink`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.turn_on_hotlink\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.turn_on_hotlink\",\n        ),\n        attrName: \"useHotlink\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-validation-fileSize`,\n        labelName: i18n.t(\"editor.inspect.setter_label.min_max_size\"),\n        placeholder: i18n.t(\"editor.inspect.setter_placeholder.min_max_size\"),\n        setterType: \"FILE_MIN_MAX_SETTER\",\n        attrName: \"\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-minFileNum`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.min_file_num\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.min_file_num\",\n        ),\n        attrName: \"minFileNum\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-label-maxFileNum`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.max_file_num\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.max_file_num\",\n        ),\n        attrName: \"maxFileNum\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          DRIVE_PICKER_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        placeholder: \"{{false}}\",\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-variant`,\n        setterType: \"RADIO_GROUP_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.variant\"),\n        attrName: \"variant\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_default_value.fill\"),\n            value: \"fill\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_default_value.outline\"),\n            value: \"outline\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-bg`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DrivePickerWidget/provider.tsx",
    "content": "import {\n  HTTP_REQUEST_PUBLIC_BASE_URL,\n  PUBLIC_DRIVE_REQUEST_PREFIX,\n} from \"@illa-public/illa-net/constant\"\nimport {\n  DRIVE_FILE_TYPE,\n  EXPIRATION_TYPE,\n  IILLAFileInfo,\n} from \"@illa-public/public-types\"\nimport { FC, ReactNode, useCallback, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport {\n  ROOT_PATH,\n  removeSuffixPath,\n  usePath,\n} from \"@/components/DriveFileSelect\"\nimport { DriveFileSelectContext } from \"@/components/DriveFileSelect/context\"\nimport { FileToPanel } from \"@/components/DriveFileSelect/interface\"\nimport { getAppInfo } from \"@/redux/currentApp/appInfo/appInfoSelector\"\nimport {\n  fetchAnonymousFileList,\n  fetchBatchAnonymousGenerateTinyUrl,\n  fetchBatchGenerateTinyUrl,\n  fetchFileList,\n} from \"@/services/drive\"\nimport { PAGESIZE } from \"./constants\"\nimport { SelectItemValue } from \"./interface\"\n\ninterface Props {\n  path?: string\n  allowAnonymousUse?: boolean\n  children?: ReactNode\n  expirationType: EXPIRATION_TYPE\n  expiredTime: number\n  useHotlink: boolean\n  sizeType: \"kb\" | \"mb\"\n  minSize?: number\n  maxSize?: number\n  minFileNum?: number\n  maxFileNum?: number\n  colorScheme: string\n  handleUpdateResult: (\n    value: SelectItemValue[],\n    files: Partial<FileToPanel>[],\n  ) => Promise<void>\n}\n\nexport const DrivePickerProvider: FC<Props> = (props) => {\n  const {\n    path = ROOT_PATH,\n    children,\n    allowAnonymousUse,\n    expirationType,\n    expiredTime,\n    useHotlink,\n    minSize,\n    maxSize,\n    minFileNum,\n    maxFileNum,\n    colorScheme,\n    sizeType,\n    handleUpdateResult,\n  } = props\n\n  const { currentPath, updatePath, totalPath } = usePath(\n    removeSuffixPath(path),\n    allowAnonymousUse,\n  )\n  const [fileList, setFileList] = useState<IILLAFileInfo[]>([])\n  const [modalVisible, setModalVisible] = useState(false)\n  const appInfo = useSelector(getAppInfo)\n\n  const handleCloseModal = useCallback(() => {\n    setModalVisible(false)\n    updatePath(path || ROOT_PATH)\n    setFileList([])\n  }, [path, updatePath])\n\n  const submitSelect = useCallback(\n    (items: FileToPanel[]) => {\n      return new Promise(async (resolve, reject) => {\n        if (appInfo.config.public && !appInfo.deployed && !allowAnonymousUse) {\n          return reject()\n        }\n        const selectIds = items.map((item) => item.id)\n        const requestParams = {\n          ids: selectIds,\n          expirationType,\n          expiry:\n            expirationType === EXPIRATION_TYPE.CUSTOM\n              ? expiredTime + \"s\"\n              : undefined,\n          hotlinkProtection: useHotlink,\n        }\n        try {\n          const res = allowAnonymousUse\n            ? await fetchBatchAnonymousGenerateTinyUrl(\n                appInfo.appId,\n                requestParams,\n              )\n            : await fetchBatchGenerateTinyUrl(requestParams)\n          const value: SelectItemValue[] = []\n          Array.isArray(res.data) &&\n            res.data.forEach((item) => {\n              let prefix =\n                HTTP_REQUEST_PUBLIC_BASE_URL + PUBLIC_DRIVE_REQUEST_PREFIX + \"/\"\n              value.push({\n                fileURL: prefix + item.tinyURL,\n                tinyURL: item.tinyURL,\n                fileID: item.fileID,\n              })\n            })\n          const files = items.map(({ lastModifiedAt, name, size, type }) => ({\n            lastModifiedAt,\n            name,\n            size,\n            type,\n          }))\n          await handleUpdateResult(value, files)\n          handleCloseModal()\n          resolve(true)\n        } catch (e) {\n          reject(e)\n        }\n      })\n    },\n    [\n      allowAnonymousUse,\n      appInfo.appId,\n      appInfo.config.public,\n      appInfo.deployed,\n      expirationType,\n      expiredTime,\n      handleCloseModal,\n      handleUpdateResult,\n      useHotlink,\n    ],\n  )\n\n  const getFileList = useCallback(\n    async (currentPage: number, totalPath: string, search?: string) => {\n      if (appInfo.config.public && !allowAnonymousUse) {\n        return\n      }\n      try {\n        const requestParams = {\n          path: `/${totalPath || ROOT_PATH}`,\n          page: currentPage,\n          limit: PAGESIZE,\n          type: DRIVE_FILE_TYPE.MIX,\n          search,\n        }\n        const res = allowAnonymousUse\n          ? await fetchAnonymousFileList(appInfo.appId, requestParams)\n          : await fetchFileList(requestParams)\n        if (currentPage === 1) {\n          setFileList(res.data?.files || [])\n        } else {\n          setFileList((prev) => [...prev, ...(res.data?.files || [])])\n        }\n      } catch (e) {}\n    },\n    [allowAnonymousUse, appInfo],\n  )\n\n  const value = {\n    rootPath: ROOT_PATH,\n    modalVisible,\n    fileList,\n    currentPath,\n    totalPath,\n    minSize,\n    maxSize,\n    minFileNum,\n    maxFileNum,\n    sizeType,\n    colorScheme,\n    updatePath,\n    submitSelect,\n    setModalVisible,\n    getFileList,\n    handleCloseModal,\n  }\n\n  return (\n    <DriveFileSelectContext.Provider value={value}>\n      {children}\n    </DriveFileSelectContext.Provider>\n  )\n}\n\nDrivePickerProvider.displayName = \"DrivePickerProvider\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DrivePickerWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const wrapperStyle = css`\n  width: 100%;\n  height: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/DrivePickerWidget/widgetConfig.tsx",
    "content": "import DrivePickerWidgetIcon from \"@/assets/widgetCover/drivePicker.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const DRIVE_PICKER_WIDGET_CONFIG: WidgetConfig = {\n  type: \"DRIVE_PICKER_WIDGET\",\n  displayName: \"drivePicker\",\n  widgetName: i18n.t(\"widget.drive_picker.name\"),\n  icon: <DrivePickerWidgetIcon />,\n  keywords: [\"drivePicker\", \"文件选择器\"],\n  sessionType: \"ILLA_DRIVE\",\n  w: 6,\n  h: 5,\n  version: 0,\n  defaults: {\n    variant: \"fill\",\n    colorScheme: \"blue\",\n    hidden: false,\n    expirationType: \"persistent\",\n    useHotlink: \"{{true}}\",\n    text: i18n.t(\n      \"editor.inspect.setter_default_value.drive_builder.button_text\",\n    ),\n    sizeType: \"mb\",\n    value: [],\n    files: [],\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EditableWidget/editableText.tsx",
    "content": "import { debounce } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useRef, useState } from \"react\"\nimport { Input, PenIcon } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { containerStyle } from \"@/widgetLibrary/PublicSector/containerStyle\"\nimport { EditableTextWidgetProps, WrappedEditableTextProps } from \"./interface\"\nimport { applyTextCss } from \"./style\"\nimport { getValidateMessageFunc } from \"./utils\"\n\nexport const WrappedEditableText: FC<WrappedEditableTextProps> = (props) => {\n  const {\n    value,\n    placeholder,\n    disabled,\n    readOnly,\n    prefixIcon,\n    prefixText,\n    suffixIcon,\n    suffixText,\n    showCharacterCount,\n    colorScheme,\n    maxLength,\n    minLength,\n    allowClear,\n    className,\n    handleOnChange,\n  } = props\n\n  const inputRef = useRef<HTMLInputElement>(null)\n  const [focus, setFocus] = useState(false)\n\n  const handleClickOnSpan = () => {\n    setFocus(true)\n    setTimeout(() => {\n      inputRef.current?.focus()\n    }, 100)\n  }\n\n  return (\n    <div css={containerStyle} className={className}>\n      {focus ? (\n        <Input\n          w=\"100%\"\n          autoFocus\n          onChange={handleOnChange}\n          showWordLimit={showCharacterCount}\n          onBlur={() => {\n            setFocus(false)\n          }}\n          value={value}\n          addAfter={suffixText}\n          addBefore={prefixText}\n          suffix={suffixIcon}\n          prefix={prefixIcon}\n          inputRef={inputRef}\n          readOnly={readOnly}\n          allowClear={allowClear}\n          placeholder={placeholder}\n          disabled={disabled}\n          colorScheme={colorScheme}\n          maxLength={maxLength}\n          minLength={minLength}\n          onClear={() => handleOnChange(\"\")}\n        />\n      ) : (\n        <span\n          css={applyTextCss(!!(value && value?.length > 0))}\n          onClick={handleClickOnSpan}\n        >\n          {value && value?.length > 0 ? value : placeholder}\n          <PenIcon />\n        </span>\n      )}\n    </div>\n  )\n}\nWrappedEditableText.displayName = \"WrappedEditableText\"\n\nexport const EditableTextWidget: FC<EditableTextWidgetProps> = (props) => {\n  const {\n    displayName,\n    value,\n    minLength,\n    maxLength,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    pattern,\n    regex,\n    customRule,\n    hideValidationMessage,\n    updateComponentHeight,\n    validateMessage,\n    defaultValue,\n    triggerEventHandler,\n    handleUpdateMultiExecutionResult,\n  } = props\n\n  const [editableTextValue, setEditableTextValue] = useState(defaultValue)\n\n  const handleValidate = useCallback(\n    (value?: any) => {\n      const message = getValidateMessageFunc(value, {\n        hideValidationMessage: hideValidationMessage,\n        pattern: pattern,\n        regex: regex,\n        minLength: minLength,\n        maxLength: maxLength,\n        required: required,\n        customRule: customRule,\n      })\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [\n      customRule,\n      handleUpdateDsl,\n      hideValidationMessage,\n      maxLength,\n      minLength,\n      pattern,\n      regex,\n      required,\n    ],\n  )\n\n  useEffect(() => {\n    setEditableTextValue(defaultValue)\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          value: defaultValue || \"\",\n        },\n      },\n    ])\n  }, [defaultValue, displayName, handleUpdateMultiExecutionResult])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: string) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: undefined })\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    handleUpdateDsl,\n    deleteComponentRuntimeProps,\n    handleValidate,\n    value,\n  ])\n\n  const debounceOnChange = useRef(\n    debounce(\n      (\n        value: string,\n        triggerEventHandler: EditableTextWidgetProps[\"triggerEventHandler\"],\n        options?: {\n          hideValidationMessage?: EditableTextWidgetProps[\"hideValidationMessage\"]\n          pattern?: EditableTextWidgetProps[\"pattern\"]\n          regex?: EditableTextWidgetProps[\"regex\"]\n          minLength?: EditableTextWidgetProps[\"minLength\"]\n          maxLength?: EditableTextWidgetProps[\"maxLength\"]\n          required?: EditableTextWidgetProps[\"required\"]\n          customRule?: EditableTextWidgetProps[\"customRule\"]\n        },\n      ) => {\n        new Promise((resolve) => {\n          const message = getValidateMessageFunc(value, options)\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                value: value || \"\",\n                validateMessage: message,\n              },\n            },\n          ])\n          resolve(true)\n        }).then(() => {\n          triggerEventHandler(\"change\")\n        })\n      },\n      180,\n    ),\n  )\n\n  const handleOnChange = useCallback(\n    (value: string) => {\n      setEditableTextValue(value)\n      debounceOnChange.current(value, triggerEventHandler, {\n        hideValidationMessage: hideValidationMessage,\n        pattern: pattern,\n        regex: regex,\n        minLength: minLength,\n        maxLength: maxLength,\n        required: required,\n        customRule: customRule,\n      })\n    },\n    [\n      customRule,\n      hideValidationMessage,\n      maxLength,\n      minLength,\n      pattern,\n      regex,\n      required,\n      triggerEventHandler,\n    ],\n  )\n\n  const handleOnBlur = useCallback(() => {\n    triggerEventHandler(\"blur\")\n  }, [triggerEventHandler])\n\n  const handleOnFocus = useCallback(() => {\n    triggerEventHandler(\"focus\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedEditableText\n            {...props}\n            value={editableTextValue}\n            handleOnChange={handleOnChange}\n            handleOnBlur={handleOnBlur}\n            handleOnFocus={handleOnFocus}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nEditableTextWidget.displayName = \"EditableTextWidget\"\nexport default EditableTextWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EditableWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const EDITABLE_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.focus\",\n      ),\n      value: \"focus\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.blur\",\n      ),\n      value: \"blur\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"focus\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EditableWidget/index.tsx",
    "content": "export { EDITABLE_TEXT_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { EDITABLE_TEXT_PANEL_CONFIG } from \"./panelConfig\"\nexport { EDITABLE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EditableWidget/interface.ts",
    "content": "import { ReactNode } from \"react\"\nimport { InputProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedEditableTextProps\n  extends Pick<\n    InputProps,\n    \"placeholder\" | \"disabled\" | \"readOnly\" | \"maxLength\" | \"minLength\"\n  > {\n  showCharacterCount?: InputProps[\"showWordLimit\"]\n  value?: string\n  className?: string\n  prefixIcon?: ReactNode\n  prefixText?: string\n  suffixIcon?: ReactNode\n  suffixText?: string\n  tooltipText?: string\n  handleUpdateDsl: (value: any) => void\n  colorScheme?: InputProps[\"colorScheme\"]\n  allowClear?: InputProps[\"allowClear\"]\n  handleOnChange: (value: string) => void\n  handleOnFocus?: () => void\n  handleOnBlur?: () => void\n}\n\nexport interface EditableTextWidgetProps\n  extends Omit<\n      WrappedEditableTextProps,\n      \"maxLength\" | \"handleOnChange\" | \"handleOnFocus\" | \"handleOnBlur\"\n    >,\n    BaseWidgetProps,\n    LabelProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  validateMessage: string\n  defaultValue?: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EditableWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { EDITABLE_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/EditableWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"editable-text\"\nexport const EDITABLE_TEXT_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"defaultValue\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"placeholder\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-label-width`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          EDITABLE_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        placeholder: \"{{false}}\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readOnly\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        attrName: \"allowClear\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-showChartCount`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_character_count\"),\n        attrName: \"showCharacterCount\",\n        useCustomLayout: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-prefixText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.prefix_text\"),\n        attrName: \"prefixText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-adornments-suffixText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.suffix_text\"),\n        attrName: \"suffixText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-pattern`,\n        labelName: i18n.t(\"editor.inspect.setter_label.pattern\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"pattern\",\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.validation_pattern.email\",\n            ),\n            value: \"Email\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.validation_pattern.url\",\n            ),\n            value: \"URL\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.validation_pattern.regex\",\n            ),\n            value: \"Regex\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-validation-regex`,\n        labelName: i18n.t(\"editor.inspect.setter_label.regex\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"regex\",\n        bindAttrName: [\"pattern\"],\n        expectedType: VALIDATION_TYPES.STRING,\n        shown: (value) => value === \"Regex\",\n      },\n      {\n        id: `${baseWidgetName}-validation-max`,\n        labelName: i18n.t(\"editor.inspect.setter_label.max_length\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"maxLength\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-min`,\n        labelName: i18n.t(\"editor.inspect.setter_label.min_length\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"minLength\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        attrName: \"hideValidationMessage\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EditableWidget/style.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport function applyTextCss(isPlaceHolder = false) {\n  return css`\n    width: 100%;\n    height: 32px;\n    max-height: 32px;\n    padding: 0;\n    display: inline-flex;\n    font-size: 14px;\n    align-items: center;\n    box-sizing: border-box;\n    max-lines: 1;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    border-radius: 8px;\n    color: ${!isPlaceHolder\n      ? globalColor(`--${illaPrefix}-grayBlue-04`)\n      : globalColor(`--${illaPrefix}-grayBlue-02`)};\n    &:hover {\n      background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n      cursor: pointer;\n      padding-left: 16px;\n      svg {\n        opacity: 1;\n      }\n    }\n    transition: all 200ms;\n    svg {\n      width: 14px;\n      height: 14px;\n      margin-left: 8px;\n      opacity: 0;\n      color: ${globalColor(`--${illaPrefix}-grayBlue-05`)};\n      transition: all 200ms;\n    }\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EditableWidget/utils.ts",
    "content": "import {\n  getValidateVFromString,\n  handleValidateCheck,\n} from \"../PublicSector/InvalidMessage/utils\"\nimport { EditableTextWidgetProps } from \"./interface\"\n\nexport const getValidateMessageFunc = (\n  value: string | undefined,\n  options: {\n    hideValidationMessage?: EditableTextWidgetProps[\"hideValidationMessage\"]\n    pattern?: EditableTextWidgetProps[\"pattern\"]\n    regex?: EditableTextWidgetProps[\"regex\"]\n    minLength?: EditableTextWidgetProps[\"minLength\"]\n    maxLength?: EditableTextWidgetProps[\"maxLength\"]\n    required?: EditableTextWidgetProps[\"required\"]\n    customRule?: EditableTextWidgetProps[\"customRule\"]\n  } = {},\n) => {\n  const {\n    hideValidationMessage,\n    pattern,\n    regex,\n    maxLength,\n    minLength,\n    required,\n    customRule,\n  } = options\n  if (!hideValidationMessage) {\n    const message = handleValidateCheck({\n      value: getValidateVFromString(value),\n      pattern,\n      regex,\n      minLength,\n      maxLength,\n      required,\n      customRule,\n    })\n    const showMessage = message && message.length > 0\n    return showMessage ? message : \"\"\n  }\n  return \"\"\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EditableWidget/widgetConfig.tsx",
    "content": "import EditableTextWidgetIcon from \"@/assets/widgetCover/editableText.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const EDITABLE_TEXT_WIDGET_CONFIG: WidgetConfig = {\n  type: \"EDITABLE_TEXT_WIDGET\",\n  displayName: \"editable_text\",\n  widgetName: i18n.t(\"widget.editable_text.name\"),\n  icon: <EditableTextWidgetIcon />,\n  keywords: [\"Editable Text\", \"可编辑文本\"],\n  sessionType: \"INPUTS\",\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  w: 12,\n  h: 5,\n  version: 0,\n  defaults: {\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    colorScheme: \"blue\",\n    hidden: false,\n    value: \"editable text for display\",\n    defaultValue: \"editable text for display\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EventCalendarWidget/eventCalendar.tsx",
    "content": "import dayjs from \"dayjs\"\nimport {\n  ComponentType,\n  FC,\n  MouseEvent,\n  ReactNode,\n  TouchEvent,\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport {\n  Calendar,\n  EventProps,\n  EventWrapperProps,\n  SlotInfo,\n  View,\n  dayjsLocalizer,\n} from \"react-big-calendar\"\nimport withDragAndDrop from \"react-big-calendar/lib/addons/dragAndDrop\"\nimport \"react-big-calendar/lib/addons/dragAndDrop/styles.css\"\nimport \"react-big-calendar/lib/css/react-big-calendar.css\"\nimport { useSelector } from \"react-redux\"\nimport { useMessage } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport {\n  Event,\n  EventCalendarWidgetProps,\n  EventInteractionArgs,\n  WrappedEventCalendarProps,\n} from \"@/widgetLibrary/EventCalendarWidget/interface\"\nimport {\n  ApplyCustomStyle,\n  applyEventStyle,\n  applyEventWrapper,\n} from \"@/widgetLibrary/EventCalendarWidget/style\"\nimport { useElementSize } from \"@/widgetLibrary/EventCalendarWidget/useElementSize\"\nimport {\n  eventList2Date,\n  format2EventList,\n  formatDateTime,\n  formatEventOptions,\n  getSafeDate,\n} from \"@/widgetLibrary/EventCalendarWidget/utils\"\n\nconst DragAndDropCalendar = withDragAndDrop(Calendar)\n\nconst localizer = dayjsLocalizer(dayjs)\n\nconst CustomEvent: FC<EventProps<Event>> = ({ event }) => {\n  const isInEdit = useSelector(getIsILLAEditMode)\n  const message = useMessage()\n  const isDrag = useRef(false)\n\n  const onMouseDown = (\n    e: MouseEvent<HTMLElement> | TouchEvent<HTMLElement>,\n  ) => {\n    if (isInEdit) {\n      e.stopPropagation()\n      isDrag.current = true\n    }\n  }\n  const onMouseMove = (e: MouseEvent<HTMLElement>) => {\n    if (isInEdit && isDrag.current) {\n      e.stopPropagation()\n      isDrag.current = true\n      message.info({\n        content: i18n.t(\n          \"editor.inspect.setter_tips.eventCalendar.couldnot_drag\",\n        ),\n      })\n      isDrag.current = false\n    }\n  }\n  const onMouseUp = (e: MouseEvent<HTMLElement>) => {\n    if (isInEdit) {\n      e.stopPropagation()\n      isDrag.current = false\n    }\n  }\n\n  const handleMove = (e: MouseEvent<HTMLElement> | TouchEvent<HTMLElement>) => {\n    if (isInEdit) {\n      e.stopPropagation()\n      onMouseDown(e)\n    }\n  }\n\n  return (\n    <div\n      css={applyEventStyle}\n      onMouseDownCapture={handleMove}\n      onTouchStartCapture={handleMove}\n      onMouseMoveCapture={onMouseMove}\n      onMouseUpCapture={onMouseUp}\n    >\n      <p>{event.title}</p>\n      <span>{event.description}</span>\n    </div>\n  )\n}\n\nconst CustomEventWrapper: FC<\n  EventWrapperProps<Event> & { children: ReactNode }\n> = ({ children }) => {\n  return <div css={applyEventWrapper}>{children}</div>\n}\n\nexport const WrappedEventCalendar: FC<WrappedEventCalendarProps> = (props) => {\n  const {\n    eventList,\n    resourceMapList,\n    showResource = false,\n    showCurrentTime,\n    defaultView = \"month\",\n    slotBackground = \"white\",\n    titleColor = \"gray\",\n    eventBackground = \"blue\",\n    eventTextColor = \"blue\",\n    defaultDate,\n    displayName,\n    moveEvent,\n    resizeEvent,\n    selectEvent,\n    onDragStart,\n    selectSlot,\n  } = props\n\n  const [view, setView] = useState<View>(defaultView)\n\n  const { indicatorTop, currentTime, isLight } = useElementSize(\n    view,\n    slotBackground,\n    displayName,\n  )\n  useEffect(() => {\n    if (showResource) {\n      if (view !== \"week\" && view !== \"day\") {\n        setView(\"day\")\n      }\n    }\n  }, [showResource, view])\n\n  return (\n    <div\n      className={displayName}\n      css={ApplyCustomStyle(\n        dayjs(currentTime).format(\"HH:mm\"),\n        indicatorTop,\n        showCurrentTime,\n        slotBackground,\n        titleColor,\n        eventBackground,\n        eventTextColor,\n        isLight,\n        displayName,\n        showResource,\n        view,\n      )}\n    >\n      <DragAndDropCalendar\n        defaultDate={defaultDate}\n        events={eventList2Date(eventList)}\n        localizer={localizer}\n        view={view}\n        onView={(v) => setView(v)}\n        onEventDrop={moveEvent}\n        onEventResize={resizeEvent}\n        resizable\n        resourceIdAccessor={(resource: Event) => resource.resourceID}\n        resources={\n          showResource && resourceMapList?.length ? resourceMapList : undefined\n        }\n        resourceTitleAccessor={(resource: Event) => resource.resourceTitle}\n        selectable\n        onSelectEvent={(ev) => selectEvent(ev)}\n        onSelectSlot={(ev: SlotInfo) => selectSlot(ev)}\n        showMultiDayTimes={false}\n        components={{\n          event: CustomEvent,\n          eventWrapper: CustomEventWrapper as ComponentType<\n            EventWrapperProps<object>\n          >,\n        }}\n        onDragStart={onDragStart}\n      />\n    </div>\n  )\n}\n\nWrappedEventCalendar.displayName = \"WrappedEventCalendar\"\n\nexport const EventCalendarWidget: FC<EventCalendarWidgetProps> = (props) => {\n  const {\n    eventConfigureMode,\n    manualOptions,\n    eventList,\n    defaultDate = new Date(),\n    mappedOption,\n    resourceMapList,\n    displayName,\n    dragMsg,\n    resizeMsg,\n    triggerEventHandler,\n    handleUpdateMultiExecutionResult,\n  } = props\n\n  const currentDefaultDate = useMemo(\n    () => getSafeDate(defaultDate),\n    [defaultDate],\n  )\n\n  const isInEdit = useSelector(getIsILLAEditMode)\n  const message = useMessage()\n\n  const [finalEventOptions, finalResourceOptions] = useMemo(() => {\n    return formatEventOptions(eventConfigureMode, manualOptions, mappedOption)\n  }, [eventConfigureMode, manualOptions, mappedOption])\n\n  useEffect(() => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          eventList: format2EventList(finalEventOptions),\n          resourceMapList: finalResourceOptions,\n        },\n      },\n    ])\n  }, [\n    displayName,\n    finalEventOptions,\n    finalResourceOptions,\n    handleUpdateMultiExecutionResult,\n  ])\n\n  const moveEvent = useCallback(\n    ({\n      event,\n      start,\n      end,\n      resourceID,\n      isAllDay: droppedOnAllDaySlot = false,\n    }: EventInteractionArgs) => {\n      if (!event.draggable) {\n        message.info({\n          content:\n            dragMsg ??\n            i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.default_message_draggable\",\n            ),\n        })\n        return\n      }\n      const { allDay } = event\n      if (allDay && droppedOnAllDaySlot) {\n        event.allDay = true\n      }\n      const existing = eventList.find((ev) => ev.id === event.id) ?? {}\n      const filtered = eventList.filter((ev) => ev.id !== event.id)\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              eventList: [\n                ...format2EventList(filtered),\n                {\n                  ...existing,\n                  start: dayjs(start).format(formatDateTime),\n                  end: dayjs(end).format(formatDateTime),\n                  resourceID,\n                  allDay,\n                },\n              ],\n              changeEventValue: {\n                ...existing,\n                start: dayjs(start).format(formatDateTime),\n                end: dayjs(end).format(formatDateTime),\n              },\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"change\")\n      })\n    },\n    [\n      displayName,\n      eventList,\n      dragMsg,\n      message,\n      handleUpdateMultiExecutionResult,\n      triggerEventHandler,\n    ],\n  )\n\n  const resizeEvent = useCallback(\n    ({ event, start, end }: EventInteractionArgs) => {\n      if (!event.resizable) {\n        message.info({\n          content:\n            resizeMsg ??\n            i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.default_message_resizable\",\n            ),\n        })\n        return\n      }\n      const minStep = 180000\n      const existing = eventList.find((ev) => ev.id === event.id) ?? {}\n      const filtered = eventList.filter((ev) => ev.id !== event.id)\n      let startTime = new Date(start).getTime(),\n        endTime = new Date(end).getTime()\n      if (endTime - startTime < minStep) {\n        return\n      }\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              eventList: [\n                ...format2EventList(filtered),\n                {\n                  ...existing,\n                  start: dayjs(start).format(formatDateTime),\n                  end: dayjs(end).format(formatDateTime),\n                },\n              ],\n              changeEventValue: {\n                ...existing,\n                start: dayjs(start).format(formatDateTime),\n                end: dayjs(end).format(formatDateTime),\n              },\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"change\")\n      })\n    },\n    [\n      displayName,\n      eventList,\n      resizeMsg,\n      message,\n      handleUpdateMultiExecutionResult,\n      triggerEventHandler,\n    ],\n  )\n\n  const selectEvent = useCallback(\n    (event: Event) => {\n      const { start, end } = event\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              selectEventValue: {\n                ...event,\n                start: dayjs(start).format(formatDateTime),\n                end: dayjs(end).format(formatDateTime),\n              },\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"select\")\n      })\n    },\n    [displayName, handleUpdateMultiExecutionResult, triggerEventHandler],\n  )\n\n  const showMessageOnEdit = () => {\n    message.info({\n      content: i18n.t(\"editor.inspect.setter_tips.eventCalendar.couldnot_drag\"),\n    })\n  }\n  const onDragStart = () => {\n    isInEdit && showMessageOnEdit()\n  }\n\n  const selectSlot = (e: SlotInfo) => {\n    if (isInEdit && e.action === \"select\") {\n      showMessageOnEdit()\n      return\n    }\n    const { start, end } = e\n    new Promise((resolve) => {\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            selectStartTime: dayjs(start).format(formatDateTime),\n            selectEndTime: dayjs(end).format(formatDateTime),\n            selectResource: resourceMapList.find(\n              (v) => v.resourceID === e.resourceId,\n            ),\n          },\n        },\n      ])\n      resolve(true)\n    }).then(() => {\n      triggerEventHandler(\"DragOrClickNoEventArea\")\n    })\n  }\n\n  return (\n    <WrappedEventCalendar\n      {...props}\n      eventList={eventList}\n      resourceMapList={resourceMapList}\n      moveEvent={isInEdit ? showMessageOnEdit : moveEvent}\n      selectEvent={selectEvent}\n      resizeEvent={isInEdit ? () => {} : resizeEvent}\n      defaultDate={currentDefaultDate}\n      onDragStart={onDragStart}\n      isInEdit={isInEdit}\n      selectSlot={selectSlot}\n    />\n  )\n}\nEventCalendarWidget.displayName = \"EventCalendarWidget\"\nexport default EventCalendarWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EventCalendarWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const EVENT_CALENDAR_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.select\",\n      ),\n      value: \"select\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.DragOrClickNoEventArea\",\n      ),\n      value: \"DragOrClickNoEventArea\",\n    },\n  ],\n  methods: [],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EventCalendarWidget/index.tsx",
    "content": "export { EVENT_CALENDAR_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { EVENT_CALENDAR_PANEL_CONFIG } from \"./panelConfig\"\nexport { EVENT_CALENDAR_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EventCalendarWidget/interface.ts",
    "content": "import { SlotInfo, View, stringOrDate } from \"react-big-calendar\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport type Pluralize<T> = {\n  [K in keyof T as `${string & K}s`]: T[K][]\n}\n\nexport type CssAttribute = string | number | undefined\nexport interface Event {\n  label?: string\n  title?: string\n  id?: number | string\n  value?: string\n  start?: Date\n  end?: Date\n  resourceID?: number | string\n  description?: string\n  allDay?: boolean\n  resourceTitle?: string\n  draggable?: boolean\n  resizable?: boolean\n}\nexport interface ResourceMap {\n  resourceTitle?: string\n  resourceID?: number | string\n}\nexport interface EventInteractionArgs {\n  event: Event\n  start: stringOrDate\n  end: stringOrDate\n  isAllDay: boolean\n  resourceID?: number | string\n}\n\nexport interface WrappedEventCalendarProps {\n  eventList: Event[]\n  resourceMapList: ResourceMap[]\n  defaultDate?: Date\n  showResource?: boolean\n  showCurrentTime?: boolean\n  defaultView?: View\n  slotBackground?: string\n  titleColor?: string\n  eventBackground?: string\n  eventTextColor?: string\n  displayName: string\n  isInEdit: boolean\n  moveEvent: (args: EventInteractionArgs) => void\n  resizeEvent: (args: EventInteractionArgs) => void\n  selectEvent: (args: Event) => void\n  onDragStart: () => void\n  selectSlot: (e: SlotInfo) => void\n}\n\nexport interface EventCalendarWidgetProps\n  extends WrappedEventCalendarProps,\n    BaseWidgetProps {\n  eventConfigureMode?: \"dynamic\" | \"static\"\n  manualOptions?: Event[]\n  mappedOption?: Pluralize<Event>\n  dragMsg?: string\n  resizeMsg?: string\n}\n\nexport interface CalendarEventOptionsType extends Event {\n  id: string\n  key?: string\n  label?: string\n  caption?: string\n  tooltip?: string\n  hidden?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EventCalendarWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { EVENT_CALENDAR_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/EventCalendarWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"eventCalendar\"\nexport const EVENT_CALENDAR_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-options-event`,\n    groupName: i18n.t(\"editor.inspect.setter_group.event\"),\n    children: [\n      {\n        id: `${baseWidgetName}-options-mode-event`,\n        attrName: \"eventConfigureMode\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: i18n.t(\"widget.public.select_options.manual\"),\n            value: \"static\",\n          },\n          {\n            label: i18n.t(\"widget.public.select_options.mapped\"),\n            value: \"dynamic\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-options-event`,\n        useCustomLayout: true,\n        attrName: \"manualOptions\",\n        setterType: \"CALENDAR_EVENT_LIST_SETTER\",\n        bindAttrName: [\"eventConfigureMode\"],\n        shown: (value) => !value || value === \"static\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-options-event-id`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.event_id\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.event_id\",\n            ),\n            attrName: \"value\",\n            placeholder: \"{{id}}\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-event-title`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.title\",\n            ),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.eventCalendar.title\"),\n            attrName: \"title\",\n            placeholder: \"{{title}}\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-event-description`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.description\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.description\",\n            ),\n            attrName: \"description\",\n            placeholder: \"{{description}}\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-event-start`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.start\",\n            ),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.eventCalendar.start\"),\n            attrName: \"start\",\n            placeholder: \"{{2032-1-1 00:00}}\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-event-end`,\n            labelName: i18n.t(\"editor.inspect.setter_label.eventCalendar.end\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.eventCalendar.end\"),\n            attrName: \"end\",\n            placeholder: \"{{2032-1-1 00:00}}\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-event-resourceID`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.resource_id\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.resource_id\",\n            ),\n            attrName: \"resourceID\",\n            placeholder: \"{{resourceID}}\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-resource-resourceTitle`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.resource_title\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.resource_title\",\n            ),\n            attrName: \"resourceTitle\",\n            placeholder: \"{{resourceTitle}}\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-event-allDay`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.all_day\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.all_day\",\n            ),\n            attrName: \"allDay\",\n            placeholder: \"{{false}}\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n          {\n            id: `${baseWidgetName}-options-event-Draggable`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.draggable\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.draggable\",\n            ),\n            setterType: \"INPUT_SETTER\",\n            attrName: \"draggable\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n          {\n            id: `${baseWidgetName}-options-event-Resizable`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.resizable\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.resizable\",\n            ),\n            setterType: \"INPUT_SETTER\",\n            attrName: \"resizable\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-option-data-sources-event`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.eventCalendar.data_source\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.eventCalendar.data_source\",\n        ),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"eventConfigureMode\"],\n        expectedType: VALIDATION_TYPES.ARRAY,\n        shown: (value) => value === \"dynamic\",\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-option-mapped-event`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.map_data_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedOption\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        bindAttrName: [\"eventConfigureMode\"],\n        shown: (value) => value === \"dynamic\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-mappedOption-event-id`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.event_id\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.event_id\",\n            ),\n            attrName: \"values\",\n            placeholder: \"{{item.event}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-event-title`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.title\",\n            ),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.eventCalendar.title\"),\n            attrName: \"titles\",\n            placeholder: \"{{item.title}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-event-description`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.description\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.description\",\n            ),\n            attrName: \"descriptions\",\n            placeholder: \"{{item.description}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-event-start`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.start\",\n            ),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.eventCalendar.start\"),\n            attrName: \"starts\",\n            placeholder: \"{{item.start}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-event-end`,\n            labelName: i18n.t(\"editor.inspect.setter_label.eventCalendar.end\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.eventCalendar.end\"),\n            attrName: \"ends\",\n            placeholder: \"{{item.end}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-event-resourceID`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.resource_id\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.resource_id\",\n            ),\n            attrName: \"resourceIDs\",\n            placeholder: \"{{item.resourceID}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-resource-resourceTitle`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.resource_title\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.resource_title\",\n            ),\n            attrName: \"resourceTitles\",\n            placeholder: \"{{item.resourceTitle}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-event-allDay`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.all_day\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.all_day\",\n            ),\n            attrName: \"allDays\",\n            placeholder: \"{{item.allDay}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-event-draggable`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.draggable\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.draggable\",\n            ),\n            attrName: \"draggables\",\n            placeholder: \"{{false}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-event-resizable`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.resizable\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.resizable\",\n            ),\n            attrName: \"resizables\",\n            placeholder: \"{{false}}\",\n            isSetterSingleRow: true,\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-default-date`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.eventCalendar.default_date\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.eventCalendar.default_date\",\n        ),\n        attrName: \"defaultDate\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        placeholder: \"2032-01-01\",\n      },\n      {\n        id: `${baseWidgetName}-basic-default-showResource`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.eventCalendar.resource_grid\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.eventCalendar.resource_grid\",\n        ),\n        attrName: \"showResource\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        placeholder: \"false\",\n        defaultValue: false,\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-default-view`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.eventCalendar.default_view\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.eventCalendar.default_view\",\n        ),\n        attrName: \"defaultView\",\n        expectedType: VALIDATION_TYPES.STRING,\n        isSetterSingleRow: true,\n        bindAttrName: [\"showResource\"],\n        setterType: \"EVENT_CALENDAR_SELECT\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.eventCalendar.month\"),\n            value: \"month\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.eventCalendar.week\"),\n            value: \"week\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.eventCalendar.day\"),\n            value: \"day\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.eventCalendar.agenda\"),\n            value: \"agenda\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          EVENT_CALENDAR_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-custom_message_draggable`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.eventCalendar.custom_message_draggable\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.eventCalendar.custom_message_draggable\",\n        ),\n        attrName: \"dragMsg\",\n        isSetterSingleRow: true,\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-custom_message_resizable`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.eventCalendar.custom_message_resizable\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.eventCalendar.custom_message_resizable\",\n        ),\n        attrName: \"resizeMsg\",\n        isSetterSingleRow: true,\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        defaultValue: false,\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-showCurrentTime`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.eventCalendar.show_current_time\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.eventCalendar.show_current_time\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"showCurrentTime\",\n        placeholder: \"true\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-color`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_group.event\"),\n        attrName: \"event\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-bg`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.calendar_background\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.calendar_background\",\n            ),\n            attrName: \"slotBackground\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"white\",\n          },\n          {\n            id: `${baseWidgetName}-style-cal-text`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.calendar_text\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.calendar_text\",\n            ),\n            attrName: \"titleColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"gray\",\n          },\n          {\n            id: `${baseWidgetName}-style-event-bg`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.event_background\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.event_background\",\n            ),\n            attrName: \"eventBackground\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n          {\n            id: `${baseWidgetName}-style-event-text`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.eventCalendar.event_text\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.eventCalendar.event_text\",\n            ),\n            attrName: \"eventTextColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EventCalendarWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { View } from \"react-big-calendar\"\nimport { getColor, getSpecialThemeColor } from \"@illa-design/react\"\n\nconst applyCalendarFont = css`\n  font-family: \"Inter\";\n  font-style: normal;\n  font-size: 14px;\n  font-weight: 400;\n`\n\nexport const applyEventStyle = css`\n  line-height: 14px;\n  ${applyCalendarFont};\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n  & p {\n    padding: 0;\n    margin: 0;\n    font-weight: 500;\n  }\n`\n\nconst applyEventCardStyle = (\n  eventBackground: string,\n  eventTextColor: string,\n  view: View,\n) => {\n  return css`\n    .rbc-event {\n      box-sizing: border-box;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      gap: 4px;\n      background-color: ${getColor(eventBackground, \"08\")};\n      border-left: 2px solid ${getSpecialThemeColor(eventBackground)}!important;\n      border-radius: 4px;\n      color: ${getSpecialThemeColor(eventTextColor)};\n      padding: ${view !== \"month\" ? \"12px 16px\" : \"\"};\n      overflow: hidden;\n    }\n    .rbc-month-view .rbc-event {\n      padding: 5px 8px;\n    }\n  `\n}\n\nconst applyMonthView = (titleColor: string, eventTextColor: string) => {\n  return css`\n    .rbc-month-view {\n      color: ${getSpecialThemeColor(titleColor)};\n      font-weight: 600;\n      .rbc-off-range {\n        color: ${getColor(titleColor, \"06\")}!important;\n      }\n      .rbc-off-range-bg {\n        background: none;\n      }\n      .rbc-addons-dnd-resizable span {\n        display: none;\n      }\n      .rbc-show-more {\n        ${applyCalendarFont};\n        background-color: transparent !important;\n        &:focus,\n        &:hover {\n          color: ${getSpecialThemeColor(eventTextColor)};\n        }\n      }\n    }\n  `\n}\nconst applyAgenda = css`\n  .rbc-agenda-view {\n    font-size: 14px;\n    font-weight: 400;\n    .rbc-agenda-date-cell {\n      border-right: 1px solid #ebebeb;\n    }\n  }\n`\n\nconst applyIndicatorStyle = (indicatorTop: number) => {\n  return css`\n    .rbc-current-time-indicator {\n      background-color: red;\n    }\n    .rbc-current-time-indicator {\n      display: none;\n    }\n    .rbc-day-slot::before {\n      position: absolute;\n      z-index: 3;\n      content: \"\";\n      height: 1px;\n      width: 100%;\n      top: ${indicatorTop}px;\n      visibility: ${indicatorTop ? \"visible\" : \"hidden\"};\n      background-color: ${getColor(\"red\", \"03\")};\n    }\n  `\n}\n\nconst buttonGroupStyle = (titleColor: string, isLight: boolean) => {\n  const color = css`\n    color: ${getSpecialThemeColor(titleColor)}!important;\n  `\n  return css`\n    .rbc-btn-group {\n      background-color: transparent !important;\n      ${color};\n      button {\n        background-color: transparent !important;\n        ${color};\n        &:active,\n        &:hover,\n        &:focus {\n          background-color: transparent !important;\n          ${color};\n          box-shadow: none !important;\n        }\n      }\n      .rbc-active {\n        box-shadow: none !important;\n        background-color: ${isLight\n          ? getColor(\"blackAlpha\", \"09\")\n          : getColor(\"white\", \"09\")}!important;\n        ${color};\n        &:focus,\n        &:active {\n          ${color};\n          background-color: ${isLight\n            ? getColor(\"blackAlpha\", \"09\")\n            : getColor(\"white\", \"09\")}!important;\n        }\n      }\n    }\n  `\n}\nconst applyCalendarBg = (slotBackground: string) => {\n  return css`\n    background-color: ${getColor(slotBackground, \"08\")}!important;\n    .rbc-header,\n    .rbc-row-bg,\n    .rbc-label,\n    .rbc-time-gutter,\n    .rbc-day-slot,\n    .rbc-calendar,\n    tbody {\n      background-color: ${getColor(slotBackground, \"08\")}!important;\n    }\n  `\n}\nconst applyBorderStyle = (isLight: boolean) => {\n  return css`\n    .rbc-time-view,\n    .rbc-agenda-view,\n    .rbc-time-view div,\n    .rbc-time-view button,\n    .rbc-time-header.rbc-overflowing {\n      border-color: ${isLight\n        ? getColor(\"blackAlpha\", \"08\")\n        : getColor(\"white\", \"08\")};\n    }\n    .rbc-btn-group button,\n    .rbc-day-bg,\n    .rbc-month-row,\n    .rbc-month-view,\n    .rbc-agenda-view,\n    .rbc-header,\n    .rbc-toolbar,\n    tbody,\n    tr,\n    thead,\n    table,\n    .rbc-agenda-date-cell,\n    .rbc-agenda-event-cell,\n    .rbc-time-gutter {\n      border-color: ${isLight\n        ? getColor(\"blackAlpha\", \"08\")\n        : getColor(\"white\", \"08\")}!important;\n    }\n  `\n}\n\nexport const applyTitleColor = (titleColor: string) => {\n  return css`\n    .rbc-header,\n    .rbc-button-link,\n    .rbc-time-gutter .rbc-timeslot-group,\n    tbody {\n      color: ${getSpecialThemeColor(titleColor)};\n    }\n    .rbc-off-range .rbc-button-link {\n      color: ${getColor(titleColor, \"06\")}!important;\n    }\n  `\n}\n\nconst hiddenToolBarStyle = (showResource: boolean) => {\n  return css`\n    .rbc-toolbar .rbc-btn-group:last-of-type {\n      button:first-of-type,\n      button:last-of-type {\n        display: ${!showResource ? \"inline-block\" : \"none\"};\n      }\n    }\n  `\n}\n\nexport const ApplyCustomStyle = (\n  date: string,\n  indicatorTop: number,\n  showCurrentTime: boolean | undefined,\n  slotBackground: string,\n  titleColor: string,\n  eventBackground: string,\n  eventTextColor: string,\n  isLight: boolean,\n  displayName: string,\n  showResource: boolean,\n  view: View,\n) => {\n  let needHiddenLabel = -1\n  if (date) {\n    const [hour, minus] = Array.from(date.split(\":\"), (v) => parseInt(v))\n    if (minus <= 15) {\n      needHiddenLabel = hour\n    } else if (minus >= 45) {\n      needHiddenLabel = hour + 1\n    }\n  }\n  return css`\n    height: 100%;\n    width: 100%;\n    .rbc-today {\n      background: none !important;\n    }\n    [data-target=\"${displayName}\"] {\n      color: ${getSpecialThemeColor(titleColor)} !important;\n      visibility: ${showCurrentTime ? \"visible\" : \"hidden\"} !important;\n    }\n    .rbc-addons-dnd-resizable {\n      display: flex;\n      flex-direction: column;\n      gap: 4px;\n    }\n    .rbc-time-view {\n      .rbc-time-gutter::after {\n        position: absolute;\n        z-index: 11;\n        left: 0;\n        width: 100%;\n        content: \" ${date}\";\n        top: ${indicatorTop}px;\n        visibility: ${indicatorTop ? \"visible\" : \"hidden\"};\n        color: ${getColor(\"red\", \"03\")};\n        transform: translateY(-50%);\n        text-align: right;\n        white-space: nowrap;\n        padding: 0 5px;\n      }\n      .rbc-time-gutter {\n        position: sticky;\n        left: 0;\n        background-color: white;\n        border-right: 1px solid #ebebeb;\n        z-index: 10 !important;\n        margin-right: -1px;\n        ${applyCalendarFont};\n        font-family: \"SF Pro Display\";\n        line-height: 24px;\n      }\n      .rbc-timeslot-group .rbc-time-slot:first-of-type {\n        transform: translateY(-50%);\n      }\n      .rbc-time-gutter .rbc-timeslot-group {\n        border-bottom: none;\n      }\n      .rbc-timeslot-group:nth-of-type(${needHiddenLabel + 1}) .rbc-label,\n      .rbc-timeslot-group:first-of-type .rbc-label {\n        visibility: hidden;\n      }\n    }\n    }\n    .rbc-addons-dnd-resizable {\n      overflow: hidden;\n    }\n    .rbc-month-row {\n      min-height: 80px;\n    }\n    .rbc-row-content {\n      min-height: 60px;\n    }\n    .rbc-day-slot {\n      min-width: 140px;\n    }\n    .rbc-day-slot .rbc-events-container {\n      margin: 0 8px;\n      padding: 8px;\n    }\n    .rbc-time-header-cell .rbc-header,\n    .rbc-allday-cell .rbc-day-bg {\n      box-sizing: border-box;\n      min-width: 140px;\n    }\n    .rbc-event-label {\n      font-size: 14px;\n      font-weight: 500;\n    }\n    .${displayName} {\n      .rbc-event {\n        border-right: none;\n        border-top: none;\n        border-bottom: none;\n        min-height: ${view !== \"month\" ? \"40px\" : \"24px\"};\n        overflow: hidden;\n        margin-left: ${view !== \"month\" ? \"1px\" : \"0\"};\n        border-radius: ${view !== \"month\" ? \"4px\" : \"0\"}!important;\n      }\n      .rbc-selected {\n        background-color: ${getColor(eventBackground, \"08\")}!important;\n      }\n      .rbc-addons-dnd-resize-ew-anchor {\n        top: 50%;\n        transform: translateY(-50%);\n      }\n      .rbc-addons-dnd-resize-ew-icon {\n        width: 100% !important;\n        height: 100% !important;\n      }\n      .rbc-header {\n        font-weight: 400;\n        font-size: 14px;\n        line-light: 22px;\n      }\n      .rbc-day-slot .rbc-time-slot {\n        border: none;\n      }\n      .rbc-timeslot-group {\n        min-height: 80px;\n      }\n      ${applyIndicatorStyle(indicatorTop)};\n      ${applyMonthView(titleColor, eventTextColor)};\n      ${applyCalendarBg(slotBackground)};\n      ${applyAgenda};\n      ${buttonGroupStyle(titleColor, isLight)};\n      ${applyTitleColor(titleColor)};\n      ${applyEventCardStyle(eventBackground, eventTextColor, view)};\n      ${applyBorderStyle(isLight)};\n      ${hiddenToolBarStyle(showResource)};\n    }\n  `\n}\n\nexport const applyEventWrapper = css`\n  margin: 4px;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EventCalendarWidget/useElementSize.ts",
    "content": "import { useEffect, useState } from \"react\"\nimport { View } from \"react-big-calendar\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\nimport {\n  isInWeekOrDay,\n  isLightColor,\n} from \"@/widgetLibrary/EventCalendarWidget/utils\"\n\nexport const useElementSize = (\n  view: View,\n  slotBackground: string,\n  displayName: string,\n) => {\n  const [slotHeight, setSlotHeight] = useState(79)\n  const [indicatorTop, setIndicatorTop] = useState(0)\n  const [currentTime, setCurrentTime] = useState<Date>()\n  const [isLight, setIsLight] = useState(true)\n\n  useEffect(() => {\n    if (!isInWeekOrDay(view)) {\n      return\n    }\n    let observer: ResizeObserver | null = new ResizeObserver((entries) => {\n        const { height } = entries[0].contentRect\n        height && height > 80 && setSlotHeight(height)\n      }),\n      timeSlot = document.querySelector(\".rbc-timeslot-group\")\n    if (timeSlot) {\n      observer.observe(timeSlot)\n    }\n    return () => {\n      if (timeSlot && observer && isInWeekOrDay(view)) {\n        observer.unobserve(timeSlot)\n        timeSlot = null\n        observer = null\n      }\n    }\n  }, [view])\n\n  useEffect(() => {\n    if (!isInWeekOrDay(view)) {\n      return\n    }\n    const setIndicator = () => {\n      const date = new Date(),\n        hour = date.getHours(),\n        minus = date.getMinutes()\n      setIndicatorTop((hour + minus / 60) * (slotHeight + 1))\n      setCurrentTime(date)\n    }\n    setIndicator()\n    const intervalId = window.setInterval(setIndicator, 60000)\n    return () => {\n      if (isInWeekOrDay(view)) {\n        clearInterval(intervalId)\n      }\n    }\n  }, [slotHeight, view])\n\n  useEffect(() => {\n    if (slotBackground) {\n      const formatColor = getSpecialThemeColor(slotBackground)\n      setIsLight(isLightColor(formatColor))\n    }\n  }, [slotBackground])\n\n  useEffect(() => {\n    const toolBar = document.querySelector(\".rbc-toolbar-label\")\n    toolBar && toolBar.setAttribute(\"data-target\", displayName)\n  }, [displayName])\n\n  return {\n    slotHeight,\n    indicatorTop,\n    currentTime,\n    isLight,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EventCalendarWidget/utils.ts",
    "content": "import dayjs from \"dayjs\"\nimport { View } from \"react-big-calendar\"\nimport i18n from \"@/i18n/config\"\nimport {\n  Event,\n  Pluralize,\n  ResourceMap,\n} from \"@/widgetLibrary/EventCalendarWidget/interface\"\n\nexport const isInWeekOrDay = (view: View) => view === \"week\" || view === \"day\"\nexport const formatDateTime = \"YYYY-MM-DD HH:mm\"\n\nexport const formatEventOptions = (\n  optionConfigureMode: \"dynamic\" | \"static\" = \"static\",\n  manualOptions: (Event & ResourceMap)[] = [],\n  mappedOption: Pluralize<Event & ResourceMap> = {\n    titles: [],\n    ids: [],\n    starts: [],\n    ends: [],\n    resourceIDs: [],\n    descriptions: [],\n    resourceTitles: [],\n    allDays: [],\n  },\n) => {\n  if (optionConfigureMode === \"dynamic\") {\n    const title = mappedOption.titles ?? []\n    const id = mappedOption.values ?? []\n    const start = mappedOption.starts ?? []\n    const end = mappedOption.ends ?? []\n    const resourceID = mappedOption.resourceIDs ?? []\n    const description = mappedOption.descriptions ?? []\n    const resourceTitle = mappedOption.resourceTitles ?? []\n    const allDay = mappedOption.allDays ?? []\n    const draggable = mappedOption.draggables ?? []\n    const resizable = mappedOption.resizables ?? []\n    const maxLength = Math.max(\n      title.length,\n      id.length,\n      start.length,\n      end.length,\n      resourceID.length,\n      description.length,\n      resourceTitle.length,\n      allDay.length,\n      resizable.length,\n      draggable.length,\n    )\n    const eventList: Event[] = []\n    const resourceMap = new Map()\n    for (let i = 0; i < maxLength; i++) {\n      const idItem = id[i] || `Event-${i + 1}`\n      const titleItem =\n        title[i] ||\n        i18n.t(\"editor.inspect.setter_content.eventCalendar.no_title\")\n      const startItem = start[i] || undefined\n      const endItem = end[i] || undefined\n      const resourceIDItem = resourceID[i] || \"\"\n      const resourceIDTitleItem = resourceTitle[i]\n      const descriptionItem = description[i] || \"\"\n      const allDayItem = allDay[i] ?? false\n      const resizableItem = resizable[i] ?? true\n      const draggableItem = draggable[i] ?? true\n      resourceIDTitleItem &&\n        resourceMap.set(\n          safeNodeValue(resourceIDItem),\n          safeNodeValue(resourceIDTitleItem),\n        )\n      idItem &&\n        eventList.push({\n          label: safeNodeValue(titleItem),\n          title: safeNodeValue(titleItem),\n          id: safeNodeValue(idItem),\n          start: getSafeDate(startItem),\n          end: getSafeDate(endItem),\n          resourceID: safeNodeValue(resourceIDItem),\n          resourceTitle: safeNodeValue(resourceIDTitleItem),\n          description: safeNodeValue(descriptionItem),\n          allDay: allDayItem,\n          draggable: draggableItem,\n          resizable: resizableItem,\n        })\n    }\n    return [\n      eventList,\n      Array.from(resourceMap, ([resourceID, resourceTitle]) => ({\n        resourceID,\n        resourceTitle,\n      })),\n    ]\n  } else {\n    if (!Array.isArray(manualOptions)) {\n      return []\n    }\n    const eventList: Event[] = []\n    const resourceMap = new Map()\n    manualOptions.forEach((option, i) => {\n      const idItem = option.value || `Event-${i + 1}`\n      const titleItem =\n        option.title ||\n        i18n.t(\"editor.inspect.setter_content.eventCalendar.no_title\")\n      const startItem = option.start || undefined\n      const endItem = option.end || undefined\n      const resourceIDItem = option.resourceID || `Resource-${i + 1}`\n      const descriptionItem = option.description || `Event-${i + 1}`\n      const resourceIDTitleItem = option.resourceTitle || `Resource-${i + 1}`\n      const allDayItem = option.allDay ?? false\n      const draggableItem = option.draggable ?? true\n      const resizableItem = option.resizable ?? true\n      resourceIDTitleItem &&\n        resourceMap.set(\n          safeNodeValue(resourceIDItem),\n          safeNodeValue(resourceIDTitleItem),\n        )\n      idItem &&\n        eventList.push({\n          label: safeNodeValue(titleItem),\n          title: safeNodeValue(titleItem),\n          id: safeNodeValue(idItem),\n          start: getSafeDate(startItem),\n          end: getSafeDate(endItem),\n          resourceID: safeNodeValue(resourceIDItem),\n          resourceTitle: safeNodeValue(resourceIDTitleItem),\n          description: safeNodeValue(descriptionItem),\n          allDay: allDayItem,\n          draggable: draggableItem,\n          resizable: resizableItem,\n        })\n    })\n    return [\n      eventList,\n      Array.from(resourceMap, ([resourceID, resourceTitle]) => ({\n        resourceID,\n        resourceTitle,\n      })),\n    ]\n  }\n}\n\nexport const format2EventList = (eventList: Event[]) => {\n  if (!eventList) return []\n  return eventList.map((item) => {\n    return {\n      ...item,\n      start: dayjs(item.start).format(formatDateTime),\n      end: dayjs(item.end).format(formatDateTime),\n    }\n  })\n}\n\nexport const eventList2Date = (eventList: Event[]) => {\n  if (!eventList) return []\n  return eventList.map((item) => {\n    return {\n      ...item,\n      start: item.start ? new Date(item.start) : new Date(),\n      end: item.end ? new Date(item.end) : new Date(),\n    }\n  })\n}\n\nexport const isLightColor = (color: string): boolean => {\n  const hexRegex = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})([0-9a-fA-F]{2})?$/\n  const hslRegex =\n    /^hsla?\\(\\s*(-?\\d+%?)\\s*,\\s*(-?\\d+%?)\\s*,\\s*(-?\\d+%?)\\s*(,\\s*(0?\\.\\d+|[01]))?\\s*\\)$/i\n  const hexMatch = color.match(hexRegex)\n  const hslMatch = color.match(hslRegex)\n  const rWeights = 0.299,\n    gWeights = 0.587,\n    bWeights = 0.114,\n    fullRGB = 255,\n    critical = 0.5,\n    fullH = 360\n\n  if (hexMatch) {\n    const hex = hexMatch[1]\n    const r = parseInt(hex.length === 3 ? hex[0] + hex[0] : hex.slice(0, 2), 16)\n    const g = parseInt(hex.length === 3 ? hex[1] + hex[1] : hex.slice(2, 4), 16)\n    const b = parseInt(hex.length === 3 ? hex[2] + hex[2] : hex.slice(4, 6), 16)\n    const luminance = (rWeights * r + gWeights * g + bWeights * b) / fullRGB\n    return luminance >= critical\n  } else if (hslMatch) {\n    const h = parseInt(hslMatch[1])\n    const s = parseInt(hslMatch[2].slice(0, -1)) / 100\n    const l = parseInt(hslMatch[3].slice(0, -1)) / 100\n    const a = hslMatch[4] ? parseFloat(hslMatch[5]) : 1\n    const luminance =\n      (rWeights * s + gWeights * l + (bWeights * h) / fullH) * a + (1 - a)\n    return luminance >= critical\n  } else {\n    return false\n  }\n}\n\nconst safeNodeValue = (value: unknown) => {\n  return typeof value === \"string\" ? value : \"\"\n}\n\nexport const getSafeDate = (value: string | Date | undefined) => {\n  if (value) {\n    const date = new Date(value)\n    if (isNaN(date.getTime())) {\n      return new Date()\n    }\n    return date\n  }\n  return new Date()\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/EventCalendarWidget/widgetConfig.tsx",
    "content": "import dayjs from \"dayjs\"\nimport { v4 } from \"uuid\"\nimport EventCalendarWidgetIcon from \"@/assets/widgetCover/eventCalendar.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { formatDateTime } from \"@/widgetLibrary/EventCalendarWidget/utils\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nconst date = new Date(),\n  fullYear = date.getFullYear(),\n  month = date.getMonth(),\n  day = date.getDate(),\n  hour = date.getHours(),\n  minus = date.getMinutes(),\n  emptyEvent = {\n    id: \"\",\n    title: \"\",\n    description: \"\",\n    start: \"\",\n    end: \"\",\n    resourceID: \"\",\n    resourceTitle: \"\",\n    allDay: false,\n  }\n\nexport const EVENT_CALENDAR_WIDGET_CONFIG: WidgetConfig = {\n  displayName: \"eventCalendar\",\n  widgetName: i18n.t(\"widget.eventCalendar.name.event_calendar\"),\n  h: 70,\n  w: 30,\n  type: \"EVENT_CALENDAR_WIDGET\",\n  icon: <EventCalendarWidgetIcon />,\n  keywords: [\"EventCalendar\", \"活动日历\"],\n  sessionType: \"CALENDAR\",\n  resizeDirection: RESIZE_DIRECTION.ALL,\n  version: 0,\n  defaults: {\n    eventConfigureMode: \"static\",\n    manualOptions: [\n      {\n        id: `event-${v4()}`,\n        label: \"Event 1\",\n        title: \"Event 1\",\n        value: \"Event 1\",\n        description: \"\",\n        start: dayjs(new Date(fullYear, month, day - 1, hour, minus)).format(\n          formatDateTime,\n        ),\n        end: dayjs(new Date(fullYear, month, day - 1, hour + 2, minus)).format(\n          formatDateTime,\n        ),\n        resourceID: \"Resource 1\",\n        resourceTitle: \"Resource 1\",\n        allDay: undefined,\n      },\n      {\n        id: `event-${v4()}`,\n        title: \"Event 2\",\n        label: \"Event 2\",\n        value: \"Event 2\",\n        description: \"\",\n        start: dayjs(new Date(fullYear, month, day, hour, minus)).format(\n          formatDateTime,\n        ),\n        end: dayjs(new Date(fullYear, month, day, hour + 2, minus)).format(\n          formatDateTime,\n        ),\n        resourceID: \"Resource 2\",\n        resourceTitle: \"Resource 2\",\n        allDay: undefined,\n      },\n      {\n        id: `event-${v4()}`,\n        title: \"Event 3\",\n        label: \"Event 3\",\n        value: \"Event 3\",\n        description: \"\",\n        start: dayjs(new Date(fullYear, month, day + 1, hour, minus)).format(\n          formatDateTime,\n        ),\n        end: dayjs(new Date(fullYear, month, day + 1, hour + 2, minus)).format(\n          formatDateTime,\n        ),\n        resourceID: \"Resource 3\",\n        resourceTitle: \"Resource 3\",\n        allDay: undefined,\n      },\n    ],\n    resourceMapList: [\n      {\n        resourceID: \"Resource 1\",\n        resourceTitle: \"Resource 1\",\n      },\n      {\n        resourceID: \"Resource 2\",\n        resourceTitle: \"Resource 2\",\n      },\n      {\n        resourceID: \"Resource 3\",\n        resourceTitle: \"Resource 3\",\n      },\n    ],\n    dataSources: \"{{[]}}\",\n    defaultView: \"month\",\n    defaultDate: dayjs(date).format(\"YYYY-MM-DD\"),\n    showResource: false,\n    showCurrentTime: \"{{true}}\",\n    slotBackground: \"white\",\n    titleColor: \"gray\",\n    eventBackground: \"blue\",\n    eventTextColor: \"blue\",\n    borderColor: \"gray\",\n    hidden: false,\n    addEventValue: emptyEvent,\n    deleteEventValue: emptyEvent,\n    selectEventValue: emptyEvent,\n    changeEventValue: emptyEvent,\n    selectStartTime: \"\",\n    selectEndTime: \"\",\n    selectResource: {\n      resourceID: \"\",\n      resourceTitle: \"\",\n    },\n    draggable: \"{{true}}\",\n    resizable: \"{{true}}\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/FormWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const FORM_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.submit\",\n      ),\n      value: \"submit\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.invalid\",\n      ),\n      value: \"invalid\",\n    },\n  ],\n  methods: [\"submit\", \"reset\", \"setValue\", \"validate\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/FormWidget/form.tsx",
    "content": "import { ComponentMapNode } from \"@illa-public/public-types\"\nimport { get, isEqual, set } from \"lodash-es\"\nimport { Resizable, ResizeCallback, ResizeStartCallback } from \"re-resizable\"\nimport {\n  FC,\n  MutableRefObject,\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport { useDrop } from \"react-dnd\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport useMeasure from \"react-use-measure\"\nimport { useMessage } from \"@illa-design/react\"\nimport ResizeBar from \"@/assets/resizeBar.svg?react\"\nimport { DropResultInfo } from \"@/page/App/components/DotPanel/components/Canvas/interface\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { DragInfo } from \"@/page/App/components/ScaleSquare/components/DragContainer/interface\"\nimport {\n  applyDashedLineStyle,\n  applyXDirectionDashedLineStyle,\n} from \"@/page/App/components/ScaleSquare/style\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getComponentMap } from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { evaluateDynamicString } from \"@/utils/evaluateDynamicString\"\nimport { ILLAEditorRuntimePropsCollectorInstance } from \"@/utils/executionTreeHelper/runtimePropsCollector\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport RenderChildrenCanvas from \"../PublicSector/RenderChildrenCanvas\"\nimport { FormWidgetProps } from \"./interface\"\nimport {\n  formBodyStyle,\n  formContainerStyle,\n  formHeaderStyle,\n  resizeBarStyle,\n  resizeLineStyle,\n} from \"./style\"\nimport {\n  FORM_BODY_MARGIN,\n  FORM_BODY_MIN_HEIGHT,\n  FORM_CAN_BIND_WIDGET_TYPE,\n  FORM_MIN_FOOTER_HEIGHT_ROW_NUMBER,\n  FORM_MIN_HEADER_HEIGHT_ROW_NUMBER,\n} from \"./widgetConfig\"\n\nfunction getLikeInputChildrenNode(\n  componentNodeDisplayName: string,\n  componentNodeResult: ComponentMapNode[],\n  components: Record<string, ComponentMapNode>,\n  hasForm: boolean,\n) {\n  const componentNode = components[componentNodeDisplayName]\n  if (\n    (componentNode.containerType !== \"EDITOR_DOT_PANEL\" &&\n      FORM_CAN_BIND_WIDGET_TYPE.has(componentNode.type)) ||\n    (hasForm && componentNode.type === \"FORM_WIDGET\")\n  ) {\n    componentNodeResult.push(componentNode)\n    if (Array.isArray(componentNode.childrenNode)) {\n      componentNode.childrenNode.forEach((childDisplayName) => {\n        getLikeInputChildrenNode(\n          childDisplayName,\n          componentNodeResult,\n          components,\n          hasForm,\n        )\n      })\n    }\n  } else {\n    if (Array.isArray(componentNode.childrenNode)) {\n      componentNode.childrenNode.forEach((childDisplayName) => {\n        getLikeInputChildrenNode(\n          childDisplayName,\n          componentNodeResult,\n          components,\n          hasForm,\n        )\n      })\n    }\n  }\n}\n\ninterface DragCollection {\n  isDraggingActive: boolean\n}\n\nexport const FormWidget: FC<FormWidgetProps> = (props) => {\n  const {\n    childrenNode: childrenNodeDisplayNames,\n    showFooter,\n    showHeader,\n    headerHeight,\n    footerHeight,\n    disabled,\n    displayName,\n    disabledSubmit,\n    resetAfterSuccessful,\n    validateInputsOnSubmit,\n    columnNumber,\n    formData: propsFormData,\n    dynamicHeight = \"fixed\",\n    padding,\n    handleUpdateOriginalDSLMultiAttr,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n  } = props\n\n  const message = useMessage()\n  const [containerRef, containerBounds] = useMeasure()\n  const prevDisabled = useRef<boolean>(disabled)\n  const containerNodeRef = useRef<HTMLDivElement>(\n    null,\n  ) as MutableRefObject<HTMLDivElement | null>\n  const [isMouseHover, setIsMouseHover] = useState(false)\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const executionResult = useSelector(getExecutionResult)\n  const components = useSelector(getComponentMap)\n\n  const dispatch = useDispatch()\n\n  const allLikeInputWithFormChildrenNodeDisplayName = useMemo(() => {\n    let componentNodeResult: ComponentMapNode[] = []\n    childrenNodeDisplayNames.forEach((node) => {\n      getLikeInputChildrenNode(node, componentNodeResult, components, true)\n    })\n    return componentNodeResult.map((node) => node.displayName)\n  }, [childrenNodeDisplayNames, components])\n\n  const allLikeInputChildrenNode = useMemo(() => {\n    let componentNodeResult: ComponentMapNode[] = []\n    childrenNodeDisplayNames.forEach((node) => {\n      getLikeInputChildrenNode(node, componentNodeResult, components, false)\n    })\n    return componentNodeResult\n  }, [childrenNodeDisplayNames, components])\n\n  const allLikeInputChildrenNodeDisplayName = useMemo(() => {\n    return allLikeInputChildrenNode.map((node) => node.displayName)\n  }, [allLikeInputChildrenNode])\n\n  const allLikeInputChildrenNodeRealProps = useMemo(() => {\n    return allLikeInputChildrenNodeDisplayName.map((name) => {\n      const widgetProps = get(executionResult, name, {})\n      return {\n        displayName: name,\n        ...widgetProps,\n      }\n    })\n  }, [allLikeInputChildrenNodeDisplayName, executionResult])\n\n  const formDataKeyMapProps = useMemo(() => {\n    const map: Record<string, any> = {}\n    allLikeInputChildrenNodeRealProps.forEach((prop) => {\n      set(map, prop.formDataKey || prop.displayName, prop)\n    })\n    return map\n  }, [allLikeInputChildrenNodeRealProps])\n\n  const formData = useMemo(() => {\n    const data: Record<string, any> = {}\n    allLikeInputChildrenNodeRealProps.forEach((prop) => {\n      set(data, prop.formDataKey || prop.displayName, prop.value)\n    })\n    return data\n  }, [allLikeInputChildrenNodeRealProps])\n\n  useEffect(() => {\n    if (!isEqual(formData, propsFormData)) {\n      handleUpdateMultiExecutionResult?.([\n        {\n          displayName,\n          value: {\n            formData: formData,\n          },\n        },\n      ])\n    }\n  }, [\n    dispatch,\n    displayName,\n    formData,\n    handleUpdateMultiExecutionResult,\n    propsFormData,\n  ])\n\n  useEffect(() => {\n    if (prevDisabled.current !== disabled) {\n      const updateArray = allLikeInputWithFormChildrenNodeDisplayName.map(\n        (displayName) => {\n          return {\n            displayName,\n            updateSlice: {\n              disabled:\n                typeof disabled === \"undefined\" ? \"\" : `{{${disabled}}}`,\n            },\n          }\n        },\n      )\n      dispatch(componentsActions.updateMultiComponentPropsReducer(updateArray))\n    }\n    prevDisabled.current = disabled\n  }, [\n    disabled,\n    childrenNodeDisplayNames,\n    allLikeInputWithFormChildrenNodeDisplayName,\n    dispatch,\n  ])\n\n  const handleOnInvalid = useCallback(() => {\n    triggerEventHandler(\"invalid\")\n  }, [triggerEventHandler])\n\n  const handleOnValidate = useCallback(() => {\n    const finalContext =\n      ILLAEditorRuntimePropsCollectorInstance.getCurrentPageCalcContext()\n    allLikeInputChildrenNode.forEach((node) => {\n      try {\n        return evaluateDynamicString(\n          \"events\",\n          `{{${node.displayName}.validate()}}`,\n          finalContext,\n        )\n      } catch (e) {\n        message.error({\n          content: \"eventHandler run error\",\n        })\n        return false\n      }\n    })\n  }, [allLikeInputChildrenNode, message])\n\n  const handleSetValue = useCallback(\n    (value: Record<string, any>) => {\n      const keys = Object.keys(value)\n      const updateSlice: {\n        displayName: string\n        value: {\n          value: string\n        }\n      }[] = []\n\n      keys.forEach((key) => {\n        const realDisplayName = get(formDataKeyMapProps, key, null)\n        if (realDisplayName) {\n          updateSlice.push({\n            displayName: key,\n            value: {\n              value: value[key],\n            },\n          })\n        }\n      })\n      if (updateSlice.length > 0) {\n        handleUpdateMultiExecutionResult?.(updateSlice)\n      }\n    },\n    [formDataKeyMapProps, handleUpdateMultiExecutionResult],\n  )\n\n  const handleOnReset = useCallback(() => {\n    const allUpdate = allLikeInputChildrenNode.map((node) => {\n      return {\n        displayName: node.displayName,\n        value: {\n          value: node.props!.value,\n          validateMessage: \"\",\n        },\n      }\n    })\n    handleUpdateMultiExecutionResult?.(allUpdate)\n  }, [allLikeInputChildrenNode, handleUpdateMultiExecutionResult])\n\n  const handleOnSubmit = useCallback(() => {\n    if (disabledSubmit || disabled) return\n    if (validateInputsOnSubmit) {\n      const finalContext =\n        ILLAEditorRuntimePropsCollectorInstance.getCurrentPageCalcContext()\n      const validateResult = allLikeInputChildrenNode.every((node) => {\n        try {\n          const validateFunc = get(\n            finalContext,\n            `${node.displayName}.validate`,\n          ) as unknown\n          if (typeof validateFunc === \"function\") {\n            return !validateFunc()\n          }\n          return false\n        } catch (e) {\n          message.error({\n            content: \"eventHandler run error\",\n          })\n          return false\n        }\n      })\n      if (!validateResult) {\n        handleOnInvalid()\n        return\n      }\n    }\n    triggerEventHandler(\"submit\")\n    if (resetAfterSuccessful) {\n      handleOnReset()\n    }\n  }, [\n    allLikeInputChildrenNode,\n    disabled,\n    disabledSubmit,\n    handleOnInvalid,\n    handleOnReset,\n    message,\n    resetAfterSuccessful,\n    triggerEventHandler,\n    validateInputsOnSubmit,\n  ])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      submit: handleOnSubmit,\n      invalid: handleOnInvalid,\n      reset: handleOnReset,\n      setValue: (value: Record<string, any>) => {\n        if (isObject(value)) {\n          handleSetValue(value)\n        }\n      },\n      validate: handleOnValidate,\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleOnInvalid,\n    handleOnReset,\n    handleOnSubmit,\n    handleOnValidate,\n    handleSetValue,\n    updateComponentRuntimeProps,\n  ])\n\n  const headerMinHeight = useMemo(\n    () => FORM_MIN_HEADER_HEIGHT_ROW_NUMBER * UNIT_HEIGHT,\n    [],\n  )\n  const footerMinHeight = useMemo(\n    () => FORM_MIN_FOOTER_HEIGHT_ROW_NUMBER * UNIT_HEIGHT,\n    [],\n  )\n\n  const headerMaxHeight = useMemo(() => {\n    return (\n      Math.floor(\n        (containerBounds.height -\n          (FORM_BODY_MIN_HEIGHT + 2 * FORM_BODY_MARGIN) -\n          footerHeight * UNIT_HEIGHT) /\n          UNIT_HEIGHT,\n      ) * UNIT_HEIGHT\n    )\n  }, [containerBounds.height, footerHeight])\n\n  const footerMaxHeight = useMemo(() => {\n    return (\n      Math.floor(\n        (containerBounds.height -\n          (FORM_BODY_MIN_HEIGHT + 2 * FORM_BODY_MARGIN) -\n          headerHeight * UNIT_HEIGHT) /\n          UNIT_HEIGHT,\n      ) * UNIT_HEIGHT\n    )\n  }, [containerBounds.height, headerHeight])\n\n  const handleUpdateHeight = useCallback((_height: number) => {\n    // TODO: update height\n  }, [])\n\n  const canResizeCanvas = dynamicHeight !== \"fixed\"\n\n  const resizeTopHandler = useMemo(() => {\n    return {\n      bottom: (\n        <div css={resizeLineStyle}>\n          <ResizeBar css={resizeBarStyle} />\n        </div>\n      ),\n    }\n  }, [])\n\n  const resizeBottomHandler = useMemo(() => {\n    return {\n      top: (\n        <div css={resizeLineStyle}>\n          <ResizeBar css={resizeBarStyle} />\n        </div>\n      ),\n    }\n  }, [])\n\n  const handleResizeStart: ResizeStartCallback = (e) => {\n    e.preventDefault()\n    e.stopPropagation()\n    dispatch(\n      configActions.setResizingNodeIDsReducer([\n        `${displayName}-resize-form-header`,\n      ]),\n    )\n  }\n\n  const handleOnResizeTopStop: ResizeCallback = useCallback(\n    (e, dir, elementRef, delta) => {\n      const { height } = delta\n      let finalHeight = Math.floor(\n        (headerHeight * UNIT_HEIGHT + height) / UNIT_HEIGHT,\n      )\n      if (finalHeight * UNIT_HEIGHT >= headerMaxHeight) {\n        finalHeight = Math.floor(headerMaxHeight / UNIT_HEIGHT)\n      }\n      handleUpdateOriginalDSLMultiAttr({\n        headerHeight: finalHeight,\n      })\n      dispatch(configActions.setResizingNodeIDsReducer([]))\n    },\n    [dispatch, handleUpdateOriginalDSLMultiAttr, headerHeight, headerMaxHeight],\n  )\n\n  const handleOnResizeBottomStop: ResizeCallback = useCallback(\n    (e, dir, elementRef, delta) => {\n      const { height } = delta\n      let finalHeight = Math.floor(\n        (footerHeight * UNIT_HEIGHT + height) / UNIT_HEIGHT,\n      )\n      if (finalHeight * UNIT_HEIGHT > footerMaxHeight) {\n        finalHeight = Math.floor(footerMaxHeight / UNIT_HEIGHT)\n      }\n      handleUpdateOriginalDSLMultiAttr({\n        footerHeight: finalHeight,\n      })\n      dispatch(configActions.setResizingNodeIDsReducer([]))\n    },\n    [dispatch, footerHeight, footerMaxHeight, handleUpdateOriginalDSLMultiAttr],\n  )\n\n  const [{ isDraggingActive }, dropRef] = useDrop<\n    DragInfo,\n    DropResultInfo,\n    DragCollection\n  >(\n    () => ({\n      accept: [\"components\"],\n      hover: (dragInfo, monitor) => {\n        if (monitor.isOver({ shallow: true })) {\n        }\n      },\n      drop: (dropInfo) => {\n        const { draggedComponents } = dropInfo\n        const drageedDisplayNames = draggedComponents.map(\n          (component) => component.displayName,\n        )\n        if (disabled) {\n          const updateSlice = {\n            disabled: \"{{true}}\",\n          }\n          const MultiUpdateSlice = drageedDisplayNames.map((displayName) => {\n            return {\n              displayName,\n              updateSlice,\n            }\n          })\n          dispatch(\n            componentsActions.updateMultiComponentPropsReducer(\n              MultiUpdateSlice,\n            ),\n          )\n        }\n        return {\n          isDropOnCanvas: true,\n        }\n      },\n      collect: (monitor) => {\n        return {\n          isDraggingActive: monitor.isOver(),\n        }\n      },\n    }),\n    [disabled],\n  )\n\n  return (\n    <div\n      css={formContainerStyle}\n      ref={(node) => {\n        dropRef(node)\n        containerRef(node)\n        containerNodeRef.current = node\n      }}\n      onMouseEnter={() => {\n        setIsMouseHover(true)\n      }}\n      onMouseLeave={() => {\n        setIsMouseHover(false)\n      }}\n    >\n      {showHeader && (\n        <Resizable\n          size={{\n            width: \"100%\",\n            height: headerHeight * UNIT_HEIGHT,\n          }}\n          minHeight={headerMinHeight}\n          maxHeight={headerMaxHeight}\n          handleComponent={\n            isEditMode && isMouseHover && !isDraggingActive\n              ? resizeTopHandler\n              : undefined\n          }\n          enable={{\n            bottom: true,\n          }}\n          onResizeStart={handleResizeStart}\n          onResizeStop={handleOnResizeTopStop}\n        >\n          <div css={formHeaderStyle}>\n            <RenderChildrenCanvas\n              displayName={childrenNodeDisplayNames[0]}\n              columnNumber={columnNumber}\n              handleUpdateHeight={handleUpdateHeight}\n              canResizeCanvas={canResizeCanvas}\n              containerPadding={padding?.size}\n            />\n          </div>\n          {isMouseHover && !isDraggingActive && isEditMode && (\n            <div css={applyDashedLineStyle(false, true, false)} />\n          )}\n        </Resizable>\n      )}\n      <div css={formBodyStyle}>\n        <RenderChildrenCanvas\n          displayName={childrenNodeDisplayNames[1]}\n          columnNumber={columnNumber}\n          handleUpdateHeight={handleUpdateHeight}\n          canResizeCanvas={canResizeCanvas}\n          containerPadding={padding?.size}\n        />\n        {isMouseHover && !isDraggingActive && isEditMode && (\n          <div css={applyXDirectionDashedLineStyle(false, true, false)} />\n        )}\n      </div>\n      {showFooter && (\n        <Resizable\n          size={{\n            width: \"100%\",\n            height: footerHeight * UNIT_HEIGHT,\n          }}\n          minHeight={footerMinHeight}\n          maxHeight={footerMaxHeight}\n          handleComponent={\n            isEditMode && isMouseHover && !isDraggingActive\n              ? resizeBottomHandler\n              : undefined\n          }\n          enable={{\n            top: true,\n          }}\n          onResizeStart={handleResizeStart}\n          onResizeStop={handleOnResizeBottomStop}\n        >\n          <div css={formHeaderStyle}>\n            <RenderChildrenCanvas\n              displayName={childrenNodeDisplayNames[2]}\n              columnNumber={columnNumber}\n              handleUpdateHeight={handleUpdateHeight}\n              canResizeCanvas={canResizeCanvas}\n              containerPadding={padding?.size}\n            />\n          </div>\n          {isMouseHover && !isDraggingActive && isEditMode && (\n            <div\n              css={applyDashedLineStyle(false, true, false, footerMaxHeight)}\n            />\n          )}\n        </Resizable>\n      )}\n    </div>\n  )\n}\n\nFormWidget.displayName = \"FormWidget\"\nexport default FormWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/FormWidget/index.ts",
    "content": "export * from \"./panelConfig\"\nexport * from \"./widgetConfig\"\nexport * from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/FormWidget/interface.ts",
    "content": "import { PADDING_MODE } from \"@illa-public/public-types\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface FormWidgetProps extends BaseWidgetProps {\n  showFooter: boolean\n  showHeader: boolean\n  headerHeight: number\n  footerHeight: number\n  handleUpdateDsl: (value: Record<string, any>) => void\n  handleUpdateOriginalDSLMultiAttr: (updateSlice: Record<string, any>) => void\n  unitH: number\n  disabled: boolean\n  disabledSubmit: boolean\n  validateInputsOnSubmit: boolean\n  resetAfterSuccessful: boolean\n  columnNumber: number\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  formData?: Record<string, any>\n  padding?: {\n    size: string\n    mode: PADDING_MODE\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/FormWidget/panelConfig.tsx",
    "content": "import RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { FORM_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n\nconst baseWidgetName = \"form\"\nexport const FORM_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          FORM_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        placeholder: \"{{false}}\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled-submit`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disable_submit\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled_submit\"),\n        attrName: \"disabledSubmit\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n      {\n        id: `${baseWidgetName}-interaction-validate-input-on-submit`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.validate_inputs_on_submit\",\n        ),\n        attrName: \"validateInputsOnSubmit\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n      {\n        id: `${baseWidgetName}-interaction-reset-after-successful-submit`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.reset_after_successful_submit\",\n        ),\n        attrName: \"resetAfterSuccessful\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-show-header`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_header\"),\n        attrName: \"showHeader\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n      {\n        id: `${baseWidgetName}-layout-show-footer`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_footer\"),\n        attrName: \"showFooter\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        attrName: \"hidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-styles`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"border\",\n      },\n      {\n        id: `${baseWidgetName}-styles-color`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"border\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-background`,\n            labelName: i18n.t(\"editor.inspect.setter_label.background\"),\n            attrName: \"backgroundColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"#ffffffff\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            attrName: \"radius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n          {\n            id: `${baseWidgetName}-style-shadow`,\n            labelName: i18n.t(\"editor.inspect.setter_label.shadow.shadow\"),\n            attrName: \"shadow\",\n            setterType: \"SHADOW_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"small\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-padding`,\n        setterType: \"PADDING_INPUT_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_group.padding\"),\n        attrName: \"padding\",\n        useCustomLayout: true,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/FormWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const formContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  position: relative;\n  overflow: hidden;\n`\n\nexport const formHeaderStyle = css`\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n`\nexport const formBodyStyle = css`\n  width: 100%;\n  height: 100%;\n  min-height: 100px;\n  flex: 1;\n  overflow-y: auto;\n  position: relative;\n`\nexport const resizeLineStyle = css`\n  width: 100%;\n  height: 100%;\n  cursor: row-resize;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n\nexport const resizeBarStyle = css`\n  fill: ${globalColor(`--${illaPrefix}-white-01`)};\n  stroke: ${globalColor(`--${illaPrefix}-techPurple-03`)};\n  :hover {\n    fill: ${globalColor(`--${illaPrefix}-techPurple-03`)};\n    stroke: ${globalColor(`--${illaPrefix}-white-01`)};\n  }\n  :active {\n    fill: ${globalColor(`--${illaPrefix}-techPurple-03`)};\n    stroke: ${globalColor(`--${illaPrefix}-white-01`)};\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/FormWidget/widgetConfig.tsx",
    "content": "import { PADDING_MODE } from \"@illa-public/public-types\"\nimport { v4 } from \"uuid\"\nimport FormWidgetIcon from \"@/assets/widgetCover/form.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { BasicContainerConfig } from \"@/widgetLibrary/BasicContainer/BasicContainer\"\nimport { TEXT_WIDGET_CONFIG } from \"@/widgetLibrary/TextWidget\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\nimport { BUTTON_WIDGET_CONFIG } from \"../ButtonWidget\"\n\nexport const FORM_WIDGET_CONFIG: WidgetConfig = {\n  type: \"FORM_WIDGET\",\n  displayName: \"form\",\n  widgetName: i18n.t(\"widget.form.name\"),\n  keywords: [\"form\", \"表单\"],\n  icon: <FormWidgetIcon />,\n  sessionType: \"CONTAINER\",\n  w: 16,\n  h: 40,\n  version: 0,\n  childrenNode: [\n    {\n      ...BasicContainerConfig,\n      childrenNode: [\n        {\n          ...TEXT_WIDGET_CONFIG,\n          w: 10,\n          h: 5,\n          x: 0,\n          y: 0,\n          defaults: {\n            ...TEXT_WIDGET_CONFIG.defaults,\n            value: \"### Form\",\n          },\n        },\n      ],\n    },\n    BasicContainerConfig,\n    {\n      ...BasicContainerConfig,\n      childrenNode: [\n        {\n          ...BUTTON_WIDGET_CONFIG,\n          w: 8,\n          h: 5,\n          x: 24,\n          y: 0,\n          defaults: {\n            ...BUTTON_WIDGET_CONFIG.defaults,\n            text: \"Submit\",\n            events: [\n              {\n                actionType: \"widget\",\n                id: v4(),\n                eventType: \"click\",\n                widgetID: \"form\",\n                widgetMethod: \"submit\",\n              },\n            ],\n          },\n        },\n      ],\n    },\n  ],\n  defaults: {\n    showHeader: true,\n    showFooter: true,\n    validateInputsOnSubmit: true,\n    resetAfterSuccessful: true,\n    backgroundColor: \"#ffffffff\",\n    radius: \"4px\",\n    shadow: \"small\",\n    headerHeight: 11,\n    footerHeight: 7,\n    padding: {\n      mode: PADDING_MODE.ALL,\n      size: \"4\",\n    },\n  },\n}\n\nexport const FORM_BODY_MIN_HEIGHT = 100\nexport const FORM_MIN_FOOTER_HEIGHT_ROW_NUMBER = 7\nexport const FORM_MIN_HEADER_HEIGHT_ROW_NUMBER = 7\nexport const FORM_BODY_MARGIN = 7\n\nexport const FORM_CAN_BIND_WIDGET_TYPE = new Map([\n  [\"INPUT_WIDGET\", true],\n  [\"TEXTAREA_INPUT_WIDGET\", true],\n  [\"NUMBER_INPUT_WIDGET\", true],\n  [\"SELECT_WIDGET\", true],\n  [\"RADIO_BUTTON_WIDGET\", true],\n  [\"RADIO_GROUP_WIDGET\", true],\n  [\"CHECKBOX_GROUP_WIDGET\", true],\n  [\"DATE_RANGE_WIDGET\", true],\n  [\"DATE_TIME_WIDGET\", true],\n  [\"DATE_WIDGET\", true],\n  [\"RATE_WIDGET\", true],\n  [\"FORM_WIDGET\", true],\n  [\"UPLOAD_WIDGET\", true],\n  [\"MULTISELECT_WIDGET\", true],\n  [\"TIME_PICKER_WIDGET\", true],\n  [\"TIME_RANGE_WIDGET\", true],\n  [\"SWITCH_GROUP_WIDGET\", true],\n  [\"RECORDING_WIDGET\", true],\n  [\"EDITABLE_TEXT_WIDGET\", true],\n  [\"SIGNATURE_WIDGET\", true],\n])\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/components/CursorBasedSelector/index.tsx",
    "content": "import { FC } from \"react\"\nimport { NextIcon, PreviousIcon } from \"@illa-design/react\"\nimport { operationIconStyle, selectContainerStyle } from \"./style\"\n\ninterface CursorBasedSelectorProps {\n  hasNextPage?: boolean\n  page: number\n  previousCursor?: string\n  nextCursor?: string\n  onChange: (isNext: boolean) => void\n}\nconst CursorBasedSelector: FC<CursorBasedSelectorProps> = ({\n  hasNextPage,\n  page,\n  onChange,\n}) => {\n  return (\n    <div css={selectContainerStyle}>\n      <span css={operationIconStyle(page <= 0)} onClick={() => onChange(false)}>\n        <PreviousIcon size=\"14px\" />\n      </span>\n      {page + 1}\n      <span\n        css={operationIconStyle(!hasNextPage)}\n        onClick={() => hasNextPage && onChange(true)}\n      >\n        <NextIcon size=\"14px\" />\n      </span>\n    </div>\n  )\n}\n\nexport default CursorBasedSelector\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/components/CursorBasedSelector/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const selectContainerStyle = css`\n  width: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const operationIconStyle = (disabled: boolean) => {\n  return css`\n    pointer-events: ${disabled ? \"not-allowed\" : \"auto\"};\n    font-size: 14px;\n    width: 32px;\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    height: 32px;\n    border-radius: 4px;\n    cursor: ${disabled ? \"not-allowed\" : \"pointer\"};\n    color: ${getColor(\"grayBlue\", disabled ? \"08\" : \"03\")};\n    background-color: unset;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/components/ListWidgetWithAutoPagination/index.tsx",
    "content": "import { chunk } from \"lodash-es\"\nimport { Resizable, ResizeCallback, ResizeStartCallback } from \"re-resizable\"\nimport { FC, useCallback, useMemo, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport useMeasure from \"react-use-measure\"\nimport { Pagination } from \"@illa-design/react\"\nimport { LIST_ITEM_MARGIN_TOP } from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { applyDashedLineStyle } from \"@/page/App/components/ScaleSquare/style\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getShadowStyle } from \"@/utils/styleUtils/shadow\"\nimport RenderCopyContainer from \"@/widgetLibrary/GridListWidget/components/RenderCopyContainer\"\nimport RenderTemplateContainer from \"@/widgetLibrary/GridListWidget/components/RenderTemplateContainer\"\nimport {\n  COLUMN_NUM_ADAPTATION,\n  ListWidgetPropsWithChildrenNodes,\n} from \"@/widgetLibrary/GridListWidget/interface\"\nimport {\n  applyListItemStyle,\n  itemContainerStyle,\n  listParentContainerWithPagination,\n  paginationWrapperStyle,\n  selectStyle,\n} from \"@/widgetLibrary/GridListWidget/style\"\nimport { resizeBottomHandler } from \"@/widgetLibrary/GridListWidget/utils\"\n\nconst ListWidgetWithAutoPagination: FC<ListWidgetPropsWithChildrenNodes> = (\n  props,\n) => {\n  const {\n    dataSources,\n    itemHeight = 48,\n    displayName,\n    page = 0,\n    dynamicMinHeight,\n    dynamicMaxHeight,\n    enablePagination,\n    childrenNode,\n    itemGapX = LIST_ITEM_MARGIN_TOP,\n    itemGapY = LIST_ITEM_MARGIN_TOP,\n    itemShadow,\n    itemBorderColor,\n    itemBorderRadius,\n    itemBorderWidth,\n    columnNumAdaptation,\n    numberOfColumns = 3,\n    minColumnWidth,\n    handleUpdateOriginalDSLMultiAttr,\n    updateComponentHeight,\n    copyComponents,\n    pageSize,\n    handleUpdateSelectedItem,\n    itemBackGroundColor,\n    columnNumber,\n    dynamicHeight = \"fixed\",\n    selectIndexForMark,\n    themeColor,\n    loading,\n    handleUpdateMultiExecutionResult,\n    itemPadding,\n    h,\n  } = props\n\n  const [containerRef, containerBounds] = useMeasure()\n  const [paginationRef, paginationBounds] = useMeasure()\n  const [itemRef, itemBounds] = useMeasure()\n  const [isMouseHover, setIsMouseHover] = useState(false)\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const dispatch = useDispatch()\n  const safePageSize = !pageSize ? 0 : pageSize\n\n  const currentContainerBoundsHeight =\n    containerBounds.height - paginationBounds.height\n  const itemNumber = useMemo(() => {\n    if (enablePagination) {\n      return safePageSize\n    } else {\n      return dataSources?.length\n    }\n  }, [dataSources?.length, enablePagination, safePageSize])\n\n  const handleChangeCurrentPage = useCallback(\n    (pageNumber: number) => {\n      handleUpdateSelectedItem()\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            page: pageNumber - 1,\n          },\n        },\n      ])\n    },\n    [displayName, handleUpdateMultiExecutionResult, handleUpdateSelectedItem],\n  )\n\n  const currentData = useMemo(() => {\n    const chunkData = chunk(copyComponents, itemNumber)\n    if (chunkData.length === 0) return []\n    return page < chunkData.length ? chunkData[page] : chunkData[0]\n  }, [copyComponents, page, itemNumber])\n\n  const rowsNum = useMemo(() => {\n    if (\n      columnNumAdaptation === COLUMN_NUM_ADAPTATION.FIXED &&\n      !!numberOfColumns\n    ) {\n      return Math.ceil(currentData.length / numberOfColumns)\n    } else {\n      return Math.ceil(\n        currentData.length / (containerBounds.width / itemBounds.width),\n      )\n    }\n  }, [\n    columnNumAdaptation,\n    containerBounds.width,\n    currentData.length,\n    itemBounds.width,\n    numberOfColumns,\n  ])\n\n  const handleResizeStart: ResizeStartCallback = (e) => {\n    e.preventDefault()\n    e.stopPropagation()\n    dispatch(\n      configActions.setResizingNodeIDsReducer([`${displayName}-resize-grid`]),\n    )\n  }\n\n  const handleOnResizeTopStop: ResizeCallback = useCallback(\n    (e, dir, elementRef, delta) => {\n      const { height } = delta\n      let finalHeight = itemHeight + height\n      handleUpdateOriginalDSLMultiAttr({\n        itemHeight: finalHeight,\n      })\n      dispatch(configActions.setResizingNodeIDsReducer([]))\n    },\n    [dispatch, handleUpdateOriginalDSLMultiAttr, itemHeight],\n  )\n\n  const canShowBorder = isEditMode && isMouseHover\n\n  const shadowStyle = getShadowStyle(itemShadow)\n  const borderStyle = useMemo(() => {\n    let borderWidth, borderRadius\n    const borderWidthNum = itemBorderWidth?.match(/\\d+(\\.\\d+)?/g)\n    if (borderWidthNum) borderWidth = borderWidthNum?.join(\"\") + \"px\"\n    const radiusNum = itemBorderRadius?.match(/\\d+(\\.\\d+)?/g)\n    if (radiusNum) borderRadius = radiusNum?.join(\"\") + \"px\"\n    return `\n    border: ${\n      borderWidth ? `${borderWidth} solid ${itemBorderColor}` : \"unset\"\n    };\n      border-radius: ${borderRadius ?? \"unset\"}\n    `\n  }, [itemBorderColor, itemBorderRadius, itemBorderWidth])\n\n  return (\n    <div\n      css={listParentContainerWithPagination}\n      onMouseEnter={() => {\n        setIsMouseHover(true)\n      }}\n      onMouseLeave={() => {\n        setIsMouseHover(false)\n      }}\n      ref={containerRef}\n    >\n      <div\n        css={itemContainerStyle(\n          columnNumAdaptation!,\n          itemGapX,\n          itemGapY,\n          itemShadow,\n          numberOfColumns,\n          minColumnWidth,\n        )}\n      >\n        {(page == undefined || page === 0) && (\n          <Resizable\n            size={{\n              width: \"100%\",\n              height: itemHeight,\n            }}\n            key={childrenNode[0]}\n            bounds=\"parent\"\n            minHeight={48}\n            maxHeight={\n              dynamicHeight !== \"fixed\"\n                ? \"unset\"\n                : currentContainerBoundsHeight - 4\n            }\n            handleComponent={isMouseHover ? resizeBottomHandler() : undefined}\n            enable={\n              dynamicHeight !== \"fixed\" || loading\n                ? {}\n                : {\n                    bottom: true,\n                  }\n            }\n            onResizeStart={handleResizeStart}\n            onResizeStop={handleOnResizeTopStop}\n          >\n            <div\n              css={selectStyle(\n                selectIndexForMark === 0,\n                isEditMode,\n                themeColor,\n                itemBorderRadius,\n              )}\n            >\n              <div\n                css={applyListItemStyle(\n                  true,\n                  itemBackGroundColor,\n                  shadowStyle,\n                  borderStyle,\n                  isEditMode,\n                  loading,\n                )}\n                ref={itemRef}\n                onClick={(e) => {\n                  const isClickOnContainer = !!(\n                    e.target as HTMLElement\n                  )?.getAttribute(\"data-list-widget-container\")\n                  handleUpdateSelectedItem(0, isClickOnContainer)\n                }}\n              >\n                <RenderTemplateContainer\n                  templateComponentDisplayName={childrenNode[0]}\n                  templateContainerHeight={itemHeight}\n                  columnNumber={columnNumber}\n                  dynamicHeight={dynamicHeight}\n                  itemNumber={rowsNum}\n                  extraHeight={paginationBounds.height}\n                  itemShadow={itemShadow}\n                  enableAutoPagination={enablePagination}\n                  handleUpdateOriginalDSLMultiAttr={\n                    handleUpdateOriginalDSLMultiAttr\n                  }\n                  h={h}\n                  updateComponentHeight={updateComponentHeight}\n                  dynamicMinHeight={dynamicMinHeight}\n                  dynamicMaxHeight={dynamicMaxHeight}\n                  itemGap={itemGapY}\n                  itemPadding={itemPadding}\n                />\n              </div>\n            </div>\n            {canShowBorder && (\n              <div css={applyDashedLineStyle(false, true, false)} />\n            )}\n          </Resizable>\n        )}\n        {currentData.map((node, index) => {\n          if ((page == undefined || page === 0) && index === 0) {\n            return null\n          }\n          const step = page == undefined ? 0 : page\n          return (\n            <div\n              key={node.displayName}\n              css={selectStyle(\n                selectIndexForMark === index,\n                isEditMode,\n                themeColor,\n                itemBorderRadius,\n                itemHeight,\n              )}\n            >\n              <div\n                css={applyListItemStyle(\n                  false,\n                  itemBackGroundColor,\n                  shadowStyle,\n                  borderStyle,\n                  isEditMode,\n                  loading,\n                  itemHeight,\n                  itemPadding?.size,\n                )}\n                onClick={(e) => {\n                  const isClickOnContainer = !!(\n                    e.target as HTMLElement\n                  )?.getAttribute(\"data-list-widget-container\")\n                  handleUpdateSelectedItem(index, isClickOnContainer)\n                }}\n              >\n                <RenderCopyContainer\n                  templateComponentNodes={node}\n                  templateContainerHeight={itemHeight}\n                  columnNumber={columnNumber}\n                  displayNamePrefix={`grid-list-child-${\n                    step * itemNumber! + index\n                  }-`}\n                />\n              </div>\n            </div>\n          )\n        })}\n      </div>\n      {enablePagination && (\n        <div css={paginationWrapperStyle} ref={paginationRef}>\n          <Pagination\n            total={dataSources?.length}\n            current={page + 1}\n            pageSize={itemNumber}\n            disableSimplePageJump\n            size=\"medium\"\n            sizeCanChange={false}\n            hideOnSinglePage={false}\n            simple\n            onChange={handleChangeCurrentPage}\n          />\n        </div>\n      )}\n    </div>\n  )\n}\n\nexport default ListWidgetWithAutoPagination\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/components/ListWidgetWithServerPagination/index.tsx",
    "content": "import { isEqual } from \"lodash-es\"\nimport { Resizable, ResizeCallback, ResizeStartCallback } from \"re-resizable\"\nimport { FC, useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport useMeasure from \"react-use-measure\"\nimport { Pagination } from \"@illa-design/react\"\nimport { LIST_ITEM_MARGIN_TOP } from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { applyDashedLineStyle } from \"@/page/App/components/ScaleSquare/style\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getShadowStyle } from \"@/utils/styleUtils/shadow\"\nimport CursorBasedSelector from \"@/widgetLibrary/GridListWidget/components/CursorBasedSelector\"\nimport RenderCopyContainer from \"@/widgetLibrary/GridListWidget/components/RenderCopyContainer\"\nimport RenderTemplateContainer from \"@/widgetLibrary/GridListWidget/components/RenderTemplateContainer\"\nimport {\n  COLUMN_NUM_ADAPTATION,\n  ListWidgetPropsWithChildrenNodes,\n  PAGINATION_TYPE,\n} from \"@/widgetLibrary/GridListWidget/interface\"\nimport {\n  ListParentContainerWithScroll,\n  applyListItemStyle,\n  itemContainerStyle,\n  paginationWrapperStyle,\n  selectStyle,\n} from \"@/widgetLibrary/GridListWidget/style\"\nimport { resizeBottomHandler } from \"@/widgetLibrary/GridListWidget/utils\"\n\nconst ListWidgetWithServerPagination: FC<ListWidgetPropsWithChildrenNodes> = (\n  props,\n) => {\n  const {\n    itemHeight = 48,\n    handleUpdateOriginalDSLMultiAttr,\n    childrenNode,\n    copyComponents = [],\n    handleUpdateSelectedItem,\n    itemBackGroundColor,\n    columnNumber,\n    pageSize,\n    paginationType,\n    totalRowCount,\n    nextCursor,\n    previousCursor,\n    itemGapX = LIST_ITEM_MARGIN_TOP,\n    itemGapY = LIST_ITEM_MARGIN_TOP,\n    itemBorderColor,\n    itemBorderRadius,\n    itemBorderWidth,\n    itemShadow,\n    page = 1,\n    enableServerSidePagination,\n    dynamicHeight,\n    updateComponentHeight,\n    h,\n    dynamicMinHeight,\n    dynamicMaxHeight,\n    displayName,\n    columnNumAdaptation,\n    numberOfColumns = 3,\n    minColumnWidth,\n    disabled,\n    selectIndexForMark,\n    themeColor,\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n    enablePagination,\n    loading,\n    itemPadding,\n  } = props\n  const [containerRef, containerBounds] = useMeasure()\n  const [paginationRef, paginationBounds] = useMeasure()\n  const [itemRef, itemBounds] = useMeasure()\n  const [isMouseHover, setIsMouseHover] = useState(false)\n  const safePageSize = !pageSize ? 0 : pageSize\n\n  const currentContainerBoundsHeight =\n    containerBounds.height - paginationBounds.height\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const dispatch = useDispatch()\n\n  const propsRef = useRef(props)\n  const handleChangePage = useCallback(\n    (pageNumber: number) => {\n      if (pageNumber <= 0 || disabled) return\n      handleUpdateSelectedItem()\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              page: pageNumber - 1,\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"pageChange\")\n      })\n    },\n    [\n      disabled,\n      handleUpdateSelectedItem,\n      handleUpdateMultiExecutionResult,\n      displayName,\n      triggerEventHandler,\n    ],\n  )\n\n  const handleCursorBasedChangePage = useCallback(\n    (isNext: boolean) => {\n      if ((page <= 0 && !isNext) || disabled) return\n      handleUpdateSelectedItem()\n      let value: {\n        page: number\n        beforeCursor: string | undefined\n        afterCursor: string | undefined\n      }\n      if (isNext) {\n        value = {\n          page: page + 1,\n          beforeCursor: undefined,\n          afterCursor: nextCursor,\n        }\n      } else {\n        value = {\n          page: page - 1,\n          beforeCursor: previousCursor,\n          afterCursor: undefined,\n        }\n      }\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value,\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"pageChange\")\n      })\n    },\n    [\n      disabled,\n      displayName,\n      handleUpdateMultiExecutionResult,\n      handleUpdateSelectedItem,\n      nextCursor,\n      page,\n      previousCursor,\n      triggerEventHandler,\n    ],\n  )\n\n  useEffect(() => {\n    if (!isEqual(propsRef.current, props)) {\n      propsRef.current = props\n    }\n  }, [props])\n\n  const handleResizeStart: ResizeStartCallback = (e) => {\n    e.preventDefault()\n    e.stopPropagation()\n    dispatch(\n      configActions.setResizingNodeIDsReducer([\n        `${displayName}-resize-list-item`,\n      ]),\n    )\n  }\n\n  const handleOnResizeTopStop: ResizeCallback = useCallback(\n    (e, dir, elementRef, delta) => {\n      let finalHeight = itemHeight + delta.height\n      handleUpdateOriginalDSLMultiAttr({\n        itemHeight: finalHeight,\n      })\n      dispatch(configActions.setResizingNodeIDsReducer([]))\n    },\n    [dispatch, handleUpdateOriginalDSLMultiAttr, itemHeight],\n  )\n\n  const canShowBorder = isEditMode && isMouseHover\n\n  const shadowStyle = getShadowStyle(itemShadow)\n  const borderStyle = useMemo(() => {\n    let borderWidth, borderRadius\n    const borderWidthNum = itemBorderWidth?.match(/\\d+(\\.\\d+)?/g)\n    if (borderWidthNum) borderWidth = borderWidthNum?.join(\"\") + \"px\"\n    const radiusNum = itemBorderRadius?.match(/\\d+(\\.\\d+)?/g)\n    if (radiusNum) borderRadius = radiusNum?.join(\"\") + \"px\"\n    return `\n    border: ${\n      borderWidth ? `${borderWidth} solid ${itemBorderColor}` : \"unset\"\n    };\n      border-radius: ${borderRadius ?? \"unset\"}\n    `\n  }, [itemBorderColor, itemBorderRadius, itemBorderWidth])\n\n  const rowsNum = useMemo(() => {\n    const rows =\n      safePageSize > (copyComponents?.length ?? 0)\n        ? copyComponents?.length ?? 0\n        : safePageSize\n    if (\n      columnNumAdaptation === COLUMN_NUM_ADAPTATION.FIXED &&\n      !!numberOfColumns\n    ) {\n      return Math.ceil(rows / numberOfColumns)\n    } else {\n      return Math.ceil(rows / (containerBounds.width / itemBounds.width))\n    }\n  }, [\n    columnNumAdaptation,\n    containerBounds.width,\n    itemBounds.width,\n    numberOfColumns,\n    safePageSize,\n    copyComponents?.length,\n  ])\n\n  useEffect(() => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          offset: safePageSize * page,\n        },\n      },\n    ])\n  }, [displayName, handleUpdateMultiExecutionResult, page, safePageSize])\n\n  return (\n    <div\n      css={ListParentContainerWithScroll}\n      ref={containerRef}\n      onMouseEnter={() => {\n        setIsMouseHover(true)\n      }}\n      onMouseLeave={() => {\n        setIsMouseHover(false)\n      }}\n    >\n      <div\n        css={itemContainerStyle(\n          columnNumAdaptation!,\n          itemGapX,\n          itemGapY,\n          itemShadow,\n          numberOfColumns,\n          minColumnWidth,\n        )}\n      >\n        <Resizable\n          size={{\n            width: \"100%\",\n            height: itemHeight,\n          }}\n          bounds=\"parent\"\n          minHeight={48}\n          maxHeight={\n            dynamicHeight !== \"fixed\"\n              ? \"unset\"\n              : currentContainerBoundsHeight - 4\n          }\n          handleComponent={isMouseHover ? resizeBottomHandler() : undefined}\n          enable={\n            dynamicHeight !== \"fixed\" || loading\n              ? {}\n              : {\n                  bottom: true,\n                }\n          }\n          onResizeStart={handleResizeStart}\n          onResizeStop={handleOnResizeTopStop}\n        >\n          <div\n            css={selectStyle(\n              selectIndexForMark === 0,\n              isEditMode,\n              themeColor,\n              itemBorderRadius,\n            )}\n          >\n            <div\n              css={applyListItemStyle(\n                true,\n                itemBackGroundColor,\n                shadowStyle,\n                borderStyle,\n                isEditMode,\n                loading,\n              )}\n              onClick={(e) => {\n                const isClickOnContainer = !!(\n                  e.target as HTMLElement\n                )?.getAttribute(\"data-list-widget-container\")\n\n                handleUpdateSelectedItem(0, isClickOnContainer)\n              }}\n            >\n              <RenderTemplateContainer\n                templateComponentDisplayName={childrenNode[0]}\n                templateContainerHeight={itemHeight}\n                columnNumber={columnNumber}\n                dynamicHeight={dynamicHeight}\n                extraHeight={paginationBounds.height}\n                itemShadow={itemShadow}\n                enableAutoPagination={enablePagination}\n                handleUpdateOriginalDSLMultiAttr={\n                  handleUpdateOriginalDSLMultiAttr\n                }\n                itemNumber={rowsNum}\n                updateComponentHeight={updateComponentHeight}\n                h={h}\n                dynamicMinHeight={dynamicMinHeight}\n                dynamicMaxHeight={dynamicMaxHeight}\n                itemGap={itemGapY}\n                itemPadding={itemPadding}\n              />\n            </div>\n          </div>\n\n          {canShowBorder && (\n            <div css={applyDashedLineStyle(false, true, false)} />\n          )}\n        </Resizable>\n        {copyComponents?.map((node, index) => {\n          if (index === 0) return null\n          return (\n            <div\n              key={node.displayName}\n              css={selectStyle(\n                selectIndexForMark === index,\n                isEditMode,\n                themeColor,\n                itemBorderRadius,\n                itemHeight,\n              )}\n            >\n              <div\n                css={applyListItemStyle(\n                  false,\n                  itemBackGroundColor,\n                  shadowStyle,\n                  borderStyle,\n                  isEditMode,\n                  loading,\n                  itemHeight,\n                  itemPadding?.size,\n                )}\n                ref={itemRef}\n                onClick={(e) => {\n                  const isClickOnContainer = !!(\n                    e.target as HTMLElement\n                  )?.getAttribute(\"data-list-widget-container\")\n                  handleUpdateSelectedItem(index, isClickOnContainer)\n                }}\n              >\n                <RenderCopyContainer\n                  templateComponentNodes={node}\n                  templateContainerHeight={itemHeight}\n                  columnNumber={columnNumber}\n                  displayNamePrefix={`grid-list-child-${index}-`}\n                />\n              </div>\n            </div>\n          )\n        })}\n      </div>\n      {enablePagination && enableServerSidePagination && (\n        <div css={paginationWrapperStyle} ref={paginationRef}>\n          {paginationType === PAGINATION_TYPE.LIMIT_OFFSET_BASED ? (\n            <Pagination\n              total={totalRowCount ?? 1}\n              current={page + 1 ?? 1}\n              pageSize={safePageSize}\n              size=\"medium\"\n              disableSimplePageJump\n              sizeCanChange={false}\n              hideOnSinglePage={false}\n              simple\n              onChange={handleChangePage}\n            />\n          ) : (\n            <CursorBasedSelector\n              page={page}\n              hasNextPage={props.hasNextPage}\n              onChange={handleCursorBasedChangePage}\n            />\n          )}\n        </div>\n      )}\n    </div>\n  )\n}\n\nexport default ListWidgetWithServerPagination\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/components/Loading/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { ComponentLoadingStyle } from \"./style\"\n\nexport const ComponentLoading: FC<{ themeColor?: string }> = ({\n  themeColor,\n}) => {\n  return (\n    <div css={ComponentLoadingStyle}>\n      <Loading colorScheme={themeColor} />\n    </div>\n  )\n}\n\nComponentLoading.displayName = \"ComponentLoading\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/components/Loading/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const ComponentLoadingStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  background-color: ${getColor(\"white\", \"03\")};\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/components/RenderCopyContainer/index.tsx",
    "content": "import { FC } from \"react\"\nimport { RenderComponentCanvasWithJson } from \"@/page/App/components/DotPanel/components/Canvas/renderComponentCanvasContainerWithJson\"\nimport { RenderCopyContainerProps } from \"@/widgetLibrary/GridListWidget/interface\"\n\nconst RenderCopyContainer: FC<RenderCopyContainerProps> = (props) => {\n  const {\n    templateComponentNodes,\n    templateContainerHeight: _templateContainerHeight,\n    columnNumber,\n    displayNamePrefix,\n  } = props\n  return templateComponentNodes ? (\n    <RenderComponentCanvasWithJson\n      componentNode={templateComponentNodes}\n      containerPadding={0}\n      columnNumber={columnNumber}\n      displayNamePrefix={displayNamePrefix}\n    />\n  ) : null\n}\n\nexport default RenderCopyContainer\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/components/RenderTemplateContainer/index.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport {\n  LIST_ITEM_MARGIN_TOP,\n  WIDGET_SCALE_SQUARE_BORDER_WIDTH,\n} from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { RenderTemplateContainerProps } from \"@/widgetLibrary/GridListWidget/interface\"\nimport RenderChildrenCanvas from \"@/widgetLibrary/PublicSector/RenderChildrenCanvas\"\nimport { getGapByShadow } from \"../../utils\"\n\nconst RenderTemplateContainer: FC<RenderTemplateContainerProps> = (props) => {\n  const {\n    templateComponentDisplayName,\n    columnNumber,\n    itemGap = LIST_ITEM_MARGIN_TOP,\n    dynamicHeight,\n    extraHeight = 0,\n    templateContainerHeight,\n    handleUpdateOriginalDSLMultiAttr,\n    updateComponentHeight,\n    itemNumber = 1,\n    enableAutoPagination,\n    itemShadow,\n    itemPadding,\n  } = props\n  const enableAutoHeight = dynamicHeight !== \"fixed\"\n\n  const handleUpdateHeight = useCallback(\n    (height: number) => {\n      if (!updateComponentHeight) return\n      if (\n        height + 2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH !==\n        templateContainerHeight\n      ) {\n        handleUpdateOriginalDSLMultiAttr(\n          {\n            itemHeight: height + 2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH,\n          },\n          true,\n        )\n      }\n\n      // height + pagination height + pagination gap + every item height\n      let componentHeight: number\n      let gap = itemGap >= 0 ? itemGap : LIST_ITEM_MARGIN_TOP\n      if (enableAutoPagination) {\n        componentHeight =\n          height +\n          extraHeight +\n          LIST_ITEM_MARGIN_TOP +\n          2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH +\n          (height + 2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH + gap) *\n            (itemNumber - 1) +\n          getGapByShadow(itemShadow) * 2\n      } else {\n        componentHeight =\n          height +\n          2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH +\n          (height + 2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH + gap) *\n            (itemNumber - 1) +\n          getGapByShadow(itemShadow) * 2\n      }\n      updateComponentHeight(componentHeight)\n    },\n    [\n      handleUpdateOriginalDSLMultiAttr,\n      itemNumber,\n      templateContainerHeight,\n      updateComponentHeight,\n      extraHeight,\n      enableAutoPagination,\n      itemGap,\n      itemShadow,\n    ],\n  )\n\n  return (\n    <RenderChildrenCanvas\n      displayName={templateComponentDisplayName}\n      columnNumber={columnNumber}\n      handleUpdateHeight={handleUpdateHeight}\n      canResizeCanvas={enableAutoHeight}\n      containerPadding={itemPadding?.size}\n    />\n  )\n}\n\nexport default RenderTemplateContainer\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/constants.ts",
    "content": "export const DEFAULT_LIST = [\n  {\n    name: \"Yank Vanin\",\n    photo:\n      \"https://images.pexels.com/photos/1181424/pexels-photo-1181424.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Willey Swatridge\",\n    photo:\n      \"https://images.pexels.com/photos/2853592/pexels-photo-2853592.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Piper Whisker\",\n    photo:\n      \"https://images.pexels.com/photos/1181690/pexels-photo-1181690.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Sargent Boswell\",\n    photo:\n      \"https://images.pexels.com/photos/1586973/pexels-photo-1586973.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Anita Mordy\",\n    photo:\n      \"https://images.pexels.com/photos/1181391/pexels-photo-1181391.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Domini Queree\",\n    photo:\n      \"https://images.pexels.com/photos/826349/pexels-photo-826349.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Hunter Dossett\",\n    photo:\n      \"https://images.pexels.com/photos/3769021/pexels-photo-3769021.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Phylis Bonass\",\n    photo:\n      \"https://images.pexels.com/photos/806835/pexels-photo-806835.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Lyndsey Bransom\",\n    photo:\n      \"https://images.pexels.com/photos/920382/pexels-photo-920382.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Pepi Peter\",\n    photo:\n      \"https://images.pexels.com/photos/1586996/pexels-photo-1586996.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Way Guy\",\n    photo:\n      \"https://images.pexels.com/photos/785667/pexels-photo-785667.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Karalee Coton\",\n    photo:\n      \"https://images.pexels.com/photos/914931/pexels-photo-914931.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Daniele Adamik\",\n    photo:\n      \"https://images.pexels.com/photos/1024403/pexels-photo-1024403.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n    title: \"🧑‍💻 Customer Success Team Lead\",\n  },\n  {\n    name: \"Auria Archer\",\n    photo:\n      \"https://images.pexels.com/photos/1181414/pexels-photo-1181414.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Caesar Jakubowsky\",\n    photo:\n      \"https://images.pexels.com/photos/834863/pexels-photo-834863.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Noelle Loache\",\n    photo:\n      \"https://images.pexels.com/photos/3756679/pexels-photo-3756679.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Benedetta Warbrick\",\n    photo:\n      \"https://images.pexels.com/photos/32976/pexels-photo.jpg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Lyndsey Pycock\",\n    photo:\n      \"https://images.pexels.com/photos/3184608/pexels-photo-3184608.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Stuart Eymer\",\n    photo:\n      \"https://images.pexels.com/photos/1181695/pexels-photo-1181695.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Mar Rogeon\",\n    photo:\n      \"https://images.pexels.com/photos/50855/pexels-photo-50855.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Tom Warbrick\",\n    photo:\n      \"https://images.pexels.com/photos/789822/pexels-photo-789822.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Fabien Aitken\",\n    photo:\n      \"https://images.pexels.com/photos/1181678/pexels-photo-1181678.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Kipp Fendt\",\n    photo:\n      \"https://images.pexels.com/photos/1181293/pexels-photo-1181293.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Guillermo Anten\",\n    photo:\n      \"https://images.pexels.com/photos/7647990/pexels-photo-7647990.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Micah McLeod\",\n    photo:\n      \"https://images.pexels.com/photos/2955376/pexels-photo-2955376.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Ivar Filon\",\n    photo:\n      \"https://images.pexels.com/photos/7648004/pexels-photo-7648004.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Micah Bohey\",\n    photo:\n      \"https://images.pexels.com/photos/7647992/pexels-photo-7647992.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Georgianne Guy\",\n    photo:\n      \"https://images.pexels.com/photos/8145344/pexels-photo-8145344.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Tom Raffels\",\n    photo:\n      \"https://images.pexels.com/photos/8134106/pexels-photo-8134106.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Annadiana Brockman\",\n    photo:\n      \"https://images.pexels.com/photos/7644155/pexels-photo-7644155.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const GRID_LIST_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.clickItem\",\n      ),\n      value: \"clickItem\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onPaginationModelChange\",\n      ),\n      value: \"pageChange\",\n    },\n  ],\n  methods: [],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/gridList.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { klona } from \"klona\"\nimport { get, isEqual, set, toPath } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getComponentMap } from \"@/redux/currentApp/components/componentsSelector\"\nimport {\n  getExecutionResult,\n  getRawTree,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { evaluateDynamicString } from \"@/utils/evaluateDynamicString\"\nimport { getObjectPaths } from \"@/utils/executionTreeHelper/utils\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport { VALIDATION_TYPES, validationFactory } from \"@/utils/validationFactory\"\nimport ListWidgetWithAutoPagination from \"./components/ListWidgetWithAutoPagination\"\nimport ListWidgetWithServerPagination from \"./components/ListWidgetWithServerPagination\"\nimport { ComponentLoading } from \"./components/Loading\"\nimport { GridListWidgetProps } from \"./interface\"\n\nexport const GridListWidget: FC<GridListWidgetProps> = (props) => {\n  const {\n    displayName,\n    dataSources,\n    childrenNode,\n    enableServerSidePagination,\n    paginationType,\n    enablePagination,\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n    disabled,\n    loading,\n    themeColor,\n    page = 1,\n    pageSize = 10,\n  } = props\n\n  const executionResult = useSelector(getExecutionResult)\n  const rawTree = useSelector(getRawTree)\n  const components = useSelector(getComponentMap)\n  const prevDataSourcesRef = useRef(dataSources)\n  const [selectIndexForMark, setSelectIndexForMark] = useState<\n    undefined | number\n  >()\n\n  const updateTemplateContainerNodesProps = useCallback(\n    (childrenNodeDisplayNames: string[]) => {\n      return childrenNodeDisplayNames.map((itemContainerDisplayName, index) => {\n        const currentItemContainer = klona(components[itemContainerDisplayName])\n        const currentItemDisplayNames = currentItemContainer.childrenNode\n        if (\n          Array.isArray(currentItemDisplayNames) &&\n          currentItemDisplayNames.length > 0\n        ) {\n          let newCurrentItems = currentItemDisplayNames.map(\n            (currentItemDisplayName) => {\n              const currentItem = JSON.parse(\n                JSON.stringify(components[currentItemDisplayName]),\n              ) as ComponentTreeNode\n              if (\n                currentItem.props &&\n                Array.isArray(currentItem.props.$dynamicAttrPaths)\n              ) {\n                const { displayName } = currentItem\n                const { $dynamicAttrPaths } = currentItem.props\n                $dynamicAttrPaths.forEach((path) => {\n                  const finalPath = convertPathToString(toPath(path))\n                  const requireEvalString = get(\n                    currentItem.props,\n                    finalPath,\n                    \"\",\n                  )\n                  let evalResult: unknown\n                  try {\n                    evalResult = evaluateDynamicString(\n                      \"\",\n                      requireEvalString,\n                      executionResult,\n                    )\n                  } catch (e) {\n                    console.log(e)\n                    evalResult = \"\"\n                  }\n                  let value = evalResult\n                  if (Array.isArray(evalResult) && evalResult.length > index) {\n                    const rawWidget = rawTree[displayName]\n                    if (rawWidget && isObject(rawWidget.$validationPaths)) {\n                      const validationPaths = rawWidget.$validationPaths\n                      const validationType = get(validationPaths, finalPath)\n                      if (validationType === VALIDATION_TYPES.ARRAY) {\n                        if (Array.isArray(evalResult)) {\n                          const needSetValue = evalResult[index] ?? []\n                          const validationFunc =\n                            validationFactory[validationType]\n                          const res = validationFunc?.(needSetValue, \"\")\n                          value = res?.safeValue ?? needSetValue\n                        } else {\n                          const validationFunc =\n                            validationFactory[validationType]\n                          const res = validationFunc?.(evalResult, \"\")\n                          value = res?.safeValue ?? evalResult\n                        }\n                      } else {\n                        value = evalResult[index]\n                        const validationFunc = validationFactory[validationType]\n                        const res = validationFunc?.(value, \"\")\n                        value = res?.safeValue ?? value\n                      }\n                    }\n                  }\n                  set(currentItem, `props.${finalPath}`, value)\n                })\n              }\n              if (index !== 0) {\n                set(\n                  currentItem,\n                  \"displayName\",\n                  `grid-list-child-${index}-${currentItemDisplayName}`,\n                )\n                if (disabled != undefined) {\n                  set(currentItem, \"props.disabled\", disabled)\n                }\n              }\n              return currentItem\n            },\n          )\n          newCurrentItems = newCurrentItems.map((item) => {\n            const displayName = item.displayName\n            const displayNameArray = displayName.split(\"-\")\n            const realDisplayName = displayNameArray.at(-1)\n            const rawWidget = rawTree[realDisplayName as string]\n            const validationPaths = rawWidget.$validationPaths\n            if (isObject(validationPaths)) {\n              getObjectPaths(validationPaths).forEach((path) => {\n                const validationType = validationPaths[path] as VALIDATION_TYPES\n                const validationFunc = validationFactory[validationType]\n                const currentValue = get(item, `props.${path}`, \"\")\n                const res = validationFunc?.(currentValue, \"\")\n                set(item, `props.${path}`, res?.safeValue)\n              })\n            }\n            return item\n          })\n          set(currentItemContainer, \"childrenNode\", newCurrentItems)\n        }\n        if (index !== 0) {\n          set(\n            currentItemContainer,\n            \"displayName\",\n            `grid-list-widget-container-${index}`,\n          )\n        }\n        return currentItemContainer as unknown as ComponentTreeNode\n      })\n    },\n    [components, disabled, executionResult, rawTree],\n  )\n\n  const transTemplateContainerNodes = useCallback(\n    (templateContainerDisplayName: string) => {\n      const canvasChildrenDisplayNames: string[] = []\n      if (Array.isArray(dataSources) && dataSources.length > 0) {\n        dataSources.forEach((v, index) => {\n          canvasChildrenDisplayNames[index] = templateContainerDisplayName\n        })\n        return updateTemplateContainerNodesProps(canvasChildrenDisplayNames)\n      } else {\n        return updateTemplateContainerNodesProps([templateContainerDisplayName])\n      }\n    },\n    [dataSources, updateTemplateContainerNodesProps],\n  )\n\n  const getChildrenNodes = useMemo(() => {\n    if (childrenNode && childrenNode.length > 0 && dataSources) {\n      let canvasDisplayName = childrenNode[0]\n      return transTemplateContainerNodes(canvasDisplayName)\n    }\n    return null\n  }, [childrenNode, dataSources, transTemplateContainerNodes])\n\n  const handleUpdateSelectedItem = useCallback(\n    (index?: number, isContainerClick?: boolean) => {\n      if (!Array.isArray(dataSources) || disabled) return\n      if (\n        (selectIndexForMark === index && isContainerClick) ||\n        index === undefined\n      ) {\n        setSelectIndexForMark(undefined)\n      } else {\n        setSelectIndexForMark(index)\n      }\n      new Promise((resolve) => {\n        let value\n        if (\n          index === undefined ||\n          (selectIndexForMark === index && isContainerClick)\n        ) {\n          value = {\n            selectedItem: undefined,\n            selectedIndex: undefined,\n          }\n        } else {\n          const selectItemIndex = enableServerSidePagination\n            ? index\n            : index + page * (pageSize ?? 0)\n          value = {\n            selectedItem: dataSources[selectItemIndex],\n            selectedIndex: index,\n          }\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value,\n          },\n        ])\n        resolve(value)\n      }).then(() => {\n        triggerEventHandler(\"clickItem\")\n      })\n    },\n    [\n      dataSources,\n      disabled,\n      displayName,\n      enableServerSidePagination,\n      handleUpdateMultiExecutionResult,\n      page,\n      pageSize,\n      selectIndexForMark,\n      triggerEventHandler,\n    ],\n  )\n\n  useEffect(() => {\n    if (!isEqual(prevDataSourcesRef.current, dataSources)) {\n      handleUpdateMultiExecutionResult?.([\n        {\n          displayName,\n          value: {\n            selectedIndex: undefined,\n            selectedItem: undefined,\n          },\n        },\n      ])\n    }\n  }, [dataSources, displayName, handleUpdateMultiExecutionResult])\n\n  useEffect(() => {\n    handleUpdateMultiExecutionResult?.([\n      {\n        displayName,\n        value: {\n          page: 0,\n        },\n      },\n    ])\n  }, [\n    displayName,\n    handleUpdateMultiExecutionResult,\n    paginationType,\n    enablePagination,\n    enableServerSidePagination,\n  ])\n\n  return (\n    <>\n      {enableServerSidePagination ? (\n        <ListWidgetWithServerPagination\n          {...props}\n          copyComponents={getChildrenNodes}\n          handleUpdateSelectedItem={handleUpdateSelectedItem}\n          selectIndexForMark={selectIndexForMark}\n        />\n      ) : (\n        <ListWidgetWithAutoPagination\n          {...props}\n          copyComponents={getChildrenNodes}\n          handleUpdateSelectedItem={handleUpdateSelectedItem}\n          selectIndexForMark={selectIndexForMark}\n        />\n      )}\n      {loading && <ComponentLoading themeColor={themeColor} />}\n    </>\n  )\n}\n\nexport default GridListWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/index.tsx",
    "content": "export * from \"./widgetConfig\"\nexport * from \"./panelConfig\"\nexport * from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/interface.ts",
    "content": "import { ComponentTreeNode, PADDING_MODE } from \"@illa-public/public-types\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport enum PAGINATION_TYPE {\n  LIMIT_OFFSET_BASED = \"limitOffsetBased\",\n  CURSOR_BASED = \"cursorBased\",\n}\n\nexport enum COLUMN_NUM_ADAPTATION {\n  FIXED = \"fixed\",\n  DYNAMIC = \"dynamic\",\n}\n\ntype ItemPadding = {\n  size: string\n  mode: PADDING_MODE\n}\n\nexport type ShadowOptions = \"none\" | \"small\" | \"medium\" | \"large\"\nexport interface GridListWidgetProps extends BaseWidgetProps {\n  dataSources?: Array<unknown>\n  enablePagination?: boolean\n  enableServerSidePagination?: boolean\n  paginationType?: PAGINATION_TYPE\n  page?: number\n  pageSize?: number\n  previousCursor?: string\n  nextCursor?: string\n  hasNextPage?: boolean\n  totalRowCount?: number\n  itemGapX?: number\n  itemGapY?: number\n  itemHeight: number\n  currentPage: number\n  itemBackGroundColor: string\n  itemBorderWidth?: string\n  itemBorderColor?: string\n  itemBorderRadius?: string\n  itemShadow?: ShadowOptions\n  disabled: boolean\n  columnNumber: number\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  h: number\n  dynamicMinHeight?: number\n  dynamicMaxHeight?: number\n  columnNumAdaptation?: COLUMN_NUM_ADAPTATION\n  numberOfColumns?: number\n  minColumnWidth?: number\n  themeColor?: string\n  loading?: boolean\n  itemPadding?: ItemPadding\n}\n\nexport interface RenderTemplateContainerProps {\n  templateComponentDisplayName: string\n  templateContainerHeight: number\n  columnNumber: number\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  handleUpdateOriginalDSLMultiAttr: BaseWidgetProps[\"handleUpdateOriginalDSLMultiAttr\"]\n  updateComponentHeight?: (newHeight: number) => void\n  itemNumber?: number\n  h: number\n  dynamicMinHeight?: number\n  dynamicMaxHeight?: number\n  extraHeight?: number\n  itemGap?: number\n  enableAutoPagination?: boolean\n  itemShadow?: ShadowOptions\n  itemPadding?: ItemPadding\n}\n\nexport interface RenderCopyContainerProps {\n  templateComponentNodes: ComponentTreeNode\n  templateContainerHeight: number\n  columnNumber: number\n  displayNamePrefix: string\n  itemPadding?: ItemPadding\n}\n\nexport interface ListWidgetPropsWithChildrenNodes extends GridListWidgetProps {\n  copyComponents: ComponentTreeNode[] | null\n  handleUpdateSelectedItem: (index?: number, isContainerClick?: boolean) => void\n  selectIndexForMark?: number\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/panelConfig.tsx",
    "content": "import RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport ColumnAutoIcon from \"@/assets/rightPagePanel/gridList/columnAuto.svg?react\"\nimport ColumnFixedIcon from \"@/assets/rightPagePanel/gridList/columnFixed.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { LIST_ITEM_MARGIN_TOP } from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { GRID_LIST_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/GridListWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { COLUMN_NUM_ADAPTATION, PAGINATION_TYPE } from \"./interface\"\nimport { radioButtonOptionItemStyle } from \"./style\"\n\nconst baseWidgetName = \"gridList\"\nexport const GRID_LIST_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-data`,\n    groupName: i18n.t(\"editor.inspect.setter_group.data\"),\n    children: [\n      {\n        id: `${baseWidgetName}-data-source`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          GRID_LIST_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-loading`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n        attrName: \"loading\",\n        placeholder: \"{{false}}\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-PAGINATION`,\n    groupName: i18n.t(\"editor.inspect.setter_group.pagination\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-enable_pagination`,\n        labelName: i18n.t(\"editor.inspect.setter_label.enable_pagination\"),\n        attrName: \"enablePagination\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        useCustomLayout: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-enableServerSidePagination`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.table.enable_server_side_p\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.table.enable_server_side_p\",\n        ),\n        attrName: \"enableServerSidePagination\",\n        bindAttrName: [\"enablePagination\"],\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        shown: (v) => v,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-column-paginationType`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.pagination_type\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.pagination_type\"),\n        attrName: \"paginationType\",\n        setterType: \"SEARCH_SELECT_SETTER\",\n        isSetterSingleRow: true,\n        bindAttrName: [\"enablePagination\", \"enableServerSidePagination\"],\n        shown: (enablePagination, enableServerSidePagination) =>\n          enablePagination && enableServerSidePagination,\n        defaultValue: PAGINATION_TYPE.LIMIT_OFFSET_BASED,\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.table.limit_offset_based\",\n            ),\n            value: PAGINATION_TYPE.LIMIT_OFFSET_BASED,\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.table.cursor_based\"),\n            value: PAGINATION_TYPE.CURSOR_BASED,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-totalRowCount`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.total_row_count\"),\n        attrName: \"totalRowCount\",\n        setterType: \"INPUT_SETTER\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\n          \"enablePagination\",\n          \"enableServerSidePagination\",\n          \"paginationType\",\n        ],\n        shown: (\n          enablePagination,\n          enableServerSidePagination,\n          paginationType,\n        ) => {\n          return (\n            enablePagination &&\n            enableServerSidePagination &&\n            paginationType === PAGINATION_TYPE.LIMIT_OFFSET_BASED\n          )\n        },\n      },\n      {\n        id: `${baseWidgetName}-basic-previousCursor`,\n        labelName: i18n.t(\"editor.inspect.setter_label.previous_cursor\"),\n        attrName: \"previousCursor\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        bindAttrName: [\n          \"enablePagination\",\n          \"enableServerSidePagination\",\n          \"paginationType\",\n        ],\n        shown: (enablePagination, enableServerSidePagination, paginationType) =>\n          enablePagination &&\n          enableServerSidePagination &&\n          paginationType === \"cursorBased\",\n      },\n      {\n        id: `${baseWidgetName}-basic-nextCursor`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.next_cursor\"),\n        attrName: \"nextCursor\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        bindAttrName: [\n          \"enablePagination\",\n          \"enableServerSidePagination\",\n          \"paginationType\",\n        ],\n        shown: (enablePagination, enableServerSidePagination, paginationType) =>\n          enablePagination &&\n          enableServerSidePagination &&\n          paginationType === \"cursorBased\",\n      },\n      {\n        id: `${baseWidgetName}-basic-hasNextPage`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.has_next_page\"),\n        attrName: \"hasNextPage\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\n          \"enablePagination\",\n          \"enableServerSidePagination\",\n          \"paginationType\",\n        ],\n        shown: (enablePagination, enableServerSidePagination, paginationType) =>\n          enablePagination &&\n          enableServerSidePagination &&\n          paginationType === \"cursorBased\",\n      },\n      {\n        id: `${baseWidgetName}-basic-pageSize`,\n        labelName: i18n.t(\"editor.inspect.setter_label.pageSize\"),\n        attrName: \"pageSize\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"enablePagination\"],\n        shown: (v) => v,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-Column_num_adaptation`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.grid_list.column_adaptation\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.grid_list.column_adaptation\",\n        ),\n        attrName: \"columnNumAdaptation\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        isSetterSingleRow: true,\n        defaultValue: COLUMN_NUM_ADAPTATION.FIXED,\n        options: [\n          {\n            label: (\n              <span css={radioButtonOptionItemStyle}>\n                <ColumnFixedIcon />\n                <span>\n                  {i18n.t(\n                    \"editor.inspect.setter_option.grid_list.column_adaptation.fixed\",\n                  )}\n                </span>\n              </span>\n            ),\n            value: COLUMN_NUM_ADAPTATION.FIXED,\n          },\n          {\n            label: (\n              <span css={radioButtonOptionItemStyle}>\n                <ColumnAutoIcon />\n                <span>\n                  {i18n.t(\n                    \"editor.inspect.setter_option.grid_list.column_adaptation.dynamic\",\n                  )}\n                </span>\n              </span>\n            ),\n            value: COLUMN_NUM_ADAPTATION.DYNAMIC,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-number_of_columns`,\n        labelName: i18n.t(\"editor.inspect.setter_label.grid_list.column_num\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.grid_list.column_num\"),\n        attrName: \"numberOfColumns\",\n        setterType: \"INPUT_SETTER\",\n        isSetterSingleRow: true,\n        bindAttrName: [\"columnNumAdaptation\"],\n        shown: (v) => v === COLUMN_NUM_ADAPTATION.FIXED,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-layout-Min_column_width(px)`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.grid_list.min_column_width\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.grid_list.min_column_width\",\n        ),\n        attrName: \"minColumnWidth\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"columnNumAdaptation\"],\n        shown: (v) => v === COLUMN_NUM_ADAPTATION.DYNAMIC,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-layout-item_gap`,\n        setterType: \"LIST_GAP_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.grid_list.item_spacing\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.grid_list.item_spacing\"),\n        attrName: \"itemGap\",\n        defaultValue: LIST_ITEM_MARGIN_TOP,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-layout-height`,\n        labelName: i18n.t(\"editor.inspect.setter_label.height\"),\n        attrName: \"dynamicHeight\",\n        setterType: \"HEIGHT_MODE_SELECT\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.fixed\"),\n            value: \"fixed\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_height\"),\n            value: \"auto\",\n          },\n        ],\n      },\n\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        useCustomLayout: true,\n        attrName: \"hidden\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"ITEM_BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"itemBorder\",\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.grid_list.item_radius\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.grid_list.item_radius\",\n            ),\n            attrName: \"itemBorderRadius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n          {\n            id: `${baseWidgetName}-style-shadow`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.grid_list.item_shadow\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.grid_list.item_shadow\",\n            ),\n            attrName: \"itemShadow\",\n            setterType: \"SHADOW_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"medium\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-style-color`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-colors-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"themeColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n          {\n            id: `${baseWidgetName}-style-color`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.item_background_color\",\n            ),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"itemBackGroundColor\",\n            defaultValue: \"white\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-padding`,\n        setterType: \"PADDING_INPUT_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_group.item_padding\"),\n        attrName: \"itemPadding\",\n        useCustomLayout: true,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor, getSpecialThemeColor } from \"@illa-design/react\"\nimport { SCROLL_CONTAINER_PADDING } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { getPaddingShape } from \"@/utils/styleUtils/padding\"\nimport { COLUMN_NUM_ADAPTATION, ShadowOptions } from \"./interface\"\nimport { getGapByShadow } from \"./utils\"\n\nexport const listParentContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  position: relative;\n  overflow: hidden;\n  gap: 8px;\n  justify-content: space-between;\n`\n\nexport const listParentContainerWithPagination = css`\n  ${listParentContainerStyle};\n  overflow-y: auto;\n`\n\nexport const ListParentContainerWithScroll = css`\n  ${listParentContainerStyle};\n  overflow-y: auto;\n`\n\nexport const applyListItemStyle = (\n  isFirst: boolean = false,\n  bgColor: string,\n  shadowStyle: string,\n  borderStyle: string,\n  isEditor: boolean = false,\n  loading?: boolean,\n  itemHeight?: number,\n  padding?: string,\n) => {\n  // canvas container hash scroll container padding\n  let extraPadding = isFirst ? 0 : SCROLL_CONTAINER_PADDING\n  const { paddingTop, paddingBottom, paddingLeft, paddingRight } =\n    getPaddingShape(padding)\n  return css`\n    width: 100%;\n    height: ${itemHeight ? `${itemHeight}px` : \"100%\"};\n    background-color: ${bgColor\n      ? getSpecialThemeColor(bgColor)\n      : \"transparent\"};\n    flex: none;\n    opacity: ${isEditor && !isFirst ? 0.5 : 1};\n    ${borderStyle};\n    box-shadow: ${shadowStyle};\n    padding: ${paddingTop + extraPadding}px ${paddingRight + extraPadding}px\n      ${paddingBottom + extraPadding}px ${paddingLeft + extraPadding}px;\n    pointer-events: ${loading ? \"none\" : \"unset\"};\n  `\n}\n\nexport const paginationWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  flex: none;\n`\n\nexport const itemContainerStyle = (\n  columnNumAdaptation: COLUMN_NUM_ADAPTATION,\n  itemGapX: number,\n  itemGapY: number,\n  shadow?: ShadowOptions,\n  numberOfColumns?: number,\n  minColumnWidth?: number,\n) => {\n  let gridStyle\n  if (columnNumAdaptation === COLUMN_NUM_ADAPTATION.FIXED) {\n    gridStyle = css`\n      grid-template-columns: repeat(${numberOfColumns ?? 3}, 1fr);\n    `\n  } else {\n    gridStyle = css`\n      grid-template-columns: repeat(\n        auto-fit,\n        minmax(${minColumnWidth ?? 240}px, 1fr)\n      );\n    `\n  }\n  let paddingStyle = getGapByShadow(shadow)\n  return css`\n    display: grid;\n    width: 100%;\n    gap: ${itemGapX}px ${itemGapY}px;\n    ${gridStyle};\n    overflow-y: auto;\n    padding: ${paddingStyle}px;\n  `\n}\n\nexport const radioButtonOptionItemStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const selectStyle = (\n  isSelect: boolean,\n  isEditMode: boolean,\n  themeColor?: string,\n  radius?: string,\n  itemHeight?: number,\n) => {\n  if (isEditMode || !isSelect) {\n    return css`\n      width: 100%;\n      height: ${itemHeight ? `${itemHeight}px` : \"100%\"};\n    `\n  }\n  return css`\n    width: 100%;\n    height: ${itemHeight ? `${itemHeight}px` : \"100%\"};\n    outline: 1px solid ${themeColor ?? getColor(\"blue\", \"03\")} !important;\n    border-radius: ${radius ?? \"unset\"};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/utils.tsx",
    "content": "import {\n  applyBarHandlerStyle,\n  applyBarPointerStyle,\n} from \"@/page/App/components/ScaleSquare/style\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport store from \"@/store\"\nimport { ShadowOptions } from \"./interface\"\n\nexport const resizeBottomHandler = () => {\n  const rootState = store.getState()\n  const isEditMode = getIsILLAEditMode(rootState)\n  const scaleSquareState = !isEditMode ? \"production\" : \"normal\"\n  return {\n    bottom: (\n      <div css={applyBarHandlerStyle(true, scaleSquareState, \"b\")}>\n        <div\n          className=\"handler\"\n          css={applyBarPointerStyle(true, scaleSquareState, \"b\")}\n        />\n      </div>\n    ),\n  }\n}\n\nexport const getGapByShadow = (itemShadow?: ShadowOptions) => {\n  switch (itemShadow) {\n    case \"large\": {\n      return 20\n    }\n    case \"medium\": {\n      return 16\n    }\n    case \"small\": {\n      return 4\n    }\n    case \"none\":\n    default:\n      return 1\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/GridListWidget/widgetConfig.tsx",
    "content": "import { PADDING_MODE } from \"@illa-public/public-types\"\nimport GridListWidgetIcon from \"@/assets/widgetCover/gridList.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { TEMPLATE_DISPLAYNAME_KEY } from \"@/utils/generators/generateComponentNode\"\nimport { BasicContainerConfig } from \"@/widgetLibrary/BasicContainer/BasicContainer\"\nimport { IMAGE_WIDGET_CONFIG } from \"@/widgetLibrary/ImageWidget\"\nimport { TEXT_WIDGET_CONFIG } from \"@/widgetLibrary/TextWidget\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\nimport { DEFAULT_LIST } from \"./constants\"\nimport { COLUMN_NUM_ADAPTATION, PAGINATION_TYPE } from \"./interface\"\n\nexport const GRID_LIST_WIDGET_CONFIG: WidgetConfig = {\n  type: \"GRID_LIST_WIDGET\",\n  displayName: \"gridList\",\n  widgetName: i18n.t(\"widget.grid_list.name\"),\n  keywords: [\"gridList\", \"网格列表\"],\n  icon: <GridListWidgetIcon />,\n  sessionType: \"CONTAINER\",\n  w: 20,\n  h: 55,\n  version: 0,\n  childrenNode: [\n    {\n      ...BasicContainerConfig,\n      childrenNode: [\n        {\n          ...IMAGE_WIDGET_CONFIG,\n          w: 32,\n          h: 17,\n          x: 0,\n          y: 1,\n          defaults: {\n            ...IMAGE_WIDGET_CONFIG.defaults,\n            imageSrc: `{{${TEMPLATE_DISPLAYNAME_KEY}.dataSources.map((currentItem) => (currentItem.photo))}}`,\n            $dynamicAttrPaths: [\"imageSrc\"],\n            radius: \"4px\",\n          },\n        },\n        {\n          ...TEXT_WIDGET_CONFIG,\n          w: 32,\n          h: 9,\n          x: 0,\n          y: 18,\n          defaults: {\n            ...TEXT_WIDGET_CONFIG.defaults,\n            value: `{{${TEMPLATE_DISPLAYNAME_KEY}.dataSources.map((currentItem) => ('### ' + currentItem.name))}}`,\n            $dynamicAttrPaths: [\"value\"],\n          },\n        },\n      ],\n    },\n  ],\n  defaults: {\n    enablePagination: true,\n    enableServerSidePagination: false,\n    pageSize: \"{{10}}\",\n    paginationType: PAGINATION_TYPE.LIMIT_OFFSET_BASED,\n    itemBackGroundColor: \"white\",\n    themeColor: \"blue\",\n    itemHeight: 232,\n    selectedIndex: undefined,\n    selectedItem: undefined,\n    dataSources: `{{\n      ${JSON.stringify(DEFAULT_LIST)}\n    }}`,\n    columnNumAdaptation: COLUMN_NUM_ADAPTATION.FIXED,\n    dynamicHeight: \"fixed\",\n    resizeDirection: RESIZE_DIRECTION.ALL,\n    numberOfColumns: \"{{3}}\",\n    minColumnWidth: \"{{240}}\",\n    page: \"{{0}}\",\n    offset: 0,\n    itemBorderRadius: \"4px\",\n    itemShadow: \"medium\",\n    itemPadding: {\n      mode: PADDING_MODE.ALL,\n      size: \"4\",\n    },\n    beforeCursor: undefined,\n    afterCursor: undefined,\n    totalRowCount: undefined,\n    previousCursor: undefined,\n    nextCursor: undefined,\n    hasNextPage: undefined,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IFrameWidget/eventHandlerConfig.ts",
    "content": "import { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const IFRAME_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [],\n  methods: [\"setSrc\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IFrameWidget/iframe.tsx",
    "content": "import { FC, useEffect } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getIsResizing } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { IFrameWidgetProps } from \"@/widgetLibrary/IFrameWidget/interface\"\nimport { applyIframeContainer } from \"@/widgetLibrary/IFrameWidget/style\"\n\nexport const IFrameWidget: FC<IFrameWidgetProps> = (props) => {\n  const {\n    src,\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n  } = props\n\n  const isResizingGlobal = useSelector(getIsResizing)\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setSrc: (url: string) => {\n        handleUpdateDsl({ src: url })\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n  ])\n\n  return (\n    <iframe\n      allow=\"*\"\n      allowFullScreen={true}\n      css={applyIframeContainer(isResizingGlobal)}\n      src={src}\n    />\n  )\n}\nIFrameWidget.displayName = \"IFrameWidget\"\nexport default IFrameWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IFrameWidget/index.tsx",
    "content": "export { IFRAME_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { IFRAME_PANEL_CONFIG } from \"./panelConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IFrameWidget/interface.ts",
    "content": "import { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface IFrameWidgetProps extends BaseWidgetProps {\n  src: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IFrameWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst baseWidgetName = \"iframe\"\nexport const IFRAME_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-src`,\n        labelName: i18n.t(\"editor.inspect.setter_label.src\"),\n        attrName: \"src\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        placeholder: \"https://illacloud.com\",\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IFrameWidget/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\n\nexport function applyIframeContainer(isDragging: boolean): SerializedStyles {\n  return css`\n    pointer-events: ${isDragging ? \"none\" : \"auto\"};\n    border: none;\n    height: 100%;\n    width: 100%;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IFrameWidget/widgetConfig.tsx",
    "content": "import IFrameWidgetIcon from \"@/assets/widgetCover/iframe.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const IFRAME_WIDGET_CONFIG: WidgetConfig = {\n  displayName: \"iframe\",\n  widgetName: i18n.t(\"widget.iframe.name\"),\n  h: 40,\n  w: 16,\n  type: \"IFRAME_WIDGET\",\n  icon: <IFrameWidgetIcon />,\n  keywords: [\"iframe\", \"內联框架\"],\n  sessionType: \"PRESENTATION\",\n  resizeDirection: RESIZE_DIRECTION.ALL,\n  version: 0,\n  defaults: {\n    src: \"https://www.nasa.gov/\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IconWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const ICON_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.click\",\n      ),\n      value: \"click\",\n    },\n  ],\n  methods: [],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IconWidget/icon.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport { useMeasure } from \"react-use\"\nimport { IconWidgetProps } from \"@/widgetLibrary/IconWidget/interface\"\nimport { getIconContainerStyle } from \"@/widgetLibrary/IconWidget/style\"\nimport { getIcon } from \"@/widgetLibrary/IconWidget/utils\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\n\nexport const IconWidget: FC<IconWidgetProps> = (props) => {\n  const { tooltipText, iconName, colorScheme, triggerEventHandler } = props\n\n  const [containerRef, containerBounds] = useMeasure<HTMLDivElement>()\n\n  const Icon = getIcon(iconName)\n\n  const handleOnClick = useCallback(() => {\n    triggerEventHandler(\"click\")\n  }, [triggerEventHandler])\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div\n        ref={containerRef}\n        css={getIconContainerStyle(\n          containerBounds.width > containerBounds.height,\n          colorScheme,\n        )}\n      >\n        <div onClick={handleOnClick}>{Icon ? <Icon /> : null}</div>\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nIconWidget.displayName = \"IconWidget\"\nexport default IconWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IconWidget/index.ts",
    "content": "export { ICON_PANEL_CONFIG } from \"./panelConfig\"\nexport { ICON_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { ICON_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IconWidget/interface.ts",
    "content": "import { GenIcon, IconBase, IconContext, IconManifest } from \"react-icons\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface RIALL {\n  IconsManifest: IconManifest[]\n  GenIcon: typeof GenIcon\n  IconBase: typeof IconBase\n  DefaultContext: IconContext\n  IconContext: React.Context<IconContext>\n}\n\nexport interface IconWidgetProps\n  extends BaseWidgetProps,\n    Pick<TooltipWrapperProps, \"tooltipText\"> {\n  iconName?: string\n  colorScheme?: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IconWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { ICON_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/IconWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"icon\"\nexport const ICON_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-iconName`,\n        labelName: i18n.t(\"editor.inspect.setter_label.icon\"),\n        attrName: \"iconName\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"ICON_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          ICON_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-colors-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IconWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const getIconContainerStyle = (\n  isWidthBigger: boolean,\n  colorScheme?: string,\n) => {\n  const svgStyle = isWidthBigger\n    ? css`\n        height: 100%;\n        width: auto;\n      `\n    : css`\n        width: 100%;\n        height: auto;\n      `\n  const svgColor = colorScheme\n    ? css`\n        color: ${colorScheme};\n      `\n    : css``\n  return css`\n    width: 100%;\n    height: 100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    & div {\n      ${svgStyle};\n    }\n    & svg {\n      ${svgStyle};\n      ${svgColor};\n      cursor: pointer;\n      display: block;\n    }\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IconWidget/utils.ts",
    "content": "import * as RiLib from \"react-icons\"\nimport * as bs from \"react-icons/bs\"\nimport * as fc from \"react-icons/fc\"\nimport * as sl from \"react-icons/sl\"\nimport * as tb from \"react-icons/tb\"\nimport { RIALL } from \"./interface\"\n\nconst IMPORT_ICONS_ID = [\"sl\", \"fc\", \"bs\", \"tb\"]\nexport const ALL_ICONS = (RiLib as unknown as RIALL)[\"IconsManifest\"].filter(\n  (iconManifest) => {\n    return IMPORT_ICONS_ID.includes(iconManifest.id)\n  },\n)\nexport const AllIconData: Record<string, Record<string, RiLib.IconType>> = {\n  sl,\n  fc,\n  bs,\n  tb,\n}\n\nexport const AllData: Record<string, RiLib.IconType> = Object.keys(\n  AllIconData,\n).reduce((result, key) => {\n  const data = AllIconData[key]\n  result = { ...result, ...data }\n  return result\n}, {})\n\nexport const getIcon = (iconName?: string) => {\n  return iconName ? AllData[iconName] : null\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/IconWidget/widgetConfig.tsx",
    "content": "import IconsWidgetIcon from \"@/assets/widgetCover/icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const ICON_WIDGET_CONFIG: WidgetConfig = {\n  type: \"ICON_WIDGET\",\n  displayName: \"icon\",\n  widgetName: i18n.t(\"widget.icon.name\"),\n  icon: <IconsWidgetIcon />,\n  keywords: [\"Icon\", \"图标\"],\n  sessionType: \"PRESENTATION\",\n  w: 1,\n  h: 4,\n  version: 0,\n  defaults: {\n    iconName: \"BsHandThumbsUp\",\n    colorScheme: \"grayBlue\",\n    hidden: false,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ImageWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const IMAGE_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.click\",\n      ),\n      value: \"click\",\n    },\n  ],\n  methods: [\"setImageUrl\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ImageWidget/image.tsx",
    "content": "import {\n  FC,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useState,\n} from \"react\"\nimport useMeasure from \"react-use-measure\"\nimport { Image } from \"@illa-design/react\"\nimport { MediaSourceLoadContext } from \"@/utils/mediaSourceLoad\"\nimport { isValidUrlScheme } from \"@/utils/typeHelper\"\nimport {\n  ImageWrapperStyle,\n  imageWrapperContainerStyle,\n} from \"@/widgetLibrary/ImageWidget/style\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { DynamicHeight, ImageWidgetProps, WrappedImageProps } from \"./interface\"\n\nconst getHeight = (\n  dynamicHeight: DynamicHeight,\n  aspectRatio: number,\n  width: number,\n) => {\n  if (dynamicHeight === \"auto\") {\n    if (aspectRatio && aspectRatio > 0) {\n      return `${width * aspectRatio}px`\n    } else {\n      return `${width}px`\n    }\n  } else {\n    return dynamicHeight === \"fixed\" ? \"100%\" : \"auto\"\n  }\n}\n\nexport const WrappedImage: FC<WrappedImageProps> = (props) => {\n  const {\n    imageSrc,\n    altText,\n    imageRadius,\n    objectFit,\n    aspectRatio = 1,\n    dynamicHeight,\n    handleOnClick,\n    sourceLoadErrorHandle,\n  } = props\n\n  const [imageRef, imageBouds] = useMeasure()\n  const [error, setError] = useState(false)\n\n  const width =\n    dynamicHeight === \"auto\" || objectFit === \"cover\" || !imageSrc || error\n      ? \"100%\"\n      : \"auto\"\n\n  const height = getHeight(dynamicHeight, aspectRatio, imageBouds.width)\n\n  const finalObjectFit = dynamicHeight === \"auto\" ? \"cover\" : objectFit\n\n  return (\n    <Image\n      ref={imageRef}\n      src={imageSrc}\n      radius={imageRadius}\n      objectFit={finalObjectFit}\n      alt={altText}\n      width=\"100%\"\n      height=\"100%\"\n      css={imageWrapperContainerStyle(width, height)}\n      draggable={false}\n      onClick={handleOnClick}\n      onLoad={() => {\n        setError(false)\n      }}\n      onError={() => {\n        setError(true)\n        sourceLoadErrorHandle?.(imageSrc, \"image\")\n      }}\n    />\n  )\n}\n\nWrappedImage.displayName = \"WrappedImage\"\n\nexport const ImageWidget: FC<ImageWidgetProps> = (props) => {\n  const {\n    imageSrc,\n    imageRadius,\n    objectFit,\n    horizontalAlign,\n    dynamicHeight,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    tooltipText,\n    triggerEventHandler,\n    updateComponentHeight,\n  } = props\n\n  const { sourceLoadErrorHandler } = useContext(MediaSourceLoadContext)\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setImageUrl: (url: string) => {\n        handleUpdateDsl({ imageSrc: url })\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n  ])\n\n  const finalSrc = useMemo(() => {\n    let finalURL = imageSrc\n    if (finalURL && !isValidUrlScheme(finalURL)) {\n      if (!finalURL.startsWith(\"data:\")) {\n        finalURL = `https://${finalURL}`\n      }\n    }\n    return finalURL\n  }, [imageSrc])\n\n  const finalRadius = useMemo(() => {\n    const reg = /^\\d+$/\n    const pattern = new RegExp(reg)\n    if (imageRadius && pattern.test(imageRadius)) {\n      return imageRadius + \"px\"\n    }\n    return imageRadius\n  }, [imageRadius])\n\n  const handleOnClick = useCallback(() => {\n    triggerEventHandler(\"click\")\n  }, [triggerEventHandler])\n\n  const enableAutoHeight = useMemo(() => {\n    switch (dynamicHeight) {\n      case \"auto\":\n        return true\n      case \"fixed\":\n      default:\n        return false\n    }\n  }, [dynamicHeight])\n\n  return (\n    <AutoHeightContainer\n      updateComponentHeight={updateComponentHeight}\n      enable={enableAutoHeight}\n    >\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={ImageWrapperStyle(horizontalAlign)}>\n          <WrappedImage\n            {...props}\n            imageSrc={finalSrc}\n            imageRadius={finalRadius}\n            objectFit={objectFit}\n            dynamicHeight={dynamicHeight}\n            handleOnClick={handleOnClick}\n            sourceLoadErrorHandle={sourceLoadErrorHandler}\n          />\n        </div>\n      </TooltipWrapper>\n    </AutoHeightContainer>\n  )\n}\nImageWidget.displayName = \"ImageWidget\"\nexport default ImageWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ImageWidget/index.tsx",
    "content": "export { IMAGE_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { IMAGE_PANEL_CONFIG } from \"./panelConfig\"\nexport { IMAGE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ImageWidget/interface.ts",
    "content": "import { ImageProps } from \"@illa-design/react\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport type HorizontalAlign = \"start\" | \"center\" | \"end\"\nexport type DynamicHeight = \"auto\" | \"fixed\"\nexport type ObjectFit = \"contain\" | \"cover\"\nexport interface WrappedImageProps\n  extends Pick<ImageProps, \"width\" | \"height\"> {\n  imageSrc?: ImageProps[\"src\"]\n  altText?: ImageProps[\"alt\"]\n  aspectRatio?: number\n  objectFit?: ObjectFit\n  dynamicHeight: DynamicHeight\n  horizontalAlign?: HorizontalAlign\n  imageRadius?: string\n  handleOnClick: () => void\n  sourceLoadErrorHandle: (\n    source: string | undefined,\n    widgetType: string,\n  ) => void\n}\n\nexport interface ImageWidgetProps\n  extends Omit<WrappedImageProps, \"handleOnClick\">,\n    BaseWidgetProps,\n    TooltipWrapperProps {}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ImageWidget/panelConfig.tsx",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport {\n  HorizontalCenterIcon,\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n} from \"@illa-design/react\"\nimport RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { IMAGE_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/ImageWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { ObjectFit } from \"./interface\"\n\nconst baseWidgetName = \"input\"\nexport const IMAGE_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-source-self-host`,\n        attrName: \"imageSrc\",\n        expectedType: VALIDATION_TYPES.STRING,\n        labelName: i18n.t(\"editor.inspect.setter_label.image_source\"),\n        isSetterSingleRow: true,\n        bindAttrName: [],\n        shown: () => !isCloudVersion,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-source-cloud-version`,\n        attrName: \"imageSrc\",\n        expectedType: VALIDATION_TYPES.STRING,\n        labelName: i18n.t(\"editor.inspect.setter_label.image_source\"),\n        isSetterSingleRow: true,\n        bindAttrName: [],\n        shown: () => isCloudVersion,\n        setterType: \"DRIVE_SOURCE_GROUP_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-alt-text`,\n        labelName: i18n.t(\"editor.inspect.setter_label.alt_text\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_label.alt_text_desc\"),\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"altText\",\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          IMAGE_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        attrName: \"hidden\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n      {\n        id: `${baseWidgetName}-layout-height`,\n        labelName: i18n.t(\"editor.inspect.setter_label.height\"),\n        attrName: \"dynamicHeight\",\n        setterType: \"HEIGHT_MODE_SELECT\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.fixed\"),\n            value: \"fixed\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_height\"),\n            value: \"auto\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-aspect-ratio`,\n        labelName: i18n.t(\"aspect-ratio\"),\n        attrName: \"aspectRatio\",\n        bindAttrName: [\"dynamicHeight\"],\n        shown: (dynamicHeight: \"fixed\" | \"auto\") => dynamicHeight === \"auto\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-basic-scale-type`,\n        labelName: i18n.t(\"editor.inspect.setter_label.scale_type\"),\n        attrName: \"objectFit\",\n        bindAttrName: [\"dynamicHeight\"],\n        shown: (dynamicHeight: \"fixed\" | \"auto\") => dynamicHeight === \"fixed\",\n        setterType: \"SEARCH_SELECT_SETTER\",\n        options: [\"cover\", \"contain\"],\n      },\n      {\n        id: `${baseWidgetName}-layout-col`,\n        labelName: i18n.t(\"editor.inspect.setter_label.horizontal_alignment\"),\n        attrName: \"horizontalAlign\",\n        bindAttrName: [\"dynamicHeight\", \"objectFit\"],\n        shown: (dynamicHeight: \"fixed\" | \"auto\", objectFit: ObjectFit) =>\n          dynamicHeight === \"fixed\" && objectFit !== \"cover\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        isSetterSingleRow: true,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"start\",\n          },\n          {\n            label: <HorizontalCenterIcon />,\n            value: \"center\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"end\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        isSetterSingleRow: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.styles\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            attrName: \"imageRadius\",\n            icon: <RadioIcon />,\n            defaultValue: \"0px\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ImageWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { HorizontalAlign } from \"./interface\"\n\nexport const imageWrapperContainerStyle = (width: string, height: string) => {\n  return css`\n    height: ${height};\n    width: ${width};\n  `\n}\nexport const ImageWrapperStyle = (horizontalAlign?: HorizontalAlign) => {\n  let align = \"center\"\n  if (horizontalAlign === \"start\") {\n    align = \"flex-start\"\n  } else if (horizontalAlign === \"end\") {\n    align = \"flex-end\"\n  }\n  return css`\n    width: 100%;\n    height: 100%;\n    overflow: hidden;\n    display: flex;\n    align-items: center;\n    justify-content: ${align};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ImageWidget/widgetConfig.tsx",
    "content": "import ImageWidgetIcon from \"@/assets/widgetCover/image.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const IMAGE_WIDGET_CONFIG: WidgetConfig = {\n  type: \"IMAGE_WIDGET\",\n  displayName: \"image\",\n  widgetName: i18n.t(\"widget.image.name\"),\n  icon: <ImageWidgetIcon />,\n  keywords: [\"Image\", \"图片\"],\n  sessionType: \"PRESENTATION\",\n  h: 16,\n  w: 3,\n  version: 0,\n  defaults: {\n    imageSrc:\n      \"https://images.unsplash.com/photo-1614853316476-de00d14cb1fc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2370&q=80\",\n    imageRadius: \"0px\",\n    hidden: false,\n    objectFit: \"cover\",\n    dynamicHeight: \"fixed\",\n    horizontalAlign: \"center\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/InputWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const INPUT_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.focus\",\n      ),\n      value: \"focus\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.blur\",\n      ),\n      value: \"blur\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"focus\", \"validate\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/InputWidget/index.tsx",
    "content": "export { INPUT_PANEL_CONFIG } from \"./panelConfig\"\nexport { INPUT_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { INPUT_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/InputWidget/input.tsx",
    "content": "import { debounce } from \"lodash-es\"\nimport { FC, forwardRef, useCallback, useEffect, useRef, useState } from \"react\"\nimport { Input, Password, Search } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { InputWidgetProps, WrappedInputProps } from \"./interface\"\nimport { getValidateMessageFunc } from \"./utils\"\n\nexport const WrappedInput = forwardRef<HTMLInputElement, WrappedInputProps>(\n  (props, ref) => {\n    const {\n      type = \"input\",\n      showVisibleButton = true,\n      value,\n      placeholder,\n      disabled,\n      readOnly,\n      prefixText,\n      suffixText,\n      showCharacterCount,\n      colorScheme,\n      handleOnChange,\n      handleOnFocus,\n      handleOnBlur,\n      allowClear,\n      maxLength,\n      minLength,\n      clearValue,\n    } = props\n\n    return (\n      <>\n        {type === \"input\" && (\n          <Input\n            w=\"100%\"\n            inputRef={ref}\n            value={value}\n            placeholder={placeholder}\n            disabled={disabled}\n            readOnly={readOnly}\n            addBefore={prefixText}\n            addAfter={suffixText}\n            onFocus={handleOnFocus}\n            onBlur={handleOnBlur}\n            onChange={handleOnChange}\n            showWordLimit={showCharacterCount}\n            colorScheme={colorScheme}\n            allowClear={allowClear}\n            onClear={clearValue}\n            maxLength={maxLength}\n            minLength={minLength}\n          />\n        )}\n        {type === \"password\" && (\n          <Password\n            w=\"100%\"\n            inputRef={ref}\n            value={value}\n            autoComplete=\"new-password\"\n            visibilityToggle={showVisibleButton}\n            placeholder={placeholder}\n            disabled={disabled}\n            readOnly={readOnly}\n            addBefore={prefixText}\n            addAfter={suffixText}\n            onFocus={handleOnFocus}\n            onBlur={handleOnBlur}\n            onChange={handleOnChange}\n            showWordLimit={showCharacterCount}\n            colorScheme={colorScheme}\n            allowClear={allowClear}\n            onClear={clearValue}\n            maxLength={maxLength}\n            minLength={minLength}\n          />\n        )}\n        {type === \"search\" && (\n          <Search\n            w=\"100%\"\n            inputRef={ref}\n            value={value}\n            placeholder={placeholder}\n            disabled={disabled}\n            readOnly={readOnly}\n            addBefore={prefixText}\n            addAfter={suffixText}\n            onFocus={handleOnFocus}\n            onBlur={handleOnBlur}\n            onChange={handleOnChange}\n            showWordLimit={showCharacterCount}\n            colorScheme={colorScheme}\n            allowClear={allowClear}\n            onClear={clearValue}\n            maxLength={maxLength}\n            minLength={minLength}\n          />\n        )}\n      </>\n    )\n  },\n)\nWrappedInput.displayName = \"WrappedInput\"\n\nexport const InputWidget: FC<InputWidgetProps> = (props) => {\n  const {\n    displayName,\n    value,\n    handleUpdateDsl,\n    minLength,\n    maxLength,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    pattern,\n    regex,\n    customRule,\n    hideValidationMessage,\n    defaultValue,\n    updateComponentHeight,\n    validateMessage,\n    triggerEventHandler,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n  } = props\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const [inputValue, setInputValue] = useState<string>(\n    value || defaultValue || \"\",\n  )\n\n  useEffect(() => {\n    setInputValue(defaultValue)\n\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          value: defaultValue || \"\",\n        },\n      },\n    ])\n  }, [defaultValue, displayName, handleUpdateMultiExecutionResult])\n\n  const handleValidate = useCallback(\n    (value?: string) => {\n      const message = getValidateMessageFunc(value, {\n        hideValidationMessage: hideValidationMessage,\n        pattern: pattern,\n        regex: regex,\n        minLength: minLength,\n        maxLength: maxLength,\n        required: required,\n        customRule: customRule,\n      })\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [\n      customRule,\n      handleUpdateDsl,\n      hideValidationMessage,\n      maxLength,\n      minLength,\n      pattern,\n      regex,\n      required,\n    ],\n  )\n\n  const debounceOnChange = useRef(\n    debounce(\n      (\n        value: string,\n        triggerEventHandler: InputWidgetProps[\"triggerEventHandler\"],\n        options?: {\n          hideValidationMessage?: InputWidgetProps[\"hideValidationMessage\"]\n          pattern?: InputWidgetProps[\"pattern\"]\n          regex?: InputWidgetProps[\"regex\"]\n          minLength?: InputWidgetProps[\"minLength\"]\n          maxLength?: InputWidgetProps[\"maxLength\"]\n          required?: InputWidgetProps[\"required\"]\n          customRule?: InputWidgetProps[\"customRule\"]\n        },\n      ) => {\n        new Promise((resolve) => {\n          const message = getValidateMessageFunc(value, options)\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                value: value || \"\",\n                validateMessage: message,\n              },\n            },\n          ])\n          resolve(true)\n        }).then(() => {\n          triggerEventHandler(\"change\")\n        })\n      },\n      180,\n    ),\n  )\n\n  const handleOnChange = useCallback(\n    (value: string) => {\n      setInputValue(value)\n      debounceOnChange.current(value, triggerEventHandler, {\n        hideValidationMessage: hideValidationMessage,\n        pattern: pattern,\n        regex: regex,\n        minLength: minLength,\n        maxLength: maxLength,\n        required: required,\n        customRule: customRule,\n      })\n    },\n    [\n      customRule,\n      hideValidationMessage,\n      maxLength,\n      minLength,\n      pattern,\n      regex,\n      required,\n      triggerEventHandler,\n    ],\n  )\n\n  const clearValue = useCallback(() => {\n    handleOnChange(\"\")\n  }, [handleOnChange])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      focus: () => {\n        inputRef.current?.focus()\n      },\n      setValue: (value: boolean | string | number | void) => {\n        if (typeof value === \"string\") {\n          handleOnChange(value)\n        }\n      },\n      clearValue: () => {\n        clearValue()\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {\n        handleUpdateDsl({\n          validateMessage: \"\",\n        })\n      },\n    })\n\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    clearValue,\n    deleteComponentRuntimeProps,\n    handleOnChange,\n    handleUpdateDsl,\n    handleValidate,\n    updateComponentRuntimeProps,\n    value,\n  ])\n\n  const handleOnFocus = useCallback(() => {\n    triggerEventHandler(\"focus\")\n  }, [triggerEventHandler])\n\n  const handleOnBlur = useCallback(() => {\n    triggerEventHandler(\"blur\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedInput\n            {...props}\n            value={inputValue}\n            ref={inputRef}\n            handleOnChange={handleOnChange}\n            handleOnFocus={handleOnFocus}\n            handleOnBlur={handleOnBlur}\n            clearValue={clearValue}\n          />\n        </div>\n      </TooltipWrapper>\n\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\n\nInputWidget.displayName = \"InputWidget\"\nexport default InputWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/InputWidget/interface.tsx",
    "content": "import { InputProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedInputProps\n  extends Pick<\n      InputProps,\n      \"placeholder\" | \"disabled\" | \"readOnly\" | \"maxLength\" | \"minLength\"\n    >,\n    BaseWidgetProps {\n  showCharacterCount?: InputProps[\"showWordLimit\"]\n  type?: \"input\" | \"password\" | \"search\"\n  showVisibleButton?: boolean\n  value?: string\n  prefixIcon?: InputProps[\"prefix\"]\n  prefixText?: string\n  suffixIcon?: InputProps[\"suffix\"]\n  suffixText?: string\n  colorScheme?: InputProps[\"colorScheme\"]\n  allowClear?: InputProps[\"allowClear\"]\n  handleOnChange?: (value: string) => void\n  handleOnFocus?: () => void\n  handleOnBlur?: () => void\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  getValidateMessage: (value: string) => string\n  clearValue: () => void\n}\n\nexport interface InputWidgetProps\n  extends Omit<\n      WrappedInputProps,\n      \"maxLength\" | \"handleOnChange\" | \"handleOnFocus\" | \"handleOnBlur\"\n    >,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  defaultValue: string\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/InputWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { INPUT_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/InputWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"input\"\nexport const INPUT_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-type`,\n        labelName: i18n.t(\"editor.inspect.setter_label.input.type\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.input.type\"),\n        attrName: \"type\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"SEARCH_SELECT_SETTER\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.input.input\"),\n            value: \"input\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.input.password\"),\n            value: \"password\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.input.search\"),\n            value: \"search\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.input_default_value\"),\n        attrName: \"defaultValue\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"placeholder\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\", \"labelPosition\"],\n        shown: (hidden, position) => !hidden && position !== \"top\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          INPUT_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        placeholder: \"{{false}}\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readOnly\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-visible-button`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.input.show_visible_button\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.input.show_visible_button\",\n        ),\n        attrName: \"showVisibleButton\",\n        useCustomLayout: true,\n        openDynamic: true,\n        bindAttrName: [\"type\"],\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        shown: (value) => value === \"password\",\n      },\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        attrName: \"allowClear\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-showChartCount`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_character_count\"),\n        attrName: \"showCharacterCount\",\n        useCustomLayout: true,\n        openDynamic: true,\n        bindAttrName: [\"type\"],\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        shown: (value) => value !== \"password\",\n      },\n      {\n        id: `${baseWidgetName}-adornments-prefixText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.prefix_text\"),\n        attrName: \"prefixText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-adornments-suffixText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.suffix_text\"),\n        attrName: \"suffixText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-pattern`,\n        labelName: i18n.t(\"editor.inspect.setter_label.pattern\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"pattern\",\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.validation_pattern.email\",\n            ),\n            value: \"Email\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.validation_pattern.url\",\n            ),\n            value: \"URL\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.validation_pattern.regex\",\n            ),\n            value: \"Regex\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-validation-regex`,\n        labelName: i18n.t(\"editor.inspect.setter_label.regex\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"regex\",\n        bindAttrName: [\"pattern\"],\n        expectedType: VALIDATION_TYPES.STRING,\n        shown: (value) => value === \"Regex\",\n      },\n      {\n        id: `${baseWidgetName}-validation-max`,\n        labelName: i18n.t(\"editor.inspect.setter_label.max_length\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"maxLength\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-min`,\n        labelName: i18n.t(\"editor.inspect.setter_label.min_length\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"minLength\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-colors-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/InputWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  flex: 1;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/InputWidget/utils.ts",
    "content": "import {\n  getValidateVFromString,\n  handleValidateCheck,\n} from \"../PublicSector/InvalidMessage/utils\"\nimport { InputWidgetProps } from \"./interface\"\n\nexport const getValidateMessageFunc = (\n  value: string | undefined,\n  options: {\n    hideValidationMessage?: InputWidgetProps[\"hideValidationMessage\"]\n    pattern?: InputWidgetProps[\"pattern\"]\n    regex?: InputWidgetProps[\"regex\"]\n    minLength?: InputWidgetProps[\"minLength\"]\n    maxLength?: InputWidgetProps[\"maxLength\"]\n    required?: InputWidgetProps[\"required\"]\n    customRule?: InputWidgetProps[\"customRule\"]\n  } = {},\n) => {\n  const {\n    hideValidationMessage,\n    pattern,\n    regex,\n    maxLength,\n    minLength,\n    required,\n    customRule,\n  } = options\n  if (!hideValidationMessage) {\n    const message = handleValidateCheck({\n      value: getValidateVFromString(value),\n      pattern,\n      regex,\n      minLength,\n      maxLength,\n      required,\n      customRule,\n    })\n    const showMessage = message && message.length > 0\n    return showMessage ? message : \"\"\n  }\n  return \"\"\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/InputWidget/widgetConfig.tsx",
    "content": "import TextInputWidgetIcon from \"@/assets/widgetCover/textInput.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const INPUT_WIDGET_CONFIG: WidgetConfig = {\n  type: \"INPUT_WIDGET\",\n  displayName: \"input\",\n  widgetName: i18n.t(\"widget.input.name\"),\n  icon: <TextInputWidgetIcon />,\n  keywords: [\"Input\", \"文本输入框\"],\n  sessionType: \"INPUTS\",\n  w: 6,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    value: undefined,\n    defaultValue: \"\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    colorScheme: \"blue\",\n    hidden: false,\n    formDataKey: \"input\",\n    placeholder: \"input sth\",\n    $dynamicAttrPaths: [\"labelWidth\"],\n    type: \"input\",\n    showVisibleButton: \"{{true}}\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonEditorWidget/baseJsonEditor.tsx",
    "content": "import { json } from \"@codemirror/lang-json\"\nimport { githubLight } from \"@uiw/codemirror-theme-github\"\nimport CodeMirror, { ReactCodeMirrorRef } from \"@uiw/react-codemirror\"\nimport { forwardRef, useMemo, useRef } from \"react\"\nimport { BaseJsonEditorProps } from \"@/widgetLibrary/JsonEditorWidget/interface\"\nimport { baseJsonEditorStyle } from \"@/widgetLibrary/JsonEditorWidget/style\"\n\nexport const BaseJsonEditor = forwardRef<\n  ReactCodeMirrorRef,\n  BaseJsonEditorProps\n>(({ value, disabled, handleOnChange, handleOnBlur, handleOnFocus }, ref) => {\n  const cacheValue = useRef<string>(\"\")\n\n  const formatValue = useMemo(() => {\n    if (value) {\n      try {\n        if (value !== cacheValue.current) {\n          const currentVal = JSON.stringify(JSON.parse(value), null, 2)\n          cacheValue.current = currentVal\n          return currentVal\n        }\n        return cacheValue.current\n      } catch (e) {\n        console.warn(e)\n        if (value !== cacheValue.current) {\n          return value\n        }\n        return cacheValue.current\n      }\n    } else {\n      return \"\"\n    }\n  }, [value])\n\n  return (\n    <CodeMirror\n      ref={ref}\n      value={formatValue}\n      css={baseJsonEditorStyle}\n      onChange={handleOnChange}\n      onFocus={handleOnFocus}\n      onBlur={handleOnBlur}\n      theme={githubLight}\n      extensions={[json()]}\n      editable={!disabled}\n      onMouseDownCapture={(e) => e.stopPropagation()}\n      onTouchStartCapture={(e) => e.stopPropagation()}\n    />\n  )\n})\nBaseJsonEditor.displayName = \"BaseJsonEditor\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonEditorWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const JSON_EDITOR_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.focus\",\n      ),\n      value: \"focus\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.blur\",\n      ),\n      value: \"blur\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"focus\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonEditorWidget/index.ts",
    "content": "export { JSON_EDITOR_PANEL_CONFIG } from \"./panelConfig\"\nexport { JSON_EDITOR_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { JSON_EDITOR_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonEditorWidget/interface.ts",
    "content": "import { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface BaseJsonEditorProps extends BaseWidgetProps {\n  value?: string\n  disabled?: boolean\n  handleOnChange?: (value: string) => void\n  handleOnBlur?: () => void\n  handleOnFocus?: () => void\n}\n\nexport interface JsonEditorWidgetProps\n  extends BaseJsonEditorProps,\n    Pick<TooltipWrapperProps, \"tooltipText\"> {\n  defaultValue?: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonEditorWidget/jsonEditor.tsx",
    "content": "import { ReactCodeMirrorRef } from \"@uiw/react-codemirror\"\nimport { debounce } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useRef } from \"react\"\nimport { BaseJsonEditor } from \"@/widgetLibrary/JsonEditorWidget/baseJsonEditor\"\nimport { JsonEditorWidgetProps } from \"@/widgetLibrary/JsonEditorWidget/interface\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\n\nexport const JsonEditorWidget: FC<JsonEditorWidgetProps> = (props) => {\n  const {\n    displayName,\n    tooltipText,\n    value,\n    defaultValue,\n    triggerEventHandler,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n  } = props\n\n  const editorRef = useRef<ReactCodeMirrorRef>(null)\n  const containerRef = useRef<HTMLDivElement>(null)\n  const cacheDefaultValue = useRef(defaultValue)\n  const cacheValue = useRef(value)\n\n  const debounceUpdateOnChange = useRef(\n    debounce(\n      (\n        value: unknown,\n        triggerEventHandler: JsonEditorWidgetProps[\"triggerEventHandler\"],\n      ) => {\n        if (typeof value === \"string\") {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                value: value,\n              },\n            },\n          ])\n          triggerEventHandler(\"change\")\n        }\n      },\n      180,\n    ),\n  )\n\n  const updateOnChange = useCallback(\n    (value: unknown) => {\n      debounceUpdateOnChange.current(value, triggerEventHandler)\n    },\n    [triggerEventHandler],\n  )\n\n  const handleOnFocus = useCallback(() => {\n    triggerEventHandler(\"focus\")\n  }, [triggerEventHandler])\n\n  const handleOnBlur = useCallback(() => {\n    triggerEventHandler(\"blur\")\n  }, [triggerEventHandler])\n\n  useEffect(() => {\n    if (cacheDefaultValue.current !== defaultValue) {\n      cacheDefaultValue.current = defaultValue\n    }\n  }, [defaultValue])\n\n  useEffect(() => {\n    if (\n      cacheDefaultValue.current === defaultValue &&\n      cacheValue.current !== cacheDefaultValue.current\n    ) {\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value: defaultValue,\n          },\n        },\n      ])\n      cacheValue.current = defaultValue\n    }\n  }, [defaultValue, displayName, handleUpdateMultiExecutionResult])\n\n  useEffect(() => {\n    if (cacheValue.current !== value) {\n      cacheValue.current = value\n    }\n  }, [value])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: unknown) => {\n        if (typeof value !== \"string\") return\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value,\n            },\n          },\n        ])\n      },\n      clearValue: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: undefined,\n            },\n          },\n        ])\n      },\n      focus: () => {\n        editorRef.current?.view?.focus()\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    displayName,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n  ])\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div ref={containerRef}>\n        <BaseJsonEditor\n          {...props}\n          ref={editorRef}\n          value={value}\n          handleOnChange={updateOnChange}\n          handleOnBlur={handleOnBlur}\n          handleOnFocus={handleOnFocus}\n        />\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nJsonEditorWidget.displayName = \"JsonEditorWidget\"\nexport default JsonEditorWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonEditorWidget/panelConfig.tsx",
    "content": "import RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { JSON_EDITOR_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/JsonEditorWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"jsonEditor\"\nexport const JSON_EDITOR_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.input_default_value\"),\n        attrName: \"defaultValue\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          JSON_EDITOR_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        placeholder: \"{{false}}\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-styles`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"border\",\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            attrName: \"radius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n          {\n            id: `${baseWidgetName}-style-shadow`,\n            labelName: i18n.t(\"editor.inspect.setter_label.shadow.shadow\"),\n            attrName: \"shadow\",\n            setterType: \"SHADOW_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"small\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonEditorWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const baseJsonEditorStyle = css`\n  cursor: text;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonEditorWidget/widgetConfig.tsx",
    "content": "import JsonEditorWidgetIcon from \"@/assets/widgetCover/jsonEditor.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const JSON_EDITOR_WIDGET_CONFIG: WidgetConfig = {\n  type: \"JSON_EDITOR_WIDGET\",\n  displayName: \"jsonEditor\",\n  widgetName: i18n.t(\"widget.jsonEditor.name\"),\n  icon: <JsonEditorWidgetIcon />,\n  keywords: [\"JSON Editor\", \"JSON编辑器\"],\n  sessionType: \"INPUTS\",\n  w: 10,\n  h: 55,\n  version: 0,\n  defaults: {\n    colorScheme: \"grayBlue\",\n    hidden: false,\n    value: undefined,\n    defaultValue: `[{\n  language: \"en-US\",\n  userConfig: { \"0-16\": \"planA\", \"17-24\": \"planB\", \"25+\": \"planC\" },\n},\n{\n  language: \"ja-JP\",\n  userConfig: { \"0-16\": \"planD\", \"17-24\": \"planE\", \"25+\": \"planF\" },\n}]`,\n    radius: \"4px\",\n    shadow: \"small\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/index.ts",
    "content": "import { FormProps, ThemeProps, withTheme } from \"@rjsf/core\"\nimport { FormContextType, RJSFSchema, StrictRJSFSchema } from \"@rjsf/utils\"\nimport { ComponentType } from \"react\"\nimport Templates, { generateTemplates } from \"./templates\"\nimport Widgets, { generateWidgets } from \"./widgets\"\n\nexport function generateTheme<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(): ThemeProps<T, S, F> {\n  return {\n    templates: generateTemplates<T, S, F>(),\n    widgets: generateWidgets<T, S, F>(),\n  }\n}\n\nconst Theme = generateTheme()\n\nexport function generateForm<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(): ComponentType<FormProps<T, S, F>> {\n  return withTheme<T, S, F>(generateTheme<T, S, F>())\n}\n\nconst Form = generateForm()\n\nexport { Form, Templates, Theme, Widgets, generateTemplates, generateWidgets }\n\nexport default Form\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper/index.tsx",
    "content": "import { FC, ReactNode } from \"react\"\nimport Label from \"@/widgetLibrary/PublicSector/Label\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { applyLabelAndComponentWrapperStyle } from \"./style\"\n\nexport const LabelWrapper: FC<\n  LabelProps & { children: ReactNode; isSingleLine?: boolean }\n> = ({ label, required, children, isSingleLine }) => {\n  return (\n    <div css={applyLabelAndComponentWrapperStyle(isSingleLine)}>\n      <Label\n        label={label}\n        labelAlign=\"left\"\n        labelWidth={33}\n        labelPosition={isSingleLine ? \"right\" : \"top\"}\n        required={required}\n      />\n      {children}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const applyLabelAndComponentWrapperStyle = (isSingleLine?: boolean) => {\n  const singleLineStyle = isSingleLine\n    ? `\n    display: flex;\n    flex-direction: row-reverse;\n    align-items: center;\n    justify-content: flex-end;\n  `\n    : \"\"\n  return css`\n    color: ${getColor(\"grayBlue\", \"02\")}!important;\n    margin: 8px 0;\n    & > label {\n      font-size: 14px;\n      line-height: 20px;\n    }\n    ${singleLineStyle};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/ArrayFieldItemTemplate/index.tsx",
    "content": "import {\n  ArrayFieldTemplateItemType,\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n} from \"@rjsf/utils\"\nimport { Col, Row } from \"@illa-design/react\"\nimport { arrayItemStyle, buttonGroupStyle } from \"./style\"\n\nexport default function ArrayFieldItemTemplate<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: ArrayFieldTemplateItemType<T, S, F>) {\n  const {\n    children,\n    disabled,\n    hasCopy,\n    hasMoveDown,\n    hasMoveUp,\n    hasRemove,\n    hasToolbar,\n    index,\n    onCopyIndexClick,\n    onDropIndexClick,\n    onReorderClick,\n    readonly,\n    registry,\n    uiSchema,\n  } = props\n  const { CopyButton, MoveDownButton, MoveUpButton, RemoveButton } =\n    registry.templates.ButtonTemplates\n  const { toolbarAlign = \"top\" } = registry.formContext\n\n  return (\n    <Row align={toolbarAlign} key={`array-item-${index}`} css={arrayItemStyle}>\n      <Col flex=\"1\">{children}</Col>\n      {hasToolbar && (\n        <Col flex=\"192px\" style={{ marginLeft: \"16px\" }}>\n          <div css={buttonGroupStyle}>\n            {(hasMoveUp || hasMoveDown) && (\n              <MoveUpButton\n                disabled={disabled || readonly || !hasMoveUp}\n                onClick={onReorderClick(index, index - 1)}\n                uiSchema={uiSchema}\n                registry={registry}\n              />\n            )}\n            {(hasMoveUp || hasMoveDown) && (\n              <MoveDownButton\n                disabled={disabled || readonly || !hasMoveDown}\n                onClick={onReorderClick(index, index + 1)}\n                uiSchema={uiSchema}\n                registry={registry}\n              />\n            )}\n            {hasCopy ? (\n              <CopyButton\n                disabled={disabled || readonly}\n                onClick={onCopyIndexClick(index)}\n                uiSchema={uiSchema}\n                registry={registry}\n              />\n            ) : null}\n            {hasRemove && (\n              <RemoveButton\n                disabled={disabled || readonly}\n                onClick={onDropIndexClick(index)}\n                uiSchema={uiSchema}\n                registry={registry}\n              />\n            )}\n          </div>\n        </Col>\n      )}\n    </Row>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/ArrayFieldItemTemplate/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const buttonGroupStyle = css`\n  display: flex;\n  flex-direction: row;\n  gap: 4px;\n`\n\nexport const arrayItemStyle = css`\n  margin-bottom: 16px;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/ArrayFieldTemplate/index.tsx",
    "content": "import {\n  ArrayFieldTemplateItemType,\n  ArrayFieldTemplateProps,\n  FormContextType,\n  GenericObjectType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  getTemplate,\n  getUiOptions,\n} from \"@rjsf/utils\"\nimport { Col, Row } from \"@illa-design/react\"\nimport { fieldsetStyle } from \"./style\"\n\nconst DESCRIPTION_COL_STYLE = {\n  paddingBottom: \"8px\",\n}\n\nexport default function ArrayFieldTemplate<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: ArrayFieldTemplateProps<T, S, F>) {\n  const {\n    canAdd,\n    className,\n    disabled,\n    formContext,\n    idSchema,\n    items,\n    onAddClick,\n    readonly,\n    registry,\n    required,\n    schema,\n    title,\n    uiSchema,\n  } = props\n  const uiOptions = getUiOptions<T, S, F>(uiSchema)\n  const ArrayFieldDescriptionTemplate = getTemplate<\n    \"ArrayFieldDescriptionTemplate\",\n    T,\n    S,\n    F\n  >(\"ArrayFieldDescriptionTemplate\", registry, uiOptions)\n  const ArrayFieldItemTemplate = getTemplate<\"ArrayFieldItemTemplate\", T, S, F>(\n    \"ArrayFieldItemTemplate\",\n    registry,\n    uiOptions,\n  )\n  const ArrayFieldTitleTemplate = getTemplate<\n    \"ArrayFieldTitleTemplate\",\n    T,\n    S,\n    F\n  >(\"ArrayFieldTitleTemplate\", registry, uiOptions)\n  const {\n    ButtonTemplates: { AddButton },\n  } = registry.templates\n  const { rowGutter = 24 } = formContext as GenericObjectType\n\n  return (\n    <fieldset className={className} id={idSchema.$id} css={fieldsetStyle}>\n      <Row>\n        {(uiOptions.title || title) && (\n          <Col span={24}>\n            <ArrayFieldTitleTemplate\n              idSchema={idSchema}\n              required={required}\n              title={uiOptions.title || title}\n              schema={schema}\n              uiSchema={uiSchema}\n              registry={registry}\n            />\n          </Col>\n        )}\n        {(uiOptions.description || schema.description) && (\n          <Col span={24} style={DESCRIPTION_COL_STYLE}>\n            <ArrayFieldDescriptionTemplate\n              description={uiOptions.description || schema.description}\n              idSchema={idSchema}\n              schema={schema}\n              uiSchema={uiSchema}\n              registry={registry}\n            />\n          </Col>\n        )}\n        <Col span={24}>\n          {items &&\n            Array.isArray(items) &&\n            items.map(\n              ({ key, ...itemProps }: ArrayFieldTemplateItemType<T, S, F>) => (\n                <ArrayFieldItemTemplate key={key} {...itemProps} />\n              ),\n            )}\n        </Col>\n\n        {canAdd && (\n          <Col span={24}>\n            <Row verticalGap={rowGutter} justify=\"end\">\n              <Col flex=\"192px\">\n                <AddButton\n                  className=\"array-item-add\"\n                  disabled={disabled || readonly}\n                  onClick={onAddClick}\n                  uiSchema={uiSchema}\n                  registry={registry}\n                />\n              </Col>\n            </Row>\n          </Col>\n        )}\n      </Row>\n    </fieldset>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/ArrayFieldTemplate/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const fieldsetStyle = css`\n  border: none;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/BaseInputTemplate/index.tsx",
    "content": "import {\n  BaseInputTemplateProps,\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  ariaDescribedByIds,\n  examplesId,\n  getInputProps,\n} from \"@rjsf/utils\"\nimport { FocusEvent } from \"react\"\nimport { Input, Password } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function BaseInputTemplate<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: BaseInputTemplateProps<T, S, F>) {\n  const {\n    id,\n    type,\n    value,\n    label,\n    schema,\n    onChange,\n    onBlur,\n    onFocus,\n    options,\n    required,\n    readonly,\n    rawErrors,\n    autofocus,\n    placeholder,\n    disabled,\n    formContext,\n  } = props\n  const inputProps = getInputProps<T, S, F>(schema, type, options)\n\n  const _onChange = (value: string) =>\n    onChange(value === \"\" ? options.emptyValue : value)\n  const _onBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>\n    onBlur(id, value)\n  const _onFocus = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>\n    onFocus(id, value)\n\n  return (\n    <LabelWrapper required={required} label={label}>\n      {type === \"password\" ? (\n        <Password\n          id={id}\n          error={rawErrors && rawErrors.length > 0}\n          disabled={disabled}\n          readOnly={readonly}\n          value={value || value === 0 ? value : \"\"}\n          onChange={_onChange}\n          onBlur={_onBlur}\n          onFocus={_onFocus}\n          autoFocus={autofocus}\n          placeholder={placeholder}\n          colorScheme={formContext?.themeColor}\n          aria-describedby={ariaDescribedByIds<T>(id, !!schema.examples)}\n        />\n      ) : (\n        <>\n          <Input\n            id={id}\n            error={rawErrors && rawErrors.length > 0}\n            disabled={disabled}\n            readOnly={readonly}\n            value={value || value === 0 ? value : \"\"}\n            onChange={_onChange}\n            onBlur={_onBlur}\n            onFocus={_onFocus}\n            autoFocus={autofocus}\n            placeholder={placeholder}\n            colorScheme={formContext?.themeColor}\n            {...inputProps}\n            list={schema.examples ? examplesId<T>(id) : undefined}\n            aria-describedby={ariaDescribedByIds<T>(id, !!schema.examples)}\n          />\n          {Array.isArray(schema.examples) ? (\n            <datalist id={examplesId<T>(id)}>\n              {(schema.examples as string[])\n                .concat(\n                  schema.default && !schema.examples.includes(schema.default)\n                    ? ([schema.default] as string[])\n                    : [],\n                )\n                .map((example: string) => {\n                  return <option key={example} value={example} />\n                })}\n            </datalist>\n          ) : null}\n        </>\n      )}\n    </LabelWrapper>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/DescriptionField/index.tsx",
    "content": "import {\n  DescriptionFieldProps,\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n} from \"@rjsf/utils\"\nimport { descriptionStyle } from \"./style\"\n\nexport default function DescriptionField<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: DescriptionFieldProps<T, S, F>) {\n  const { id, description } = props\n  if (!description) {\n    return null\n  }\n  return (\n    <div id={id} css={descriptionStyle}>\n      {description}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/DescriptionField/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const descriptionStyle = css`\n  margin: 8px 0 16px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-weight: 400;\n  font-size: 14px;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/ErrorList/index.tsx",
    "content": "import {\n  ErrorListProps,\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  TranslatableString,\n} from \"@rjsf/utils\"\nimport { Alert, List } from \"@illa-design/react\"\nimport { errorDetailStyle } from \"./style\"\n\nexport default function ErrorList<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>({ errors, registry }: ErrorListProps<T, S, F>) {\n  const { translateString } = registry\n  return (\n    <Alert\n      showIcon\n      type=\"error\"\n      title={translateString(TranslatableString.ErrorsLabel)}\n      content={\n        <List\n          data={errors}\n          renderKey={(data, index) => {\n            return index.toString()\n          }}\n          render={(error, index) => {\n            return (\n              <span key={index} css={errorDetailStyle}>\n                {error?.stack}\n              </span>\n            )\n          }}\n        ></List>\n      }\n    />\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/ErrorList/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const errorDetailStyle = css`\n  font-size: 14px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/FieldTemplate/index.tsx",
    "content": "import {\n  FieldTemplateProps,\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  getTemplate,\n  getUiOptions,\n} from \"@rjsf/utils\"\nimport { Text } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function FieldTemplate<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: FieldTemplateProps<T, S, F>) {\n  const {\n    id,\n    children,\n    classNames,\n    style,\n    disabled,\n    displayLabel,\n    hidden,\n    label,\n    onDropPropertyClick,\n    onKeyChange,\n    readonly,\n    registry,\n    required,\n    help,\n    description,\n    rawDescription,\n    schema,\n    uiSchema,\n  } = props\n  const uiOptions = getUiOptions<T, S, F>(uiSchema)\n  const WrapIfAdditionalTemplate = getTemplate<\n    \"WrapIfAdditionalTemplate\",\n    T,\n    S,\n    F\n  >(\"WrapIfAdditionalTemplate\", registry, uiOptions)\n\n  if (hidden) {\n    return <div style={{ display: \"none\" }}>{children}</div>\n  }\n\n  return (\n    <WrapIfAdditionalTemplate\n      classNames={classNames}\n      style={style}\n      disabled={disabled}\n      id={id}\n      label={label}\n      onDropPropertyClick={onDropPropertyClick}\n      onKeyChange={onKeyChange}\n      readonly={readonly}\n      required={required}\n      schema={schema}\n      uiSchema={uiSchema}\n      registry={registry}\n    >\n      <LabelWrapper required={required}>\n        {children}\n        {displayLabel && rawDescription ? (\n          <Text style={{ marginTop: \"8px\" }}>{description}</Text>\n        ) : null}\n        <Text style={{ marginTop: \"8px\" }}>{help}</Text>\n      </LabelWrapper>\n    </WrapIfAdditionalTemplate>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/IconButton/index.tsx",
    "content": "import {\n  FormContextType,\n  IconButtonProps,\n  RJSFSchema,\n  StrictRJSFSchema,\n} from \"@rjsf/utils\"\nimport {\n  AddIcon,\n  Button,\n  CopyIcon,\n  DeleteIcon,\n  DownIcon,\n  UpIcon,\n} from \"@illa-design/react\"\nimport { iconButtonStyle } from \"./style\"\n\nexport function IconButton<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: IconButtonProps<T, S, F>) {\n  const { icon, ...otherProps } = props\n  return (\n    <Button {...otherProps} leftIcon={icon}>\n      {props.title}\n    </Button>\n  )\n}\n\nexport function AddButton<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>({ registry, ...props }: IconButtonProps<T, S, F>) {\n  const { formContext } = registry\n  return (\n    <Button\n      leftIcon={<AddIcon />}\n      {...props}\n      css={iconButtonStyle}\n      colorScheme={formContext?.themeColor}\n    />\n  )\n}\n\nexport function CopyButton<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: IconButtonProps<T, S, F>) {\n  const {\n    registry: { formContext },\n  } = props\n  return (\n    <Button\n      leftIcon={<CopyIcon />}\n      {...props}\n      css={iconButtonStyle}\n      colorScheme={formContext?.themeColor}\n    />\n  )\n}\n\nexport function MoveDownButton<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: IconButtonProps<T, S, F>) {\n  const {\n    registry: { formContext },\n  } = props\n  return (\n    <Button\n      leftIcon={<DownIcon />}\n      {...props}\n      css={iconButtonStyle}\n      colorScheme={formContext?.themeColor}\n    />\n  )\n}\n\nexport function MoveUpButton<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: IconButtonProps<T, S, F>) {\n  const {\n    registry: { formContext },\n  } = props\n  return (\n    <Button\n      leftIcon={<UpIcon />}\n      {...props}\n      css={iconButtonStyle}\n      colorScheme={formContext?.themeColor}\n    />\n  )\n}\n\nexport function RemoveButton<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: IconButtonProps<T, S, F>) {\n  return (\n    <Button\n      colorScheme=\"red\"\n      leftIcon={<DeleteIcon />}\n      {...props}\n      css={iconButtonStyle}\n    />\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/IconButton/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const iconButtonStyle = css`\n  padding: 5px 16px;\n  width: auto !important;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/ObjectFieldTemplate/index.tsx",
    "content": "import {\n  FormContextType,\n  GenericObjectType,\n  ObjectFieldTemplatePropertyType,\n  ObjectFieldTemplateProps,\n  RJSFSchema,\n  StrictRJSFSchema,\n  UiSchema,\n  canExpand,\n  descriptionId,\n  getTemplate,\n  getUiOptions,\n  titleId,\n} from \"@rjsf/utils\"\nimport { isNumber, isObject, isString } from \"lodash-es\"\nimport { Col, Row } from \"@illa-design/react\"\n\nexport default function ObjectFieldTemplate<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: ObjectFieldTemplateProps<T, S, F>) {\n  const {\n    description,\n    title,\n    properties,\n    formContext,\n    required,\n    disabled,\n    readonly,\n    uiSchema,\n    idSchema,\n    schema,\n    formData,\n    onAddClick,\n    registry,\n  } = props\n  const uiOptions = getUiOptions<T, S, F>(uiSchema)\n  const TitleFieldTemplate = getTemplate<\"TitleFieldTemplate\", T, S, F>(\n    \"TitleFieldTemplate\",\n    registry,\n    uiOptions,\n  )\n  const DescriptionFieldTemplate = getTemplate<\n    \"DescriptionFieldTemplate\",\n    T,\n    S,\n    F\n  >(\"DescriptionFieldTemplate\", registry, uiOptions)\n  // Button templates are not overridden in the uiSchema\n  const {\n    ButtonTemplates: { AddButton },\n  } = registry.templates\n\n  const { colSpan = 24 } = formContext as GenericObjectType\n\n  const findSchema = (element: ObjectFieldTemplatePropertyType): S =>\n    element.content.props.schema\n\n  const findSchemaType = (element: ObjectFieldTemplatePropertyType) =>\n    findSchema(element).type\n\n  const findUiSchema = (\n    element: ObjectFieldTemplatePropertyType,\n  ): UiSchema<T, S, F> | undefined => element.content.props.uiSchema\n\n  const findUiSchemaField = (element: ObjectFieldTemplatePropertyType) =>\n    getUiOptions(findUiSchema(element)).field\n\n  const findUiSchemaWidget = (element: ObjectFieldTemplatePropertyType) =>\n    getUiOptions(findUiSchema(element)).widget\n\n  const calculateColSpan = (element: ObjectFieldTemplatePropertyType) => {\n    const type = findSchemaType(element)\n    const field = findUiSchemaField(element)\n    const widget = findUiSchemaWidget(element)\n\n    const defaultColSpan =\n      properties.length < 2 || // Single or no field in object.\n      type === \"object\" ||\n      type === \"array\" ||\n      widget === \"textarea\"\n        ? 24\n        : 12\n\n    if (isObject(colSpan)) {\n      const colSpanObj: GenericObjectType = colSpan\n      if (isString(widget)) {\n        return colSpanObj[widget]\n      }\n      if (isString(field)) {\n        return colSpanObj[field]\n      }\n      if (isString(type)) {\n        return colSpanObj[type]\n      }\n    }\n    if (isNumber(colSpan)) {\n      return colSpan\n    }\n    return defaultColSpan\n  }\n\n  return (\n    <>\n      <Row w=\"100%\">\n        {title && (\n          <TitleFieldTemplate\n            id={titleId<T>(idSchema)}\n            title={title}\n            required={required}\n            schema={schema}\n            uiSchema={uiSchema}\n            registry={registry}\n          />\n        )}\n      </Row>\n      <Row>\n        {description && (\n          <DescriptionFieldTemplate\n            id={descriptionId<T>(idSchema)}\n            description={description}\n            schema={schema}\n            uiSchema={uiSchema}\n            registry={registry}\n          />\n        )}\n        {properties.map((element, index) =>\n          element.hidden ? (\n            element.content\n          ) : (\n            <Col\n              key={`${idSchema.$id}-${element.name}-${index}`}\n              span={calculateColSpan(element)}\n            >\n              {element.content}\n            </Col>\n          ),\n        )}\n      </Row>\n\n      {canExpand(schema, uiSchema, formData) && (\n        <Col span={24}>\n          <Row justify=\"end\">\n            <Col flex=\"192px\">\n              <AddButton\n                className=\"object-property-expand\"\n                disabled={disabled || readonly}\n                onClick={onAddClick(schema)}\n                uiSchema={uiSchema}\n                registry={registry}\n              />\n            </Col>\n          </Row>\n        </Col>\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/SubmitButton/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  SubmitButtonProps,\n  getSubmitButtonOptions,\n} from \"@rjsf/utils\"\nimport { Button } from \"@illa-design/react\"\n\nexport default function SubmitButton<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: SubmitButtonProps<T, S, F>) {\n  const { uiSchema } = props\n  const { formContext } = props.registry\n  const {\n    submitText,\n    norender,\n    props: submitButtonProps,\n  } = getSubmitButtonOptions(uiSchema)\n  if (formContext?.hiddenSubmitButton || norender) {\n    return null\n  }\n  return (\n    <Button\n      mt=\"24px\"\n      type=\"submit\"\n      fullWidth={formContext?.submitButtonFullWidth}\n      colorScheme={formContext?.themeColor}\n      {...submitButtonProps}\n    >\n      {formContext?.submitButtonText || submitText}\n    </Button>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/TitleField/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  TitleFieldProps,\n} from \"@rjsf/utils\"\nimport { Divider, Heading } from \"@illa-design/react\"\nimport { titleFieldStyle } from \"./style\"\n\nexport default function TitleField<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>({ id, title }: TitleFieldProps<T, S, F>) {\n  return (\n    <div id={id} css={titleFieldStyle}>\n      <Heading level=\"h5\" colorScheme=\"grayBlue\">\n        {title}\n      </Heading>\n      <Divider />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/TitleField/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const titleFieldStyle = css`\n  margin: 8px 0;\n  width: 100%;\n  h5 {\n    font-size: 16px;\n    margin: 0;\n    margin-bottom: 4px;\n    font-weight: 600;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/WrapIfAdditionalTemplate/index.tsx",
    "content": "import {\n  ADDITIONAL_PROPERTY_FLAG,\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  TranslatableString,\n  WrapIfAdditionalTemplateProps,\n} from \"@rjsf/utils\"\nimport { FocusEvent } from \"react\"\nimport { Col, Input, Row } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function WrapIfAdditionalTemplate<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WrapIfAdditionalTemplateProps<T, S, F>) {\n  const {\n    children,\n    classNames,\n    style,\n    disabled,\n    id,\n    label,\n    onDropPropertyClick,\n    onKeyChange,\n    readonly,\n    registry,\n    required,\n    schema,\n    uiSchema,\n  } = props\n  const { templates, translateString } = registry\n  const { RemoveButton } = templates.ButtonTemplates\n  const keyLabel = translateString(TranslatableString.KeyLabel, [label])\n  const additional = ADDITIONAL_PROPERTY_FLAG in schema\n  if (!additional) {\n    return (\n      <div className={classNames} style={style}>\n        {children}\n      </div>\n    )\n  }\n\n  const handleBlur = ({ target }: FocusEvent<HTMLInputElement>) =>\n    onKeyChange(target.value)\n\n  return (\n    <Row\n      key={`${id}-key`}\n      className={classNames}\n      style={style}\n      align=\"center\"\n      verticalGap=\"8px\"\n      horizontalGap=\"8px\"\n    >\n      <Col>\n        <LabelWrapper required={required} label={keyLabel}>\n          <Input\n            id={`${id}-key`}\n            defaultValue={label}\n            disabled={disabled}\n            onBlur={!readonly ? handleBlur : undefined}\n            type=\"text\"\n            readOnly={readonly}\n          />\n        </LabelWrapper>\n      </Col>\n      <Col>{children}</Col>\n      <Col>\n        <RemoveButton\n          disabled={disabled || readonly}\n          onClick={onDropPropertyClick(label)}\n          uiSchema={uiSchema}\n          registry={registry}\n        />\n      </Col>\n    </Row>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/templates/index.ts",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  TemplatesType,\n} from \"@rjsf/utils\"\nimport ArrayFieldItemTemplate from \"./ArrayFieldItemTemplate\"\nimport ArrayFieldTemplate from \"./ArrayFieldTemplate\"\nimport BaseInputTemplate from \"./BaseInputTemplate\"\nimport DescriptionField from \"./DescriptionField\"\nimport ErrorList from \"./ErrorList\"\nimport FieldTemplate from \"./FieldTemplate\"\nimport {\n  AddButton,\n  CopyButton,\n  MoveDownButton,\n  MoveUpButton,\n  RemoveButton,\n} from \"./IconButton\"\nimport ObjectFieldTemplate from \"./ObjectFieldTemplate\"\nimport SubmitButton from \"./SubmitButton\"\nimport TitleField from \"./TitleField\"\nimport WrapIfAdditionalTemplate from \"./WrapIfAdditionalTemplate\"\n\nexport function generateTemplates<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(): Partial<TemplatesType<T, S, F>> {\n  return {\n    ArrayFieldItemTemplate,\n    ArrayFieldTemplate,\n    BaseInputTemplate,\n    ButtonTemplates: {\n      AddButton,\n      CopyButton,\n      MoveDownButton,\n      MoveUpButton,\n      RemoveButton,\n      SubmitButton,\n    },\n    DescriptionFieldTemplate: DescriptionField,\n    ErrorListTemplate: ErrorList,\n    FieldTemplate,\n    ObjectFieldTemplate,\n    TitleFieldTemplate: TitleField,\n    WrapIfAdditionalTemplate,\n  }\n}\n\nexport default generateTemplates()\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/AltDateTimeWidget/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n} from \"@rjsf/utils\"\nimport _AltDateWidget from \"../AltDateWidget\"\n\nfunction AltDateTimeWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WidgetProps<T, S, F>) {\n  const { AltDateWidget } = props.registry.widgets\n  return <AltDateWidget {...props} showTime />\n}\n\nAltDateTimeWidget.defaultProps = {\n  ..._AltDateWidget.defaultProps,\n  showTime: true,\n}\n\nexport default AltDateTimeWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/AltDateWidget/index.tsx",
    "content": "import {\n  DateObject,\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  TranslatableString,\n  WidgetProps,\n  ariaDescribedByIds,\n  pad,\n  parseDateString,\n  toDateString,\n} from \"@rjsf/utils\"\nimport { MouseEvent, useEffect, useState } from \"react\"\nimport { Button } from \"@illa-design/react\"\nimport { altDateBtnStyle, dateContainerStyle, elementStyle } from \"./style\"\n\nconst rangeOptions = (start: number, stop: number) => {\n  const options = []\n  for (let i = start; i <= stop; i++) {\n    options.push({ value: i, label: pad(i, 2) })\n  }\n  return options\n}\n\nfunction DateElement<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WidgetProps<T, S, F>) {\n  const { SelectWidget } = props.registry.widgets\n  const value = props.value ? props.value : undefined\n  return (\n    <SelectWidget\n      {...props}\n      label={\"\"}\n      className=\"form-control\"\n      onChange={(elemValue: WidgetProps<T, S, F>) =>\n        props.select(props.type, elemValue)\n      }\n      options={{\n        enumOptions: rangeOptions(props.range[0], props.range[1]),\n      }}\n      placeholder={props.type}\n      schema={{ type: \"integer\" } as S}\n      value={value}\n      aria-describedby={ariaDescribedByIds<T>(props.name)}\n    />\n  )\n}\n\ninterface AltDateStateType extends DateObject {\n  [x: string]: number | undefined\n}\n\nconst readyForChange = (state: AltDateStateType) => {\n  return Object.keys(state).every(\n    (key) => typeof state[key] !== \"undefined\" && state[key] !== -1,\n  )\n}\n\nfunction AltDateWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WidgetProps<T, S, F>) {\n  const {\n    autofocus,\n    disabled,\n    id,\n    onBlur,\n    onChange,\n    onFocus,\n    options,\n    readonly,\n    registry,\n    showTime,\n    value,\n  } = props\n  const { translateString, formContext } = registry\n  const [state, setState] = useState(parseDateString(value, showTime))\n  useEffect(() => {\n    setState(parseDateString(value, showTime))\n  }, [showTime, value])\n\n  const handleChange = (property: string, nextValue: string) => {\n    const nextState = {\n      ...state,\n      [property]: typeof nextValue === \"undefined\" ? -1 : nextValue,\n    }\n\n    if (readyForChange(nextState)) {\n      onChange(toDateString(nextState, showTime))\n    } else {\n      setState(nextState)\n    }\n  }\n\n  const handleNow = (event: MouseEvent<HTMLButtonElement>) => {\n    event.preventDefault()\n    if (disabled || readonly) {\n      return\n    }\n    const nextState = parseDateString(new Date().toJSON(), showTime)\n    onChange(toDateString(nextState, showTime))\n  }\n\n  const handleClear = (event: MouseEvent<HTMLButtonElement>) => {\n    event.preventDefault()\n    if (disabled || readonly) {\n      return\n    }\n    onChange(undefined)\n  }\n\n  const dateElementProps = () => {\n    const { year, month, day, hour, minute, second } = state\n\n    const data: { type: string; range: number[]; value?: number }[] = [\n      { type: \"year\", range: options.yearsRange as number[], value: year },\n      { type: \"month\", range: [1, 12], value: month },\n      { type: \"day\", range: [1, 31], value: day },\n    ]\n\n    if (showTime) {\n      data.push(\n        { type: \"hour\", range: [0, 23], value: hour },\n        { type: \"minute\", range: [0, 59], value: minute },\n        { type: \"second\", range: [0, 59], value: second },\n      )\n    }\n\n    return data\n  }\n\n  return (\n    <div>\n      <div css={dateContainerStyle}>\n        {dateElementProps().map((elemProps, i) => {\n          const elemId = id + \"_\" + elemProps.type\n          return (\n            <div key={elemId} css={elementStyle}>\n              <DateElement<T, S, F>\n                {...props}\n                {...elemProps}\n                autofocus={autofocus && i === 0}\n                disabled={disabled}\n                id={elemId}\n                name={id}\n                onBlur={onBlur}\n                onFocus={onFocus}\n                readonly={readonly}\n                registry={registry}\n                select={handleChange}\n                value={\n                  !elemProps || !elemProps.value || elemProps.value < 0\n                    ? \"\"\n                    : elemProps.value\n                }\n              />\n            </div>\n          )\n        })}\n      </div>\n      <div css={altDateBtnStyle}>\n        {!options.hideNowButton && (\n          <Button\n            onClick={(e: MouseEvent<HTMLButtonElement>) => handleNow(e)}\n            colorScheme={formContext?.themeColor}\n          >\n            {translateString(TranslatableString.NowLabel)}\n          </Button>\n        )}\n        {!options.hideClearButton && (\n          <Button\n            onClick={(e: MouseEvent<HTMLButtonElement>) => handleClear(e)}\n            colorScheme={formContext?.themeColor}\n          >\n            {translateString(TranslatableString.ClearLabel)}\n          </Button>\n        )}\n      </div>\n    </div>\n  )\n}\n\nAltDateWidget.defaultProps = {\n  autofocus: false,\n  disabled: false,\n  readonly: false,\n  showTime: false,\n  options: {\n    yearsRange: [1900, new Date().getFullYear() + 2],\n  },\n}\n\nexport default AltDateWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/AltDateWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const dateContainerStyle = css`\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n`\n\nexport const elementStyle = css`\n  margin-right: 8px;\n  margin-bottom: 8px;\n`\n\nexport const altDateBtnStyle = css`\n  display: flex;\n  gap: 8px;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/CheckboxWidget/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  ariaDescribedByIds,\n  descriptionId,\n  getTemplate,\n  schemaRequiresTrueValue,\n} from \"@rjsf/utils\"\nimport { Checkbox } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function CheckboxWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WidgetProps<T, S, F>) {\n  const {\n    id,\n    value,\n    disabled,\n    readonly,\n    onChange,\n    label,\n    hideLabel,\n    registry,\n    options,\n    uiSchema,\n    schema,\n    formContext,\n  } = props\n\n  const required = schemaRequiresTrueValue<S>(schema)\n  const DescriptionFieldTemplate = getTemplate<\n    \"DescriptionFieldTemplate\",\n    T,\n    S,\n    F\n  >(\"DescriptionFieldTemplate\", registry, options)\n  const description = options.description || schema.description\n\n  const _onChange = (value: boolean) => onChange(value)\n\n  return (\n    <>\n      <LabelWrapper required={required} label={label} isSingleLine>\n        <Checkbox\n          colorScheme={formContext?.themeColor}\n          id={id}\n          disabled={disabled || readonly}\n          checked={value ?? false}\n          onChange={_onChange}\n          aria-describedby={ariaDescribedByIds<T>(id)}\n        />\n      </LabelWrapper>\n      {!hideLabel && !!description && (\n        <DescriptionFieldTemplate\n          id={descriptionId<T>(id)}\n          description={description}\n          schema={schema}\n          uiSchema={uiSchema}\n          registry={registry}\n        />\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/CheckboxesWidget/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  ariaDescribedByIds,\n  enumOptionsValueForIndex,\n} from \"@rjsf/utils\"\nimport { FocusEvent } from \"react\"\nimport { CheckboxGroup } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function CheckboxesWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WidgetProps<T, S, F>) {\n  const {\n    id,\n    disabled,\n    options,\n    value,\n    readonly,\n    onChange,\n    onBlur,\n    onFocus,\n    required,\n    className,\n    label,\n    formContext,\n  } = props\n  const { enumOptions, enumDisabled, emptyValue } = options\n  const _onBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>\n    onBlur(id, enumOptionsValueForIndex<S>(value, enumOptions, emptyValue))\n  const _onFocus = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>\n    onFocus(id, enumOptionsValueForIndex<S>(value, enumOptions, emptyValue))\n\n  const row = options ? options.inline : false\n\n  return (\n    <div className={className}>\n      <LabelWrapper required={required} label={label}>\n        <CheckboxGroup\n          id={id}\n          colorScheme={formContext?.themeColor}\n          direction={row ? \"horizontal\" : \"vertical\"}\n          disabled={disabled || readonly}\n          value={value}\n          onChange={(option) => onChange(option)}\n          onBlur={_onBlur}\n          onFocus={_onFocus}\n          options={enumOptions?.map(({ value, label }) => ({\n            value,\n            label,\n            disabled:\n              Array.isArray(enumDisabled) && enumDisabled.indexOf(value) !== -1,\n          }))}\n          aria-describedby={ariaDescribedByIds<T>(id)}\n        />\n      </LabelWrapper>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/DateTimeWidget/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  ariaDescribedByIds,\n} from \"@rjsf/utils\"\nimport { SingleDatePicker } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function DateTimeWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WidgetProps<T, S, F>) {\n  const {\n    id,\n    readonly,\n    disabled,\n    label,\n    value,\n    onChange,\n    rawErrors,\n    required,\n    formContext,\n  } = props\n\n  const _onChange = (value: undefined | string) => onChange(value)\n\n  return (\n    <LabelWrapper required={required} label={label}>\n      <SingleDatePicker\n        showTime\n        colorScheme={formContext?.themeColor}\n        error={rawErrors && rawErrors.length > 0}\n        disabled={disabled || readonly}\n        value={value ?? \"\"}\n        onChange={_onChange}\n        aria-describedby={ariaDescribedByIds<T>(id)}\n      />\n    </LabelWrapper>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/DateWidget/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  ariaDescribedByIds,\n} from \"@rjsf/utils\"\nimport { SingleDatePicker } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function DateWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WidgetProps<T, S, F>) {\n  const {\n    id,\n    readonly,\n    disabled,\n    label,\n    value,\n    onChange,\n    rawErrors,\n    required,\n    formContext,\n  } = props\n\n  const _onChange = (value: undefined | string) => onChange(value)\n\n  return (\n    <LabelWrapper required={required} label={label}>\n      <SingleDatePicker\n        colorScheme={formContext?.themeColor}\n        error={rawErrors && rawErrors.length > 0}\n        disabled={disabled || readonly}\n        value={value ?? \"\"}\n        onChange={_onChange}\n        aria-describedby={ariaDescribedByIds<T>(id)}\n      />\n    </LabelWrapper>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/RadioWidget/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  ariaDescribedByIds,\n  enumOptionsValueForIndex,\n} from \"@rjsf/utils\"\nimport { FocusEvent } from \"react\"\nimport { RadioGroup } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function RadioWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>({\n  id,\n  options,\n  required,\n  disabled,\n  value,\n  readonly,\n  label,\n  formContext,\n  onChange,\n  onBlur,\n  onFocus,\n}: WidgetProps<T, S, F>) {\n  const { enumOptions, enumDisabled, emptyValue } = options\n\n  const _onChange = (value: unknown) => {\n    onChange(value)\n  }\n  const _onBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>\n    onBlur(id, enumOptionsValueForIndex<S>(value, enumOptions, emptyValue))\n  const _onFocus = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>\n    onFocus(id, enumOptionsValueForIndex<S>(value, enumOptions, emptyValue))\n\n  return (\n    <LabelWrapper required={required} label={label}>\n      <RadioGroup\n        colorScheme={formContext?.themeColor}\n        disabled={disabled || readonly}\n        id={id}\n        name={id}\n        onChange={_onChange}\n        onBlur={_onBlur}\n        value={value}\n        onFocus={_onFocus}\n        options={enumOptions?.map(({ value, label }) => ({\n          value,\n          label,\n          disabled:\n            Array.isArray(enumDisabled) && enumDisabled.indexOf(value) !== -1,\n        }))}\n        aria-describedby={ariaDescribedByIds<T>(id)}\n      />\n    </LabelWrapper>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/RangeWidget/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  ariaDescribedByIds,\n  rangeSpec,\n} from \"@rjsf/utils\"\nimport { FocusEvent } from \"react\"\nimport { Slider } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function RangeWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>({\n  value,\n  readonly,\n  disabled,\n  onBlur,\n  onFocus,\n  options,\n  schema,\n  required,\n  onChange,\n  label,\n  id,\n  formContext,\n}: WidgetProps<T, S, F>) {\n  const sliderWidgetProps = { value, label, id, ...rangeSpec<S>(schema) }\n\n  const _onChange = (value: number | number[]) => {\n    onChange(value === undefined ? options.emptyValue : value)\n  }\n  const _onBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>\n    onBlur(id, value)\n  const _onFocus = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>\n    onFocus(id, value)\n\n  return (\n    <LabelWrapper label={label} required={required}>\n      <Slider\n        {...sliderWidgetProps}\n        id={id}\n        colorScheme={formContext?.themeColor}\n        disabled={disabled || readonly}\n        value={value}\n        onChange={_onChange}\n        onBlur={_onBlur}\n        onFocus={_onFocus}\n        aria-describedby={ariaDescribedByIds<T>(id)}\n      />\n    </LabelWrapper>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/SelectWidget/index.tsx",
    "content": "import {\n  EnumOptionsType,\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  ariaDescribedByIds,\n  enumOptionsIndexForValue,\n  enumOptionsValueForIndex,\n} from \"@rjsf/utils\"\nimport { Select, SelectOptionObject } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function SelectWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WidgetProps<T, S, F>) {\n  const {\n    id,\n    options,\n    label,\n    placeholder,\n    multiple,\n    required,\n    disabled,\n    readonly,\n    value,\n    formContext,\n    onChange,\n    onBlur,\n    onFocus,\n    rawErrors = [],\n  } = props\n  const { enumOptions, enumDisabled, emptyValue } = options\n\n  const _onChange = (value: unknown) => {\n    if (\n      typeof value === \"string\" ||\n      value === \"number\" ||\n      Array.isArray(value)\n    ) {\n      onChange(\n        enumOptionsValueForIndex<S>(value ?? \"\", enumOptions, emptyValue),\n      )\n    }\n  }\n\n  const _onBlur = () =>\n    onBlur(id, enumOptionsValueForIndex<S>(value, enumOptions, emptyValue))\n\n  const _onFocus = () =>\n    onFocus(id, enumOptionsValueForIndex<S>(value, enumOptions, emptyValue))\n\n  const _valueLabelMap: Record<number, unknown> = {}\n  const displayEnumOptions: SelectOptionObject[] = Array.isArray(enumOptions)\n    ? enumOptions.map((option: EnumOptionsType<S>, index: number) => {\n        const { value, label } = option\n        _valueLabelMap[index] = label || String(value)\n        return {\n          label,\n          value: String(index),\n          isDisabled:\n            Array.isArray(enumDisabled) && enumDisabled.indexOf(value) !== -1,\n        }\n      })\n    : []\n\n  const isMultiple = typeof multiple !== \"undefined\" && Boolean(enumOptions)\n  const selectedIndex = enumOptionsIndexForValue<S>(\n    value,\n    enumOptions,\n    isMultiple,\n  )\n  const formValue: string | string[] = isMultiple\n    ? ((selectedIndex as string[]) || []).map((v: string) => {\n        return `${v || \"\"}`\n      })\n    : `${selectedIndex || \"\"}`\n\n  return (\n    <LabelWrapper required={required} label={label}>\n      <Select\n        id={id}\n        colorScheme={formContext?.themeColor}\n        disabled={disabled}\n        error={rawErrors && rawErrors.length > 0}\n        readOnly={readonly}\n        value={formValue}\n        placeholder={placeholder}\n        multiple={isMultiple}\n        onChange={_onChange}\n        onBlur={_onBlur}\n        onFocus={_onFocus}\n        aria-describedby={ariaDescribedByIds<T>(id)}\n        options={displayEnumOptions}\n      />\n    </LabelWrapper>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/TextareaWidget/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  ariaDescribedByIds,\n} from \"@rjsf/utils\"\nimport { FocusEvent } from \"react\"\nimport { TextArea } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function TextareaWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>({\n  id,\n  placeholder,\n  value,\n  label,\n  disabled,\n  readonly,\n  onBlur,\n  onFocus,\n  onChange,\n  options,\n  required,\n  rawErrors,\n  formContext,\n}: WidgetProps<T, S, F>) {\n  const _onChange = (value: string | undefined) =>\n    onChange(value === \"\" ? options.emptyValue : value)\n  const _onBlur = ({ target: { value } }: FocusEvent<HTMLTextAreaElement>) =>\n    onBlur(id, value)\n  const _onFocus = ({ target: { value } }: FocusEvent<HTMLTextAreaElement>) =>\n    onFocus(id, value)\n\n  return (\n    <LabelWrapper required={required} label={label}>\n      <TextArea\n        id={id}\n        colorScheme={formContext?.themeColor}\n        error={rawErrors && rawErrors.length > 0}\n        disabled={disabled}\n        readOnly={readonly}\n        value={value ?? \"\"}\n        placeholder={placeholder}\n        onChange={_onChange}\n        onBlur={_onBlur}\n        onFocus={_onFocus}\n        aria-describedby={ariaDescribedByIds<T>(id)}\n      />\n    </LabelWrapper>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/TimeWidget/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  ariaDescribedByIds,\n} from \"@rjsf/utils\"\nimport { TimePicker } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function TimeWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WidgetProps<T, S, F>) {\n  const {\n    id,\n    readonly,\n    disabled,\n    label,\n    value,\n    onChange,\n    rawErrors,\n    required,\n    formContext,\n  } = props\n\n  const _onChange = (value: undefined | string) => onChange(value)\n\n  return (\n    <LabelWrapper required={required} label={label}>\n      <TimePicker\n        colorScheme={formContext?.themeColor}\n        error={rawErrors && rawErrors.length > 0}\n        disabled={disabled || readonly}\n        value={value ?? \"\"}\n        onChange={_onChange}\n        aria-describedby={ariaDescribedByIds<T>(id)}\n      />\n    </LabelWrapper>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/UpDownWidget/index.tsx",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  ariaDescribedByIds,\n} from \"@rjsf/utils\"\nimport { FocusEvent } from \"react\"\nimport { InputNumber } from \"@illa-design/react\"\nimport { LabelWrapper } from \"@/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/labelWrapper\"\n\nexport default function UpDownWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(props: WidgetProps<T, S, F>) {\n  const {\n    id,\n    readonly,\n    disabled,\n    label,\n    value,\n    onChange,\n    onBlur,\n    onFocus,\n    rawErrors,\n    required,\n    formContext,\n  } = props\n\n  const _onChange = (value: undefined | number) => onChange(value)\n  const _onBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>\n    onBlur(id, value)\n  const _onFocus = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>\n    onFocus(id, value)\n\n  return (\n    <LabelWrapper required={required} label={label}>\n      <InputNumber\n        id={id}\n        colorScheme={formContext?.themeColor}\n        mode=\"button\"\n        error={rawErrors && rawErrors.length > 0}\n        disabled={disabled}\n        readOnly={readonly}\n        value={value ?? \"\"}\n        onChange={_onChange}\n        onBlur={_onBlur}\n        onFocus={_onFocus}\n        aria-describedby={ariaDescribedByIds<T>(id)}\n      />\n    </LabelWrapper>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/@illadesign-ui/widgets/index.ts",
    "content": "import {\n  FormContextType,\n  RJSFSchema,\n  RegistryWidgetsType,\n  StrictRJSFSchema,\n} from \"@rjsf/utils\"\nimport AltDateTimeWidget from \"./AltDateTimeWidget\"\nimport AltDateWidget from \"./AltDateWidget\"\nimport CheckboxWidget from \"./CheckboxWidget\"\nimport CheckboxesWidget from \"./CheckboxesWidget\"\nimport DateTimeWidget from \"./DateTimeWidget\"\nimport DateWidget from \"./DateWidget\"\nimport RadioWidget from \"./RadioWidget\"\nimport RangeWidget from \"./RangeWidget\"\nimport SelectWidget from \"./SelectWidget\"\nimport TextareaWidget from \"./TextareaWidget\"\nimport TimeWidget from \"./TimeWidget\"\nimport UpDownWidget from \"./UpDownWidget\"\n\nexport function generateWidgets<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = FormContextType,\n>(): RegistryWidgetsType<T, S, F> {\n  return {\n    AltDateTimeWidget,\n    AltDateWidget,\n    DateWidget,\n    TimeWidget,\n    DateTimeWidget,\n    CheckboxWidget,\n    CheckboxesWidget,\n    RadioWidget,\n    RangeWidget,\n    SelectWidget,\n    TextareaWidget,\n    UpDownWidget,\n  }\n}\n\nexport default generateWidgets()\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const JSON_SCHEMA_FORM_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.submit\",\n      ),\n      value: \"submit\",\n    },\n  ],\n  methods: [\"submit\", \"setValue\", \"clearValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/index.ts",
    "content": "export { JSON_SCHEMA_FORM_PANEL_CONFIG } from \"./panelConfig\"\nexport { JSON_SCHEMA_FORM_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { JSON_SCHEMA_FORM_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/interface.ts",
    "content": "import { RJSFSchema, UiSchema } from \"@rjsf/utils\"\nimport { GenIcon, IconBase, IconContext, IconManifest } from \"react-icons\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface RIALL {\n  IconsManifest: IconManifest[]\n  GenIcon: typeof GenIcon\n  IconBase: typeof IconBase\n  DefaultContext: IconContext\n  IconContext: React.Context<IconContext>\n}\n\nexport interface JsonSchemaFormWidgetProps\n  extends WrapperSchemaFormProps,\n    Pick<TooltipWrapperProps, \"tooltipText\"> {\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  dynamicMinHeight?: number\n  dynamicMaxHeight?: number\n}\n\nexport interface WrapperSchemaFormProps extends BaseWidgetProps {\n  JSONSchema?: RJSFSchema\n  UISchema?: UiSchema\n  formData?: Record<string, unknown>\n  disabled?: boolean\n  hiddenSubmitButton?: boolean\n  submitButtonFullWidth?: boolean\n  submitButtonText?: string\n  themeColor?: string\n  handleOnChange?: (formData: Record<string, unknown>) => void\n  handleOnSubmit?: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/jsonSchemaForm.tsx",
    "content": "import FormRef from \"@rjsf/core\"\nimport { debounce } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useRef } from \"react\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { JsonSchemaFormWidgetProps } from \"./interface\"\nimport { WrapperSchemaForm } from \"./wrapperSchemaForm\"\n\nexport const JsonSchemaFormWidget: FC<JsonSchemaFormWidgetProps> = (props) => {\n  const {\n    displayName,\n    dynamicHeight,\n    updateComponentHeight,\n    triggerEventHandler,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n  } = props\n\n  const enableAutoHeight = dynamicHeight !== \"fixed\"\n  const formRef = useRef<FormRef>(null)\n  const onChangeRef = useRef(\n    debounce((formData: unknown) => {\n      if (isObject(formData)) {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              formData,\n            },\n          },\n        ])\n      }\n    }, 180),\n  )\n\n  const handleValidate = useCallback(() => {\n    return new Promise((resolve, reject) => {\n      const result = formRef.current?.validateForm()\n      if (result) {\n        resolve(true)\n      } else {\n        reject(formRef.current?.state.errors)\n      }\n    })\n  }, [])\n\n  const handleOnSubmit = useCallback(() => {\n    triggerEventHandler(\"submit\")\n  }, [triggerEventHandler])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      submit: () => {\n        handleValidate().then(() => {\n          formRef.current?.submit()\n        })\n      },\n      setValue: (formData: unknown) => {\n        if (isObject(formData)) {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                formData,\n              },\n            },\n          ])\n        }\n      },\n      clearValue: () => {\n        formRef.current?.reset()\n      },\n    })\n\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    displayName,\n    handleUpdateMultiExecutionResult,\n    handleValidate,\n    updateComponentRuntimeProps,\n  ])\n\n  return (\n    <AutoHeightContainer\n      updateComponentHeight={updateComponentHeight}\n      enable={enableAutoHeight}\n    >\n      <WrapperSchemaForm\n        ref={formRef}\n        {...props}\n        handleOnChange={onChangeRef.current}\n        handleOnSubmit={handleOnSubmit}\n      />\n    </AutoHeightContainer>\n  )\n}\n\nJsonSchemaFormWidget.displayName = \"JsonSchemaFormWidget\"\nexport default JsonSchemaFormWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/panelConfig.tsx",
    "content": "import RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { JSON_SCHEMA_FORM_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/JsonSchemaFormWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"icon\"\nexport const JSON_SCHEMA_FORM_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-JSONSchema`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.jsonSchemaForm.JSONSchema\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_placeholder.jsonSchemaForm.JSONSchema\",\n        ),\n        attrName: \"JSONSchema\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.OBJECT,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-UISchema`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.jsonSchemaForm.UISchema\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_placeholder.jsonSchemaForm.UISchema\",\n        ),\n        attrName: \"UISchema\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.OBJECT,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-defaultFormData`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.jsonSchemaForm.default_form_data\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_placeholder.jsonSchemaForm.default_form_data\",\n        ),\n        attrName: \"formData\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.OBJECT,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          JSON_SCHEMA_FORM_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        placeholder: \"{{false}}\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-submitButtonText`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.jsonSchemaForm.submit_button_text\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_placeholder.jsonSchemaForm.submit_button_text\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"submitButtonText\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-layout-hiddenSubmitButton`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.jsonSchemaForm.hidden_submit_button\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_placeholder.jsonSchemaForm.hidden_submit_button\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hiddenSubmitButton\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-submitButtonFullWidth`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.jsonSchemaForm.submit_button_full_w\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_placeholder.jsonSchemaForm.submit_button_full_w\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"submitButtonFullWidth\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-height`,\n        labelName: i18n.t(\"editor.inspect.setter_label.height\"),\n        attrName: \"dynamicHeight\",\n        setterType: \"HEIGHT_MODE_SELECT\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.fixed\"),\n            value: \"fixed\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_limited\"),\n            value: \"limited\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_height\"),\n            value: \"auto\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"border\",\n      },\n      {\n        id: `${baseWidgetName}-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-colors-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"themeColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-shadow`,\n            labelName: i18n.t(\"editor.inspect.setter_label.shadow.shadow\"),\n            attrName: \"shadow\",\n            setterType: \"SHADOW_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"small\",\n          },\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            attrName: \"radius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const formGlobalStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  padding: 12px;\n  fieldset {\n    margin: 0;\n    margin-block-end: 0;\n    margin-block-start: 0;\n    margin-inline-end: 0;\n    margin-inline-start: 0;\n    padding-block-end: 0;\n    padding-block-start: 0;\n    padding-inline-end: 0;\n    padding-inline-start: 0;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/widgetConfig.tsx",
    "content": "import JsonSchemaFormWidgetIcon from \"@/assets/widgetCover/jsonSchemaForm.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const JSON_SCHEMA_FORM_WIDGET_CONFIG: WidgetConfig = {\n  type: \"JSON_SCHEMA_FORM_WIDGET\",\n  displayName: \"jsonSchemaForm\",\n  widgetName: i18n.t(\"widget.jsonSchemaForm.name\"),\n  icon: <JsonSchemaFormWidgetIcon />,\n  keywords: [\"jsonSchemaForm\", \"动态表单\"],\n  sessionType: \"INPUTS\",\n  w: 16,\n  h: 40,\n  version: 0,\n  defaults: {\n    hidden: false,\n    JSONSchema: `{{{\n        \"title\": \"A registration form\",\n        \"description\": \"A simple form example.\",\n        \"type\": \"object\",\n        \"required\": [\n          \"firstName\",\n          \"lastName\"\n        ],\n        \"properties\": {\n          \"firstName\": {\n            \"type\": \"string\",\n            \"title\": \"First name\",\n            \"default\": \"Chuck\"\n          },\n          \"lastName\": {\n            \"type\": \"string\",\n            \"title\": \"Last name\"\n          },\n          \"age\": {\n            \"type\": \"integer\",\n            \"title\": \"Age\"\n          },\n          \"bio\": {\n            \"type\": \"string\",\n            \"title\": \"Bio\"\n          },\n          \"password\": {\n            \"type\": \"string\",\n            \"title\": \"Password\",\n            \"minLength\": 3\n          },\n          \"telephone\": {\n            \"type\": \"string\",\n            \"title\": \"Telephone\",\n            \"minLength\": 10\n          }\n        }\n      }}}`,\n    UISchema: `{{{\n        \"firstName\": {\n          \"ui:autofocus\": true,\n          \"ui:emptyValue\": \"\",\n          \"ui:placeholder\": \"ui:emptyValue causes this field to always be valid despite being required\",\n          \"ui:autocomplete\": \"family-name\",\n          \"ui:enableMarkdownInDescription\": true,\n        },\n        \"lastName\": {\n          \"ui:autocomplete\": \"given-name\",\n          \"ui:enableMarkdownInDescription\": true,\n        },\n        \"age\": {\n          \"ui:widget\": \"updown\",\n          \"ui:title\": \"Age of person\",\n          \"ui:description\": \"(earth year)\"\n        },\n        \"bio\": {\n          \"ui:widget\": \"textarea\"\n        },\n        \"password\": {\n          \"ui:widget\": \"password\",\n          \"ui:help\": \"Hint: Make it strong!\"\n        },\n        \"telephone\": {\n          \"ui:options\": {\n            \"inputType\": \"tel\"\n          }\n        }\n      }}}`,\n    formData: `{{{\n        \"firstName\": \"Chuck\",\n        \"lastName\": \"Norris\",\n        \"age\": 75,\n        \"bio\": \"Roundhouse kicking asses since 1940\",\n        \"password\": \"noneed\",\n        \"telephone\": \"1-800-KICKASS\"\n      }}}`,\n    dynamicHeight: \"fixed\",\n    themeColor: \"blue\",\n    radius: \"4px\",\n    shadow: \"small\",\n    disabled: false,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/JsonSchemaFormWidget/wrapperSchemaForm.tsx",
    "content": "import FormRef from \"@rjsf/core\"\nimport validator from \"@rjsf/validator-ajv8\"\nimport { forwardRef } from \"react\"\nimport { Form } from \"./@illadesign-ui\"\nimport { WrapperSchemaFormProps } from \"./interface\"\nimport { formGlobalStyle } from \"./style\"\n\nexport const WrapperSchemaForm = forwardRef<FormRef, WrapperSchemaFormProps>(\n  (\n    {\n      JSONSchema,\n      UISchema,\n      formData,\n      themeColor,\n      submitButtonFullWidth,\n      submitButtonText,\n      hiddenSubmitButton,\n      disabled,\n      handleOnChange,\n      handleOnSubmit,\n    },\n    ref,\n  ) => {\n    if (\n      !JSONSchema ||\n      (JSONSchema.type !== \"object\" && JSONSchema.type !== \"array\")\n    ) {\n      return null\n    }\n    return (\n      <Form\n        ref={ref}\n        disabled={disabled}\n        css={formGlobalStyle}\n        formContext={{\n          themeColor,\n          submitButtonFullWidth,\n          submitButtonText,\n          hiddenSubmitButton,\n        }}\n        schema={JSONSchema || {}}\n        validator={validator}\n        uiSchema={UISchema || {}}\n        formData={formData}\n        onChange={(v) => handleOnChange && handleOnChange(v.formData)}\n        onSubmit={handleOnSubmit}\n      />\n    )\n  },\n)\n\nWrapperSchemaForm.displayName = \"WrapperSchemaForm\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/components/CursorBasedSelector/index.tsx",
    "content": "import { FC } from \"react\"\nimport { NextIcon, PreviousIcon } from \"@illa-design/react\"\nimport { operationIconStyle, selectContainerStyle } from \"./style\"\n\ninterface CursorBasedSelectorProps {\n  hasNextPage?: boolean\n  page: number\n  previousCursor?: string\n  nextCursor?: string\n  onChange: (isNext: boolean) => void\n}\nconst CursorBasedSelector: FC<CursorBasedSelectorProps> = ({\n  hasNextPage,\n  page,\n  onChange,\n}) => {\n  return (\n    <div css={selectContainerStyle}>\n      <span css={operationIconStyle(page <= 0)} onClick={() => onChange(false)}>\n        <PreviousIcon size=\"14px\" />\n      </span>\n      {page + 1}\n      <span\n        css={operationIconStyle(!hasNextPage)}\n        onClick={() => hasNextPage && onChange(true)}\n      >\n        <NextIcon size=\"14px\" />\n      </span>\n    </div>\n  )\n}\n\nexport default CursorBasedSelector\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/components/CursorBasedSelector/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const selectContainerStyle = css`\n  width: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  gap: 8px;\n`\n\nexport const operationIconStyle = (disabled: boolean) => {\n  return css`\n    pointer-events: ${disabled ? \"not-allowed\" : \"auto\"};\n    font-size: 14px;\n    width: 32px;\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    height: 32px;\n    border-radius: 4px;\n    cursor: ${disabled ? \"not-allowed\" : \"pointer\"};\n    color: ${getColor(\"grayBlue\", disabled ? \"08\" : \"03\")};\n    background-color: unset;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/components/ListWidgetWithAutoPagination/index.tsx",
    "content": "import { chunk } from \"lodash-es\"\nimport { Resizable, ResizeCallback, ResizeStartCallback } from \"re-resizable\"\nimport { FC, useCallback, useMemo, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport useMeasure from \"react-use-measure\"\nimport { Pagination } from \"@illa-design/react\"\nimport { applyDashedLineStyle } from \"@/page/App/components/ScaleSquare/style\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getShadowStyle } from \"@/utils/styleUtils/shadow\"\nimport { ListWidgetPropsWithChildrenNodes } from \"@/widgetLibrary/ListWidget/interface\"\nimport {\n  applyListItemStyle,\n  itemContainerStyle,\n  listParentContainerWithPagination,\n  paginationWrapperStyle,\n  selectStyle,\n} from \"@/widgetLibrary/ListWidget/style\"\nimport { resizeBottomHandler } from \"../../utils\"\nimport RenderCopyContainer from \"../RenderCopyContainer\"\nimport RenderTemplateContainer from \"../RenderTemplateContainer\"\n\nconst ListWidgetWithAutoPagination: FC<ListWidgetPropsWithChildrenNodes> = (\n  props,\n) => {\n  const {\n    dataSources,\n    itemHeight = 48,\n    displayName,\n    page = 0,\n    itemPadding,\n    dynamicMinHeight,\n    dynamicMaxHeight,\n    enablePagination,\n    childrenNode,\n    itemGap,\n    itemShadow,\n    itemBorderColor,\n    itemBorderRadius,\n    itemBorderWidth,\n    handleUpdateOriginalDSLMultiAttr,\n    updateComponentHeight,\n    copyComponents,\n    pageSize,\n    handleUpdateSelectedItem,\n    itemBackGroundColor,\n    columnNumber,\n    dynamicHeight = \"fixed\",\n    selectIndexForMark,\n    themeColor,\n    loading,\n    handleUpdateMultiExecutionResult,\n    h,\n  } = props\n  const [containerRef, containerBounds] = useMeasure()\n  const [paginationRef, paginationBounds] = useMeasure()\n  const [isMouseHover, setIsMouseHover] = useState(false)\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const dispatch = useDispatch()\n  const safePageSize = !pageSize ? 0 : pageSize\n\n  const currentContainerBoundsHeight =\n    containerBounds.height - paginationBounds.height\n  const itemNumber = useMemo(() => {\n    if (enablePagination) {\n      return safePageSize\n    } else {\n      return dataSources?.length\n    }\n  }, [dataSources?.length, enablePagination, safePageSize])\n\n  const handleChangeCurrentPage = useCallback(\n    (pageNumber: number) => {\n      handleUpdateSelectedItem()\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            page: pageNumber - 1,\n          },\n        },\n      ])\n    },\n    [displayName, handleUpdateMultiExecutionResult, handleUpdateSelectedItem],\n  )\n\n  const currentData = useMemo(() => {\n    const chunkData = chunk(copyComponents, itemNumber)\n    if (chunkData.length === 0) return []\n    return page < chunkData.length ? chunkData[page] : chunkData[0]\n  }, [copyComponents, page, itemNumber])\n\n  const handleResizeStart: ResizeStartCallback = (e) => {\n    e.preventDefault()\n    e.stopPropagation()\n    dispatch(\n      configActions.setResizingNodeIDsReducer([\n        `${displayName}-resize-listItem`,\n      ]),\n    )\n  }\n\n  const handleOnResizeTopStop: ResizeCallback = useCallback(\n    (e, dir, elementRef, delta) => {\n      const { height } = delta\n      let finalHeight = itemHeight + height\n      handleUpdateOriginalDSLMultiAttr({\n        itemHeight: finalHeight,\n      })\n      dispatch(configActions.setResizingNodeIDsReducer([]))\n    },\n    [dispatch, handleUpdateOriginalDSLMultiAttr, itemHeight],\n  )\n\n  const canShowBorder = isEditMode && isMouseHover\n\n  const shadowStyle = getShadowStyle(itemShadow)\n  const borderStyle = useMemo(() => {\n    let borderWidth, borderRadius\n    const borderWidthNum = itemBorderWidth?.match(/\\d+(\\.\\d+)?/g)\n    if (borderWidthNum) borderWidth = borderWidthNum?.join(\"\") + \"px\"\n    const radiusNum = itemBorderRadius?.match(/\\d+(\\.\\d+)?/g)\n    if (radiusNum) borderRadius = radiusNum?.join(\"\") + \"px\"\n    return `\n    border: ${\n      borderWidth ? `${borderWidth} solid ${itemBorderColor}` : \"unset\"\n    };\n      border-radius: ${borderRadius ?? \"unset\"}\n    `\n  }, [itemBorderColor, itemBorderRadius, itemBorderWidth])\n\n  return (\n    <div\n      css={listParentContainerWithPagination}\n      onMouseEnter={() => {\n        setIsMouseHover(true)\n      }}\n      onMouseLeave={() => {\n        setIsMouseHover(false)\n      }}\n      ref={containerRef}\n    >\n      <div css={itemContainerStyle(itemGap, itemShadow)}>\n        {(page == undefined || page === 0) && (\n          <Resizable\n            size={{\n              width: \"100%\",\n              height: itemHeight,\n            }}\n            key={childrenNode[0]}\n            bounds=\"parent\"\n            minHeight={48}\n            maxHeight={\n              dynamicHeight !== \"fixed\"\n                ? \"unset\"\n                : currentContainerBoundsHeight - 4\n            }\n            handleComponent={isMouseHover ? resizeBottomHandler() : undefined}\n            enable={\n              dynamicHeight !== \"fixed\"\n                ? {}\n                : {\n                    bottom: true,\n                  }\n            }\n            onResizeStart={handleResizeStart}\n            onResizeStop={handleOnResizeTopStop}\n          >\n            <div\n              css={selectStyle(\n                selectIndexForMark === 0,\n                isEditMode,\n                themeColor,\n                itemBorderRadius,\n              )}\n            >\n              <div\n                css={applyListItemStyle(\n                  true,\n                  canShowBorder,\n                  itemBackGroundColor,\n                  shadowStyle,\n                  borderStyle,\n                  isEditMode,\n                  loading,\n                )}\n                onClick={(e) => {\n                  const isClickOnContainer = !!(\n                    e.target as HTMLElement\n                  )?.getAttribute(\"data-list-widget-container\")\n                  handleUpdateSelectedItem(0, isClickOnContainer)\n                }}\n              >\n                <RenderTemplateContainer\n                  templateComponentDisplayName={childrenNode[0]}\n                  templateContainerHeight={itemHeight}\n                  columnNumber={columnNumber}\n                  dynamicHeight={dynamicHeight}\n                  itemNumber={currentData?.length}\n                  extraHeight={paginationBounds.height}\n                  itemShadow={itemShadow}\n                  enableAutoPagination={enablePagination}\n                  handleUpdateOriginalDSLMultiAttr={\n                    handleUpdateOriginalDSLMultiAttr\n                  }\n                  h={h}\n                  updateComponentHeight={updateComponentHeight}\n                  dynamicMinHeight={dynamicMinHeight}\n                  dynamicMaxHeight={dynamicMaxHeight}\n                  itemGap={itemGap}\n                  itemPadding={itemPadding}\n                />\n              </div>\n            </div>\n            {canShowBorder && (\n              <div css={applyDashedLineStyle(false, true, false)} />\n            )}\n          </Resizable>\n        )}\n        {currentData.map((node, index) => {\n          if ((page == undefined || page === 0) && index === 0) {\n            return null\n          }\n          const step = page == undefined ? 0 : page\n          return (\n            <div\n              key={node.displayName}\n              css={selectStyle(\n                selectIndexForMark === index,\n                isEditMode,\n                themeColor,\n                itemBorderRadius,\n                itemHeight,\n              )}\n            >\n              <div\n                css={applyListItemStyle(\n                  false,\n                  canShowBorder,\n                  itemBackGroundColor,\n                  shadowStyle,\n                  borderStyle,\n                  isEditMode,\n                  loading,\n                  itemHeight,\n                  itemPadding?.size,\n                )}\n                key={node.displayName}\n                onClick={(e) => {\n                  const isClickOnContainer = !!(\n                    e.target as HTMLElement\n                  )?.getAttribute(\"data-list-widget-container\")\n                  handleUpdateSelectedItem(index, isClickOnContainer)\n                }}\n              >\n                <RenderCopyContainer\n                  templateComponentNodes={node}\n                  templateContainerHeight={itemHeight}\n                  columnNumber={columnNumber}\n                  displayNamePrefix={`list-child-${\n                    step * itemNumber! + index\n                  }-`}\n                />\n              </div>\n            </div>\n          )\n        })}\n      </div>\n      {enablePagination && (\n        <div css={paginationWrapperStyle} ref={paginationRef}>\n          <Pagination\n            total={dataSources?.length}\n            current={page <= 0 ? 1 : page + 1}\n            pageSize={itemNumber}\n            disableSimplePageJump\n            size=\"medium\"\n            sizeCanChange={false}\n            hideOnSinglePage={false}\n            simple\n            onChange={handleChangeCurrentPage}\n          />\n        </div>\n      )}\n    </div>\n  )\n}\n\nexport default ListWidgetWithAutoPagination\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/components/ListWidgetWithServerPagination/index.tsx",
    "content": "import { isEqual } from \"lodash-es\"\nimport { Resizable, ResizeCallback, ResizeStartCallback } from \"re-resizable\"\nimport { FC, useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport useMeasure from \"react-use-measure\"\nimport { Pagination } from \"@illa-design/react\"\nimport { applyDashedLineStyle } from \"@/page/App/components/ScaleSquare/style\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport { getShadowStyle } from \"@/utils/styleUtils/shadow\"\nimport {\n  ListWidgetPropsWithChildrenNodes,\n  PAGINATION_TYPE,\n} from \"@/widgetLibrary/ListWidget/interface\"\nimport {\n  ListParentContainerWithScroll,\n  applyListItemStyle,\n  itemContainerStyle,\n  paginationWrapperStyle,\n  selectStyle,\n} from \"@/widgetLibrary/ListWidget/style\"\nimport { resizeBottomHandler } from \"../../utils\"\nimport CursorBasedSelector from \"../CursorBasedSelector\"\nimport RenderCopyContainer from \"../RenderCopyContainer\"\nimport RenderTemplateContainer from \"../RenderTemplateContainer\"\n\nconst ListWidgetWithServerPagination: FC<ListWidgetPropsWithChildrenNodes> = (\n  props,\n) => {\n  const {\n    itemHeight = 48,\n    handleUpdateOriginalDSLMultiAttr,\n    childrenNode,\n    copyComponents = [],\n    handleUpdateSelectedItem,\n    itemBackGroundColor,\n    columnNumber,\n    pageSize,\n    paginationType,\n    totalRowCount = 1,\n    nextCursor,\n    previousCursor,\n    itemGap,\n    page = 0,\n    itemBorderColor,\n    itemBorderRadius,\n    itemBorderWidth,\n    itemShadow,\n    enableServerSidePagination,\n    dynamicHeight,\n    updateComponentHeight,\n    h,\n    dynamicMinHeight,\n    dynamicMaxHeight,\n    displayName,\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n    enablePagination,\n    disabled,\n    selectIndexForMark,\n    themeColor,\n    loading,\n    itemPadding,\n  } = props\n  const [containerRef, containerBounds] = useMeasure()\n  const [paginationRef, paginationBounds] = useMeasure()\n  const [isMouseHover, setIsMouseHover] = useState(false)\n  const safePageSize = !pageSize ? 0 : pageSize\n\n  const currentContainerBoundsHeight =\n    containerBounds.height - paginationBounds.height\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const dispatch = useDispatch()\n\n  const propsRef = useRef(props)\n  const handleChangePage = useCallback(\n    (pageNumber: number) => {\n      if (pageNumber <= 0 || disabled) return\n      handleUpdateSelectedItem()\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              page: pageNumber - 1,\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"pageChange\")\n      })\n    },\n    [\n      disabled,\n      displayName,\n      handleUpdateMultiExecutionResult,\n      handleUpdateSelectedItem,\n      triggerEventHandler,\n    ],\n  )\n\n  const handleCursorBasedChangePage = useCallback(\n    (isNext: boolean) => {\n      if ((page <= 0 && !isNext) || disabled) return\n      handleUpdateSelectedItem()\n      let value: {\n        page: number\n        beforeCursor: string | undefined\n        afterCursor: string | undefined\n      }\n      if (isNext) {\n        value = {\n          page: page + 1,\n          beforeCursor: undefined,\n          afterCursor: nextCursor,\n        }\n      } else {\n        value = {\n          page: page - 1,\n          beforeCursor: previousCursor,\n          afterCursor: undefined,\n        }\n      }\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value,\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"pageChange\")\n      })\n    },\n    [\n      disabled,\n      displayName,\n      handleUpdateMultiExecutionResult,\n      handleUpdateSelectedItem,\n      nextCursor,\n      page,\n      previousCursor,\n      triggerEventHandler,\n    ],\n  )\n\n  useEffect(() => {\n    if (!isEqual(propsRef.current, props)) {\n      propsRef.current = props\n    }\n  }, [props])\n\n  const handleResizeStart: ResizeStartCallback = (e) => {\n    e.preventDefault()\n    e.stopPropagation()\n    dispatch(\n      configActions.setResizingNodeIDsReducer([\n        `${displayName}-resize-listItem`,\n      ]),\n    )\n  }\n\n  const handleOnResizeTopStop: ResizeCallback = useCallback(\n    (e, dir, elementRef, delta) => {\n      let finalHeight = itemHeight + delta.height\n      handleUpdateOriginalDSLMultiAttr({\n        itemHeight: finalHeight,\n      })\n      dispatch(configActions.setResizingNodeIDsReducer([]))\n    },\n    [dispatch, handleUpdateOriginalDSLMultiAttr, itemHeight],\n  )\n\n  const canShowBorder = isEditMode && isMouseHover\n\n  const shadowStyle = getShadowStyle(itemShadow)\n  const borderStyle = useMemo(() => {\n    let borderWidth, borderRadius\n    const borderWidthNum = itemBorderWidth?.match(/\\d+(\\.\\d+)?/g)\n    if (borderWidthNum) borderWidth = borderWidthNum?.join(\"\") + \"px\"\n    const radiusNum = itemBorderRadius?.match(/\\d+(\\.\\d+)?/g)\n    if (radiusNum) borderRadius = radiusNum?.join(\"\") + \"px\"\n    return `\n    border: ${\n      borderWidth ? `${borderWidth} solid ${itemBorderColor}` : \"unset\"\n    };\n      border-radius: ${borderRadius ?? \"unset\"}\n    `\n  }, [itemBorderColor, itemBorderRadius, itemBorderWidth])\n\n  useEffect(() => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          offset: safePageSize * page,\n        },\n      },\n    ])\n  }, [displayName, handleUpdateMultiExecutionResult, page, safePageSize])\n\n  return (\n    <div\n      css={ListParentContainerWithScroll}\n      ref={containerRef}\n      onMouseEnter={() => {\n        setIsMouseHover(true)\n      }}\n      onMouseLeave={() => {\n        setIsMouseHover(false)\n      }}\n    >\n      <div css={itemContainerStyle(itemGap, itemShadow)}>\n        <Resizable\n          size={{\n            width: \"100%\",\n            height: itemHeight,\n          }}\n          bounds=\"parent\"\n          minHeight={48}\n          maxHeight={\n            dynamicHeight !== \"fixed\"\n              ? \"unset\"\n              : currentContainerBoundsHeight - 4\n          }\n          handleComponent={isMouseHover ? resizeBottomHandler() : undefined}\n          enable={\n            dynamicHeight !== \"fixed\"\n              ? {}\n              : {\n                  bottom: true,\n                }\n          }\n          onResizeStart={handleResizeStart}\n          onResizeStop={handleOnResizeTopStop}\n        >\n          <div\n            css={selectStyle(\n              selectIndexForMark === 0,\n              isEditMode,\n              themeColor,\n              itemBorderRadius,\n            )}\n          >\n            <div\n              css={applyListItemStyle(\n                true,\n                canShowBorder,\n                itemBackGroundColor,\n                shadowStyle,\n                borderStyle,\n                isEditMode,\n                loading,\n              )}\n              onClick={(e) => {\n                const isClickOnContainer = !!(\n                  e.target as HTMLElement\n                )?.getAttribute(\"data-list-widget-container\")\n                handleUpdateSelectedItem(0, isClickOnContainer)\n              }}\n            >\n              <RenderTemplateContainer\n                templateComponentDisplayName={childrenNode[0]}\n                templateContainerHeight={itemHeight}\n                columnNumber={columnNumber}\n                dynamicHeight={dynamicHeight}\n                extraHeight={paginationBounds.height}\n                itemShadow={itemShadow}\n                enableAutoPagination={enablePagination}\n                handleUpdateOriginalDSLMultiAttr={\n                  handleUpdateOriginalDSLMultiAttr\n                }\n                itemNumber={copyComponents?.length}\n                updateComponentHeight={updateComponentHeight}\n                h={h}\n                dynamicMinHeight={dynamicMinHeight}\n                dynamicMaxHeight={dynamicMaxHeight}\n                itemGap={itemGap}\n                itemPadding={itemPadding}\n              />\n            </div>\n          </div>\n          {canShowBorder && (\n            <div css={applyDashedLineStyle(false, true, false)} />\n          )}\n        </Resizable>\n        {copyComponents?.map((node, index) => {\n          if (index === 0) return null\n          return (\n            <div\n              key={node.displayName}\n              css={selectStyle(\n                selectIndexForMark === index,\n                isEditMode,\n                themeColor,\n                itemBorderRadius,\n                itemHeight,\n              )}\n            >\n              <div\n                css={applyListItemStyle(\n                  false,\n                  canShowBorder,\n                  itemBackGroundColor,\n                  shadowStyle,\n                  borderStyle,\n                  isEditMode,\n                  loading,\n                  itemHeight,\n                  itemPadding?.size,\n                )}\n                key={node.displayName}\n                onClick={(e) => {\n                  const isClickOnContainer = !!(\n                    e.target as HTMLElement\n                  )?.getAttribute(\"data-list-widget-container\")\n                  handleUpdateSelectedItem(index, isClickOnContainer)\n                }}\n              >\n                <RenderCopyContainer\n                  templateComponentNodes={node}\n                  templateContainerHeight={itemHeight}\n                  columnNumber={columnNumber}\n                  displayNamePrefix={`list-child-${index}-`}\n                />\n              </div>\n            </div>\n          )\n        })}\n      </div>\n      {enablePagination && enableServerSidePagination && (\n        <div css={paginationWrapperStyle} ref={paginationRef}>\n          {paginationType === PAGINATION_TYPE.LIMIT_OFFSET_BASED ? (\n            <Pagination\n              total={totalRowCount <= 1 ? 1 : totalRowCount}\n              current={page <= 0 ? 1 : page + 1}\n              pageSize={safePageSize}\n              size=\"medium\"\n              disableSimplePageJump\n              sizeCanChange={false}\n              hideOnSinglePage={false}\n              simple\n              onChange={handleChangePage}\n            />\n          ) : (\n            <CursorBasedSelector\n              page={page}\n              hasNextPage={props.hasNextPage}\n              onChange={handleCursorBasedChangePage}\n            />\n          )}\n        </div>\n      )}\n    </div>\n  )\n}\n\nexport default ListWidgetWithServerPagination\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/components/Loading/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { ComponentLoadingStyle } from \"./style\"\n\nexport const ComponentLoading: FC<{ themeColor?: string }> = ({\n  themeColor,\n}) => {\n  return (\n    <div css={ComponentLoadingStyle}>\n      <Loading colorScheme={themeColor} />\n    </div>\n  )\n}\n\nComponentLoading.displayName = \"ComponentLoading\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/components/Loading/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const ComponentLoadingStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  background-color: ${getColor(\"white\", \"03\")};\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/components/RenderCopyContainer/index.tsx",
    "content": "import { FC } from \"react\"\nimport { RenderComponentCanvasWithJson } from \"@/page/App/components/DotPanel/components/Canvas/renderComponentCanvasContainerWithJson\"\nimport { RenderCopyContainerProps } from \"@/widgetLibrary/ListWidget/interface\"\n\nconst RenderCopyContainer: FC<RenderCopyContainerProps> = (props) => {\n  const {\n    templateComponentNodes,\n    templateContainerHeight: _templateContainerHeight,\n    columnNumber,\n    displayNamePrefix,\n  } = props\n  return templateComponentNodes ? (\n    <RenderComponentCanvasWithJson\n      componentNode={templateComponentNodes}\n      containerPadding={0}\n      columnNumber={columnNumber}\n      displayNamePrefix={displayNamePrefix}\n    />\n  ) : null\n}\n\nexport default RenderCopyContainer\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/components/RenderTemplateContainer/index.tsx",
    "content": "import { FC, useCallback } from \"react\"\nimport {\n  LIST_ITEM_MARGIN_TOP,\n  WIDGET_SCALE_SQUARE_BORDER_WIDTH,\n} from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { RenderTemplateContainerProps } from \"@/widgetLibrary/ListWidget/interface\"\nimport RenderChildrenCanvas from \"@/widgetLibrary/PublicSector/RenderChildrenCanvas\"\nimport { getGapByShadow } from \"../../utils\"\n\nconst RenderTemplateContainer: FC<RenderTemplateContainerProps> = (props) => {\n  const {\n    templateComponentDisplayName,\n    columnNumber,\n    itemGap = LIST_ITEM_MARGIN_TOP,\n    dynamicHeight,\n    extraHeight = 0,\n    templateContainerHeight,\n    handleUpdateOriginalDSLMultiAttr,\n    updateComponentHeight,\n    itemNumber = 1,\n    enableAutoPagination,\n    itemShadow,\n    itemPadding,\n  } = props\n\n  const enableAutoHeight = dynamicHeight !== \"fixed\"\n\n  const handleUpdateHeight = useCallback(\n    (height: number) => {\n      if (!updateComponentHeight) return\n      if (\n        height + 2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH !==\n        templateContainerHeight\n      ) {\n        handleUpdateOriginalDSLMultiAttr(\n          {\n            itemHeight: height + 2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH,\n          },\n          true,\n        )\n      }\n\n      // height + pagination height + pagination gap + every item height + container padding y * 2\n      let componentHeight: number\n      let gap = itemGap >= 0 ? itemGap : LIST_ITEM_MARGIN_TOP\n      if (enableAutoPagination) {\n        componentHeight =\n          height +\n          extraHeight +\n          LIST_ITEM_MARGIN_TOP +\n          2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH +\n          (height + 2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH + gap) *\n            (itemNumber - 1) +\n          getGapByShadow(itemShadow) * 2\n      } else {\n        componentHeight =\n          height +\n          2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH +\n          (height + 2 * WIDGET_SCALE_SQUARE_BORDER_WIDTH + gap) *\n            (itemNumber - 1) +\n          getGapByShadow(itemShadow) * 2\n      }\n      updateComponentHeight(componentHeight)\n    },\n    [\n      handleUpdateOriginalDSLMultiAttr,\n      itemNumber,\n      templateContainerHeight,\n      updateComponentHeight,\n      extraHeight,\n      enableAutoPagination,\n      itemGap,\n      itemShadow,\n    ],\n  )\n\n  return (\n    <RenderChildrenCanvas\n      displayName={templateComponentDisplayName}\n      columnNumber={columnNumber}\n      handleUpdateHeight={handleUpdateHeight}\n      canResizeCanvas={enableAutoHeight}\n      containerPadding={itemPadding?.size}\n    />\n  )\n}\n\nexport default RenderTemplateContainer\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/constants.ts",
    "content": "export const DEFAULT_LIST = [\n  {\n    name: \"Yank Vanin\",\n    photo:\n      \"https://images.pexels.com/photos/1181424/pexels-photo-1181424.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Willey Swatridge\",\n    photo:\n      \"https://images.pexels.com/photos/2853592/pexels-photo-2853592.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Piper Whisker\",\n    photo:\n      \"https://images.pexels.com/photos/1181690/pexels-photo-1181690.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Sargent Boswell\",\n    photo:\n      \"https://images.pexels.com/photos/1586973/pexels-photo-1586973.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Anita Mordy\",\n    photo:\n      \"https://images.pexels.com/photos/1181391/pexels-photo-1181391.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Domini Queree\",\n    photo:\n      \"https://images.pexels.com/photos/826349/pexels-photo-826349.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Hunter Dossett\",\n    photo:\n      \"https://images.pexels.com/photos/3769021/pexels-photo-3769021.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Phylis Bonass\",\n    photo:\n      \"https://images.pexels.com/photos/806835/pexels-photo-806835.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Lyndsey Bransom\",\n    photo:\n      \"https://images.pexels.com/photos/920382/pexels-photo-920382.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Pepi Peter\",\n    photo:\n      \"https://images.pexels.com/photos/1586996/pexels-photo-1586996.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Way Guy\",\n    photo:\n      \"https://images.pexels.com/photos/785667/pexels-photo-785667.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Karalee Coton\",\n    photo:\n      \"https://images.pexels.com/photos/914931/pexels-photo-914931.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Daniele Adamik\",\n    photo:\n      \"https://images.pexels.com/photos/1024403/pexels-photo-1024403.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n    title: \"🧑‍💻 Customer Success Team Lead\",\n  },\n  {\n    name: \"Auria Archer\",\n    photo:\n      \"https://images.pexels.com/photos/1181414/pexels-photo-1181414.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Caesar Jakubowsky\",\n    photo:\n      \"https://images.pexels.com/photos/834863/pexels-photo-834863.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Noelle Loache\",\n    photo:\n      \"https://images.pexels.com/photos/3756679/pexels-photo-3756679.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Benedetta Warbrick\",\n    photo:\n      \"https://images.pexels.com/photos/32976/pexels-photo.jpg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Lyndsey Pycock\",\n    photo:\n      \"https://images.pexels.com/photos/3184608/pexels-photo-3184608.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Stuart Eymer\",\n    photo:\n      \"https://images.pexels.com/photos/1181695/pexels-photo-1181695.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Mar Rogeon\",\n    photo:\n      \"https://images.pexels.com/photos/50855/pexels-photo-50855.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Tom Warbrick\",\n    photo:\n      \"https://images.pexels.com/photos/789822/pexels-photo-789822.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Fabien Aitken\",\n    photo:\n      \"https://images.pexels.com/photos/1181678/pexels-photo-1181678.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Kipp Fendt\",\n    photo:\n      \"https://images.pexels.com/photos/1181293/pexels-photo-1181293.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Guillermo Anten\",\n    photo:\n      \"https://images.pexels.com/photos/7647990/pexels-photo-7647990.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Micah McLeod\",\n    photo:\n      \"https://images.pexels.com/photos/2955376/pexels-photo-2955376.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Ivar Filon\",\n    photo:\n      \"https://images.pexels.com/photos/7648004/pexels-photo-7648004.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Micah Bohey\",\n    photo:\n      \"https://images.pexels.com/photos/7647992/pexels-photo-7647992.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Georgianne Guy\",\n    photo:\n      \"https://images.pexels.com/photos/8145344/pexels-photo-8145344.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Tom Raffels\",\n    photo:\n      \"https://images.pexels.com/photos/8134106/pexels-photo-8134106.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n  {\n    name: \"Annadiana Brockman\",\n    photo:\n      \"https://images.pexels.com/photos/7644155/pexels-photo-7644155.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const LIST_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.rowSelect\",\n      ),\n      value: \"rowSelect\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onPaginationModelChange\",\n      ),\n      value: \"pageChange\",\n    },\n  ],\n  methods: [],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/index.tsx",
    "content": "export * from \"./widgetConfig\"\nexport * from \"./panelConfig\"\nexport * from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/interface.ts",
    "content": "import { ComponentTreeNode, PADDING_MODE } from \"@illa-public/public-types\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport enum PAGINATION_TYPE {\n  LIMIT_OFFSET_BASED = \"limitOffsetBased\",\n  CURSOR_BASED = \"cursorBased\",\n}\nexport type ShadowOptions = \"none\" | \"small\" | \"medium\" | \"large\"\n\ntype ItemPadding = {\n  size: string\n  mode: PADDING_MODE\n}\nexport interface ListWidgetProps extends BaseWidgetProps {\n  dataSources?: Array<unknown>\n  enablePagination?: boolean\n  enableServerSidePagination?: boolean\n  paginationType?: PAGINATION_TYPE\n  page?: number\n  pageSize?: number\n  previousCursor?: string\n  nextCursor?: string\n  hasNextPage?: boolean\n  totalRowCount?: number\n  itemGap?: number\n  itemHeight: number\n  currentPage: number\n  selectedIndex: number\n  itemBackGroundColor: string\n  itemBorderWidth?: string\n  itemBorderColor?: string\n  itemBorderRadius?: string\n  itemShadow?: ShadowOptions\n  disabled: boolean\n  columnNumber: number\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  h: number\n  dynamicMinHeight?: number\n  dynamicMaxHeight?: number\n  themeColor?: string\n  loading?: boolean\n  itemPadding?: ItemPadding\n}\n\nexport interface RenderTemplateContainerProps {\n  templateComponentDisplayName: string\n  templateContainerHeight: number\n  columnNumber: number\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  handleUpdateOriginalDSLMultiAttr: BaseWidgetProps[\"handleUpdateOriginalDSLMultiAttr\"]\n  updateComponentHeight?: (newHeight: number) => void\n  itemNumber?: number\n  h: number\n  dynamicMinHeight?: number\n  dynamicMaxHeight?: number\n  extraHeight?: number\n  itemGap?: number\n  enableAutoPagination?: boolean\n  itemShadow?: ShadowOptions\n  itemPadding?: ItemPadding\n}\n\nexport interface RenderCopyContainerProps {\n  templateComponentNodes: ComponentTreeNode\n  templateContainerHeight: number\n  columnNumber: number\n  displayNamePrefix: string\n  itemPadding?: ItemPadding\n}\n\nexport interface ListWidgetPropsWithChildrenNodes extends ListWidgetProps {\n  copyComponents: ComponentTreeNode[] | null\n  selectIndexForMark?: number\n  handleUpdateSelectedItem: (index?: number, isContainerClick?: boolean) => void\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/list.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { ComponentTreeNode } from \"@illa-public/public-types\"\nimport { klona } from \"klona\"\nimport { get, isEqual, set, toPath } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { getComponentMap } from \"@/redux/currentApp/components/componentsSelector\"\nimport {\n  getExecutionResult,\n  getRawTree,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { evaluateDynamicString } from \"@/utils/evaluateDynamicString\"\nimport { getObjectPaths } from \"@/utils/executionTreeHelper/utils\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport { VALIDATION_TYPES, validationFactory } from \"@/utils/validationFactory\"\nimport { ListWidgetProps } from \"@/widgetLibrary/ListWidget/interface\"\nimport ListWidgetWithAutoPagination from \"./components/ListWidgetWithAutoPagination\"\nimport ListWidgetWithServerPagination from \"./components/ListWidgetWithServerPagination\"\nimport { ComponentLoading } from \"./components/Loading\"\n\nexport const ListWidget: FC<ListWidgetProps> = (props) => {\n  const {\n    displayName,\n    dataSources,\n    childrenNode,\n    enableServerSidePagination,\n    paginationType,\n    enablePagination,\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n    disabled,\n    loading,\n    themeColor,\n    page = 1,\n    pageSize = 10,\n  } = props\n\n  const executionResult = useSelector(getExecutionResult)\n  const rawTree = useSelector(getRawTree)\n  const components = useSelector(getComponentMap)\n  const [selectIndexForMark, setSelectIndexForMark] = useState<\n    undefined | number\n  >()\n\n  const prevDataSourcesRef = useRef(dataSources)\n\n  const updateTemplateContainerNodesProps = useCallback(\n    (childrenNodeDisplayNames: string[]) => {\n      return childrenNodeDisplayNames.map((itemContainerDisplayName, index) => {\n        const currentItemContainer = klona(components[itemContainerDisplayName])\n        const currentItemDisplayNames = currentItemContainer.childrenNode\n        if (\n          Array.isArray(currentItemDisplayNames) &&\n          currentItemDisplayNames.length > 0\n        ) {\n          let newCurrentItems = currentItemDisplayNames.map(\n            (currentItemDisplayName) => {\n              const currentItem = JSON.parse(\n                JSON.stringify(components[currentItemDisplayName]),\n              ) as ComponentTreeNode\n              if (\n                currentItem.props &&\n                Array.isArray(currentItem.props.$dynamicAttrPaths)\n              ) {\n                const { displayName } = currentItem\n                const { $dynamicAttrPaths } = currentItem.props\n                $dynamicAttrPaths.forEach((path) => {\n                  const finalPath = convertPathToString(toPath(path))\n                  const requireEvalString = get(\n                    currentItem.props,\n                    finalPath,\n                    \"\",\n                  )\n                  let evalResult: unknown\n                  try {\n                    evalResult = evaluateDynamicString(\n                      \"\",\n                      requireEvalString,\n                      executionResult,\n                    )\n                  } catch (e) {\n                    console.log(e)\n                    evalResult = \"\"\n                  }\n                  let value = evalResult\n                  if (Array.isArray(evalResult) && evalResult.length > index) {\n                    const rawWidget = rawTree[displayName]\n                    if (rawWidget && isObject(rawWidget.$validationPaths)) {\n                      const validationPaths = rawWidget.$validationPaths\n                      const validationType = get(validationPaths, finalPath)\n                      if (validationType === VALIDATION_TYPES.ARRAY) {\n                        if (Array.isArray(evalResult)) {\n                          const needSetValue = evalResult[index] ?? []\n                          const validationFunc =\n                            validationFactory[validationType]\n                          const res = validationFunc?.(needSetValue, \"\")\n                          value = res?.safeValue ?? needSetValue\n                        } else {\n                          const validationFunc =\n                            validationFactory[validationType]\n                          const res = validationFunc?.(evalResult, \"\")\n                          value = res?.safeValue ?? evalResult\n                        }\n                      } else {\n                        value = evalResult[index]\n                        const validationFunc = validationFactory[validationType]\n                        const res = validationFunc?.(value, \"\")\n                        value = res?.safeValue ?? value\n                      }\n                    }\n                  }\n                  set(currentItem, `props.${finalPath}`, value)\n                })\n              }\n              if (index !== 0) {\n                set(\n                  currentItem,\n                  \"displayName\",\n                  `list-child-${index}-${currentItemDisplayName}`,\n                )\n                if (disabled != undefined) {\n                  set(currentItem, \"props.disabled\", disabled)\n                }\n              }\n              return currentItem\n            },\n          )\n          newCurrentItems = newCurrentItems.map((item) => {\n            const displayName = item.displayName\n            const displayNameArray = displayName.split(\"-\")\n            const realDisplayName = displayNameArray.at(-1)\n            const rawWidget = rawTree[realDisplayName as string]\n            const validationPaths = rawWidget.$validationPaths\n            if (isObject(validationPaths)) {\n              getObjectPaths(validationPaths).forEach((path) => {\n                const validationType = get(\n                  validationPaths,\n                  path,\n                ) as VALIDATION_TYPES\n                const validationFunc = validationFactory[validationType]\n                const currentValue = get(item, `props.${path}`, \"\")\n                const res = validationFunc?.(currentValue, \"\")\n                set(item, `props.${path}`, res?.safeValue)\n              })\n            }\n            return item\n          })\n          set(currentItemContainer, \"childrenNode\", newCurrentItems)\n        }\n        if (index !== 0) {\n          set(\n            currentItemContainer,\n            \"displayName\",\n            `list-widget-container-${index}`,\n          )\n        }\n        return currentItemContainer as unknown as ComponentTreeNode\n      })\n    },\n    [components, disabled, executionResult, rawTree],\n  )\n\n  const transTemplateContainerNodes = useCallback(\n    (templateContainerDisplayName: string) => {\n      const canvasChildrenDisplayNames: string[] = []\n      if (Array.isArray(dataSources) && dataSources.length > 0) {\n        dataSources.forEach((v, index) => {\n          canvasChildrenDisplayNames[index] = templateContainerDisplayName\n        })\n        return updateTemplateContainerNodesProps(canvasChildrenDisplayNames)\n      } else {\n        return updateTemplateContainerNodesProps([templateContainerDisplayName])\n      }\n    },\n    [dataSources, updateTemplateContainerNodesProps],\n  )\n\n  const getChildrenNodes = useMemo(() => {\n    if (childrenNode && childrenNode.length > 0 && dataSources) {\n      let canvasDisplayName = childrenNode[0]\n      return transTemplateContainerNodes(canvasDisplayName)\n    }\n    return null\n  }, [childrenNode, dataSources, transTemplateContainerNodes])\n\n  const handleUpdateSelectedItem = useCallback(\n    (index?: number, isContainerClick?: boolean) => {\n      if (!Array.isArray(dataSources) || disabled) return\n      if (\n        (selectIndexForMark === index && isContainerClick) ||\n        index === undefined\n      ) {\n        setSelectIndexForMark(undefined)\n      } else {\n        setSelectIndexForMark(index)\n      }\n      new Promise((resolve) => {\n        let value\n        if (\n          index === undefined ||\n          (selectIndexForMark === index && isContainerClick)\n        ) {\n          value = {\n            selectedItem: undefined,\n            selectedIndex: undefined,\n          }\n        } else {\n          const selectItemIndex = enableServerSidePagination\n            ? index\n            : index + page * (pageSize ?? 0)\n          value = {\n            selectedItem: dataSources[selectItemIndex],\n            selectedIndex: index,\n          }\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value,\n          },\n        ])\n        resolve(value)\n      }).then(() => {\n        triggerEventHandler(\"rowSelect\")\n      })\n    },\n    [\n      dataSources,\n      disabled,\n      displayName,\n      enableServerSidePagination,\n      handleUpdateMultiExecutionResult,\n      page,\n      pageSize,\n      selectIndexForMark,\n      triggerEventHandler,\n    ],\n  )\n\n  useEffect(() => {\n    if (!isEqual(prevDataSourcesRef.current, dataSources)) {\n      handleUpdateMultiExecutionResult?.([\n        {\n          displayName,\n          value: {\n            selectedIndex: undefined,\n            selectedItem: undefined,\n          },\n        },\n      ])\n    }\n  }, [dataSources, displayName, handleUpdateMultiExecutionResult])\n\n  useEffect(() => {\n    handleUpdateMultiExecutionResult?.([\n      {\n        displayName,\n        value: {\n          page: 0,\n        },\n      },\n    ])\n  }, [\n    displayName,\n    handleUpdateMultiExecutionResult,\n    paginationType,\n    enablePagination,\n    enableServerSidePagination,\n  ])\n\n  return (\n    <>\n      {enableServerSidePagination ? (\n        <ListWidgetWithServerPagination\n          {...props}\n          copyComponents={getChildrenNodes}\n          selectIndexForMark={selectIndexForMark}\n          handleUpdateSelectedItem={handleUpdateSelectedItem}\n        />\n      ) : (\n        <ListWidgetWithAutoPagination\n          {...props}\n          copyComponents={getChildrenNodes}\n          selectIndexForMark={selectIndexForMark}\n          handleUpdateSelectedItem={handleUpdateSelectedItem}\n        />\n      )}\n      {loading && <ComponentLoading themeColor={themeColor} />}\n    </>\n  )\n}\n\nexport default ListWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/panelConfig.tsx",
    "content": "import RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { LIST_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/ListWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { PAGINATION_TYPE } from \"./interface\"\n\nconst baseWidgetName = \"list\"\nexport const LIST_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-data`,\n    groupName: i18n.t(\"editor.inspect.setter_group.data\"),\n    children: [\n      {\n        id: `${baseWidgetName}-data-source`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          LIST_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-loading`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n        attrName: \"loading\",\n        placeholder: \"{{false}}\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-PAGINATION`,\n    groupName: i18n.t(\"editor.inspect.setter_group.pagination\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-enable_pagination`,\n        labelName: i18n.t(\"editor.inspect.setter_label.enable_pagination\"),\n        attrName: \"enablePagination\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        useCustomLayout: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-enableServerSidePagination`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.table.enable_server_side_p\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.table.enable_server_side_p\",\n        ),\n        attrName: \"enableServerSidePagination\",\n        bindAttrName: [\"enablePagination\"],\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        shown: (v) => v,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-column-paginationType`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.pagination_type\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.pagination_type\"),\n        attrName: \"paginationType\",\n        setterType: \"SEARCH_SELECT_SETTER\",\n        isSetterSingleRow: true,\n        bindAttrName: [\"enablePagination\", \"enableServerSidePagination\"],\n        shown: (enablePagination, enableServerSidePagination) =>\n          enablePagination && enableServerSidePagination,\n        defaultValue: PAGINATION_TYPE.LIMIT_OFFSET_BASED,\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.table.limit_offset_based\",\n            ),\n            value: PAGINATION_TYPE.LIMIT_OFFSET_BASED,\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.table.cursor_based\"),\n            value: PAGINATION_TYPE.CURSOR_BASED,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-totalRowCount`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.total_row_count\"),\n        attrName: \"totalRowCount\",\n        setterType: \"INPUT_SETTER\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\n          \"enablePagination\",\n          \"enableServerSidePagination\",\n          \"paginationType\",\n        ],\n        shown: (\n          enablePagination,\n          enableServerSidePagination,\n          paginationType,\n        ) => {\n          return (\n            enablePagination &&\n            enableServerSidePagination &&\n            paginationType === PAGINATION_TYPE.LIMIT_OFFSET_BASED\n          )\n        },\n      },\n      {\n        id: `${baseWidgetName}-basic-previousCursor`,\n        labelName: i18n.t(\"editor.inspect.setter_label.previous_cursor\"),\n        attrName: \"previousCursor\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        bindAttrName: [\n          \"enablePagination\",\n          \"enableServerSidePagination\",\n          \"paginationType\",\n        ],\n        shown: (enablePagination, enableServerSidePagination, paginationType) =>\n          enablePagination &&\n          enableServerSidePagination &&\n          paginationType === \"cursorBased\",\n      },\n      {\n        id: `${baseWidgetName}-basic-nextCursor`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.next_cursor\"),\n        attrName: \"nextCursor\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        bindAttrName: [\n          \"enablePagination\",\n          \"enableServerSidePagination\",\n          \"paginationType\",\n        ],\n        shown: (enablePagination, enableServerSidePagination, paginationType) =>\n          enablePagination &&\n          enableServerSidePagination &&\n          paginationType === \"cursorBased\",\n      },\n      {\n        id: `${baseWidgetName}-basic-hasNextPage`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.has_next_page\"),\n        attrName: \"hasNextPage\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\n          \"enablePagination\",\n          \"enableServerSidePagination\",\n          \"paginationType\",\n        ],\n        shown: (enablePagination, enableServerSidePagination, paginationType) =>\n          enablePagination &&\n          enableServerSidePagination &&\n          paginationType === \"cursorBased\",\n      },\n      {\n        id: `${baseWidgetName}-basic-pageSize`,\n        labelName: i18n.t(\"editor.inspect.setter_label.pageSize\"),\n        attrName: \"pageSize\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"enablePagination\"],\n        shown: (v) => v,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-height`,\n        labelName: i18n.t(\"editor.inspect.setter_label.height\"),\n        attrName: \"dynamicHeight\",\n        setterType: \"HEIGHT_MODE_SELECT\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.fixed\"),\n            value: \"fixed\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_height\"),\n            value: \"auto\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-item_gap`,\n        setterType: \"LIST_GAP_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.grid_list.item_spacing\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.grid_list.item_spacing\"),\n        attrName: \"itemGap\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        useCustomLayout: true,\n        attrName: \"hidden\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"ITEM_BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"itemBorder\",\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.grid_list.item_radius\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.grid_list.item_radius\",\n            ),\n            attrName: \"itemBorderRadius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n          {\n            id: `${baseWidgetName}-style-shadow`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.grid_list.item_shadow\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.grid_list.item_shadow\",\n            ),\n            attrName: \"itemShadow\",\n            setterType: \"SHADOW_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"medium\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-style-color`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-colors-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"themeColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n          {\n            id: `${baseWidgetName}-style-color`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.item_background_color\",\n            ),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"itemBackGroundColor\",\n            defaultValue: \"white\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-padding`,\n        setterType: \"PADDING_INPUT_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_group.item_padding\"),\n        attrName: \"itemPadding\",\n        useCustomLayout: true,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor, getSpecialThemeColor } from \"@illa-design/react\"\nimport { SCROLL_CONTAINER_PADDING } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport {\n  LIST_ITEM_MARGIN_TOP,\n  WIDGET_SCALE_SQUARE_BORDER_WIDTH,\n} from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { getPaddingShape } from \"@/utils/styleUtils/padding\"\nimport { ShadowOptions } from \"./interface\"\nimport { getGapByShadow } from \"./utils\"\n\nexport const listParentContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  position: relative;\n  overflow: hidden;\n  gap: 8px;\n  justify-content: space-between;\n`\n\nexport const listParentContainerWithPagination = css`\n  ${listParentContainerStyle};\n  overflow-y: auto;\n`\n\nexport const ListParentContainerWithScroll = css`\n  ${listParentContainerStyle};\n  overflow-y: auto;\n`\n\nexport const applyListItemStyle = (\n  isFirst: boolean = false,\n  canShowBorder: boolean = false,\n  bgColor: string,\n  shadowStyle: string,\n  borderStyle: string,\n  isEditor: boolean = false,\n  loading?: boolean,\n  itemHeight?: number,\n  padding?: string,\n) => {\n  // canvas container hash scroll container padding\n  let extraPadding = isFirst ? 0 : SCROLL_CONTAINER_PADDING\n\n  const { paddingTop, paddingBottom, paddingLeft, paddingRight } =\n    getPaddingShape(padding)\n\n  return css`\n    width: 100%;\n    height: ${itemHeight ? `${itemHeight}px` : \"100%\"};\n    background-color: ${bgColor\n      ? getSpecialThemeColor(bgColor)\n      : \"transparent\"};\n    flex: none;\n    border: ${WIDGET_SCALE_SQUARE_BORDER_WIDTH}px dashed\n      ${canShowBorder ? getColor(\"techPurple\", \"03\") : \"transparent\"};\n    opacity: ${isEditor && !isFirst ? 0.5 : 1};\n    ${borderStyle};\n    box-shadow: ${shadowStyle};\n\n    padding: ${paddingTop + extraPadding}px ${paddingRight + extraPadding}px\n      ${paddingBottom + extraPadding}px ${paddingLeft + extraPadding}px;\n    pointer-events: ${loading ? \"none\" : \"unset\"};\n  `\n}\n\nexport const paginationWrapperStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  flex: none;\n`\n\nexport const itemContainerStyle = (\n  itemGap?: number,\n  shadow?: ShadowOptions,\n) => css`\n  display: flex;\n  width: 100%;\n  flex-direction: column;\n  gap: ${itemGap ?? LIST_ITEM_MARGIN_TOP}px;\n  overflow-y: auto;\n  padding: ${getGapByShadow(shadow)}px;\n`\n\nexport const selectStyle = (\n  isSelect: boolean,\n  isEditMode: boolean,\n  themeColor?: string,\n  radius?: string,\n  itemHeight?: number,\n) => {\n  if (isEditMode || !isSelect) {\n    return css`\n      width: 100%;\n      height: ${itemHeight ? `${itemHeight}px` : \"100%\"};\n    `\n  }\n  return css`\n    width: 100%;\n    height: ${itemHeight ? `${itemHeight}px` : \"100%\"};\n    outline: 1px solid ${themeColor ?? getColor(\"blue\", \"03\")} !important;\n    border-radius: ${radius ?? \"unset\"};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/utils.tsx",
    "content": "import {\n  applyBarHandlerStyle,\n  applyBarPointerStyle,\n} from \"@/page/App/components/ScaleSquare/style\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport store from \"@/store\"\nimport { ShadowOptions } from \"./interface\"\n\nexport const resizeBottomHandler = () => {\n  const rootState = store.getState()\n  const isEditMode = getIsILLAEditMode(rootState)\n  const scaleSquareState = !isEditMode ? \"production\" : \"normal\"\n  return {\n    bottom: (\n      <div css={applyBarHandlerStyle(true, scaleSquareState, \"b\")}>\n        <div\n          className=\"handler\"\n          css={applyBarPointerStyle(true, scaleSquareState, \"b\")}\n        />\n      </div>\n    ),\n  }\n}\n\nexport const getGapByShadow = (itemShadow?: ShadowOptions) => {\n  switch (itemShadow) {\n    case \"large\": {\n      return 20\n    }\n    case \"medium\": {\n      return 16\n    }\n    case \"small\": {\n      return 4\n    }\n    case \"none\":\n    default:\n      return 1\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ListWidget/widgetConfig.tsx",
    "content": "import { PADDING_MODE } from \"@illa-public/public-types\"\nimport ListWidgetIcon from \"@/assets/widgetCover/list.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { LIST_ITEM_MARGIN_TOP } from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { TEMPLATE_DISPLAYNAME_KEY } from \"@/utils/generators/generateComponentNode\"\nimport { BasicContainerConfig } from \"@/widgetLibrary/BasicContainer/BasicContainer\"\nimport { IMAGE_WIDGET_CONFIG } from \"@/widgetLibrary/ImageWidget\"\nimport { TEXT_WIDGET_CONFIG } from \"@/widgetLibrary/TextWidget\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\nimport { DEFAULT_LIST } from \"./constants\"\nimport { PAGINATION_TYPE } from \"./interface\"\n\nexport const LIST_WIDGET_CONFIG: WidgetConfig = {\n  type: \"LIST_WIDGET\",\n  displayName: \"list\",\n  widgetName: i18n.t(\"widget.list.name\"),\n  keywords: [\"list\", \"列表\"],\n  icon: <ListWidgetIcon />,\n  sessionType: \"CONTAINER\",\n  w: 13,\n  h: 38,\n  version: 0,\n  childrenNode: [\n    {\n      ...BasicContainerConfig,\n      childrenNode: [\n        {\n          ...IMAGE_WIDGET_CONFIG,\n          w: 8,\n          h: 16,\n          x: 0,\n          y: 1,\n          defaults: {\n            ...IMAGE_WIDGET_CONFIG.defaults,\n            imageSrc: `{{${TEMPLATE_DISPLAYNAME_KEY}.dataSources.map((currentItem) => (currentItem.photo))}}`,\n            $dynamicAttrPaths: [\"imageSrc\"],\n            radius: \"4px\",\n          },\n        },\n        {\n          ...TEXT_WIDGET_CONFIG,\n          w: 23,\n          h: 9,\n          x: 9,\n          y: 2,\n          defaults: {\n            ...TEXT_WIDGET_CONFIG.defaults,\n            value: `{{${TEMPLATE_DISPLAYNAME_KEY}.dataSources.map((currentItem) => ('### ' + currentItem.name))}}`,\n            $dynamicAttrPaths: [\"value\"],\n          },\n        },\n      ],\n    },\n  ],\n  defaults: {\n    enablePagination: true,\n    enableServerSidePagination: false,\n    pageSize: \"{{10}}\",\n    itemGap: LIST_ITEM_MARGIN_TOP,\n    paginationType: PAGINATION_TYPE.LIMIT_OFFSET_BASED,\n    itemBackGroundColor: \"white\",\n    themeColor: \"blue\",\n    itemHeight: 150,\n    selectedIndex: undefined,\n    selectedItem: undefined,\n    dataSources: `{{\n      ${JSON.stringify(DEFAULT_LIST)}\n    }}`,\n    dynamicHeight: \"fixed\",\n    resizeDirection: RESIZE_DIRECTION.ALL,\n    page: \"{{0}}\",\n    offset: 0,\n    itemBorderRadius: \"4px\",\n    itemPadding: {\n      mode: PADDING_MODE.ALL,\n      size: \"4\",\n    },\n    itemShadow: \"medium\",\n    beforeCursor: undefined,\n    afterCursor: undefined,\n    totalRowCount: undefined,\n    previousCursor: undefined,\n    nextCursor: undefined,\n    hasNextPage: undefined,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/SearchInput.tsx",
    "content": "import { Autocomplete } from \"@react-google-maps/api\"\nimport React, { useEffect, useRef, useState } from \"react\"\nimport { Input } from \"@illa-design/react\"\nimport { SearchInputProps } from \"./interface\"\nimport { applyInput } from \"./style\"\n\nexport const SearchInput: React.FC<SearchInputProps> = ({ onPlaceChanged }) => {\n  const [autocomplete, setAutocomplete] =\n    useState<google.maps.places.Autocomplete | null>(null)\n\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const handlePlaceChanged = () => {\n    if (autocomplete) {\n      const place = autocomplete.getPlace()\n      if (place.geometry && place.geometry.location) {\n        const location = {\n          lat: place.geometry.location.lat(),\n          lng: place.geometry.location.lng(),\n        }\n        onPlaceChanged(location)\n      }\n    }\n  }\n\n  useEffect(() => {\n    if (inputRef.current) {\n      inputRef.current.style.cssText = applyInput\n    }\n  }, [inputRef])\n\n  return (\n    <Autocomplete\n      onLoad={(auto) => setAutocomplete(auto)}\n      onPlaceChanged={handlePlaceChanged}\n    >\n      <Input ref={inputRef} />\n    </Autocomplete>\n  )\n}\n\nexport default SearchInput\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/content.ts",
    "content": "export const DefaultMarkers =\n  '[{\"lat\":61.14009563040699,\"lng\":-114.6018657894011},{\"lat\":59.40432513713809,\"lng\":-112.98252263795787},{\"lat\":57.841288754888545,\"lng\":-103.3518657894011}]'\nexport const DefaultCenter =\n  '{\"lat\": 59.40432513713809, \"lng\": -112.98252263795787}'\nexport const DefaultZoom = 3\nexport const Libraries: \"places\"[] = [\"places\"]\nexport const LatitudeFieldName = \"lat\"\nexport const LongitudeFieldName = \"lng\"\nexport const ContainerStyle = {\n  width: \"100%\",\n  height: \"100%\",\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const MAP_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.markerSelected\",\n      ),\n      value: \"markerSelected\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.markerCreated\",\n      ),\n      value: \"markerCreated\",\n    },\n  ],\n  methods: [\"setMarkers\", \"resetMarkers\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/index.tsx",
    "content": "export { MAP_PANEL_CONFIG } from \"./panelConfig\"\nexport { MAP_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { MAP_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/interface.ts",
    "content": "import { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport {\n  BaseComponentNodeProps,\n  BaseWidgetProps,\n} from \"@/widgetLibrary/interface\"\nimport { ValidateMessageOldProps } from \"../PublicSector/InvalidMessage/interface\"\n\nexport interface MapProps {\n  center?: string\n  latitudeFieldName?: string\n  longitudeFieldName?: string\n  zoom?: number\n  markers?: string\n  enableAddMark?: boolean\n  enableSearch?: boolean\n  enableClustering?: boolean\n  onMarkerSelected?: (latLng: LatLng) => void\n  onMarkerCreated?: (latLng: LatLng) => void\n  onMarkersChanged?: (marks: LatLng[]) => void\n}\n\nexport interface WrappedMapProps\n  extends Omit<ValidateMessageOldProps, \"value\">,\n    Pick<MapProps, \"center\" | \"zoom\"> {\n  displayName: string\n  markers?: MarkersType\n  loading?: boolean\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnMarkerCreated?: () => void\n  handleOnMarkerSelect?: () => void\n}\n\nexport interface MapWidgetProps\n  extends WrappedMapProps,\n    BaseWidgetProps,\n    TooltipWrapperProps,\n    BaseComponentNodeProps {}\n\nexport interface SearchInputProps {\n  onPlaceChanged: (location: google.maps.LatLngLiteral) => void\n}\nexport type LatLng = google.maps.LatLngLiteral\nexport interface CustomLatLing {\n  [key: string]: number\n}\nexport type MarkersType = LatLng[] | CustomLatLing[]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/map.tsx",
    "content": "import { FC, useCallback, useEffect, useState } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { MapBox } from \"@/widgetLibrary/MapBoxWidget/mapBox\"\nimport { InvalidMessage } from \"../PublicSector/InvalidMessage\"\nimport { DefaultMarkers, DefaultZoom } from \"./content\"\nimport { MapWidgetProps, WrappedMapProps } from \"./interface\"\nimport { ApplyLoadingStyle, applyMapContainer, applyValidStyle } from \"./style\"\n\nexport const WrapperMap: FC<WrappedMapProps> = (props) => {\n  const {\n    displayName,\n    center,\n    markers,\n    loading,\n    handleUpdateMultiExecutionResult,\n    handleOnMarkerCreated,\n    handleOnMarkerSelect,\n  } = props\n  const onMarkersChanged = useCallback(\n    (markers: unknown) => {\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              markers: markers || [],\n            },\n          },\n        ])\n        resolve(true)\n      })\n    },\n    [displayName, handleUpdateMultiExecutionResult],\n  )\n\n  const onMarkerSelect = useCallback(\n    (selectMarker: unknown) => {\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              selectMarker: selectMarker || \"\",\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        handleOnMarkerSelect?.()\n      })\n    },\n    [displayName, handleOnMarkerSelect, handleUpdateMultiExecutionResult],\n  )\n  return (\n    <div style={{ width: \"100%\", height: \"100%\" }}>\n      {loading ? (\n        <div css={ApplyLoadingStyle}>\n          <Loading colorScheme=\"techPurple\" />\n        </div>\n      ) : (\n        <MapBox\n          {...props}\n          markers={JSON.stringify(markers)}\n          center={JSON.stringify(center)}\n          onMarkerSelected={onMarkerSelect}\n          onMarkerCreated={handleOnMarkerCreated}\n          onMarkersChanged={onMarkersChanged}\n        />\n      )}\n    </div>\n  )\n}\n\nWrapperMap.displayName = \"WrapperMap\"\n\nexport const MapWidget: FC<MapWidgetProps> = (props) => {\n  const {\n    displayName,\n    loading,\n    markers,\n    center,\n    zoom = DefaultZoom,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n    ...rest\n  } = props\n\n  const [message, setValidateMessage] = useState(\"\")\n\n  const checkZoom = useCallback((zoom: number) => {\n    if (zoom > 22) {\n      setValidateMessage(\"Need to be less than 22\")\n    } else if (zoom < 1) {\n      setValidateMessage(\"Need to be greater than 1\")\n    } else {\n      setValidateMessage(\"\")\n    }\n  }, [])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setMarkers: (markers: unknown) => {\n        if (!Array.isArray(markers)) {\n          console.error(\"TypeError: value is not a boolean\")\n          return\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { markers },\n          },\n        ])\n      },\n      resetMarkers: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { markers: JSON.parse(DefaultMarkers || \"{}\") },\n          },\n        ])\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  ])\n\n  useEffect(() => {\n    checkZoom(zoom)\n  }, [checkZoom, zoom])\n\n  const handleOnMarkerSelect = useCallback(() => {\n    triggerEventHandler(\"markerSelected\")\n  }, [triggerEventHandler])\n\n  const handleOnMarkerCreated = useCallback(() => {\n    triggerEventHandler(\"markerCreated\")\n  }, [triggerEventHandler])\n\n  return (\n    <div css={applyMapContainer}>\n      <WrapperMap\n        markers={markers}\n        center={center}\n        loading={loading}\n        zoom={zoom}\n        displayName={displayName}\n        handleUpdateMultiExecutionResult={handleUpdateMultiExecutionResult}\n        handleOnMarkerSelect={handleOnMarkerSelect}\n        handleOnMarkerCreated={handleOnMarkerCreated}\n        {...rest}\n      />\n      <div css={applyValidStyle}>\n        <InvalidMessage validateMessage={message} />\n      </div>\n    </div>\n  )\n}\n\nMapWidget.displayName = \"MapWidget\"\nexport default MapWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/mapBox.tsx",
    "content": "import {\n  GoogleMap,\n  Marker,\n  MarkerClusterer,\n  useJsApiLoader,\n} from \"@react-google-maps/api\"\nimport { FC, useEffect } from \"react\"\nimport { SearchInput } from \"./SearchInput\"\nimport {\n  ContainerStyle,\n  DefaultCenter,\n  DefaultZoom,\n  LatitudeFieldName,\n  Libraries,\n  LongitudeFieldName,\n} from \"./content\"\nimport { LatLng, MapProps } from \"./interface\"\nimport { useCenter } from \"./useCenter\"\nimport { useMark } from \"./useMark\"\n\nexport const MapBox: FC<MapProps> = ({\n  center = DefaultCenter,\n  latitudeFieldName = LatitudeFieldName,\n  longitudeFieldName = LongitudeFieldName,\n  zoom = DefaultZoom,\n  markers = \"\",\n  enableAddMark = true,\n  enableSearch = true,\n  enableClustering = false,\n  onMarkerSelected,\n  onMarkerCreated,\n  onMarkersChanged,\n}) => {\n  const { currentMarks, addMark } = useMark(\n    markers,\n    latitudeFieldName,\n    longitudeFieldName,\n  )\n  const {\n    map,\n    currentCenter,\n    currentZoom,\n    handleLoad,\n    handleUnmount,\n    setCurrentZoom,\n  } = useCenter(center, zoom, latitudeFieldName, longitudeFieldName)\n  const mapClick = (e: google.maps.MapMouseEvent) => {\n    if (!enableAddMark) return\n    const { latLng } = e\n    const lat = latLng?.lat(),\n      lng = latLng?.lng()\n    if (lat !== undefined && lng !== undefined) {\n      addMark(lat, lng)\n      onMarkerCreated && onMarkerCreated({ lat, lng })\n    }\n  }\n  const { isLoaded } = useJsApiLoader({\n    id: \"google-map-script\",\n    googleMapsApiKey: import.meta.env.ILLA_GOOGLE_MAP_KEY,\n    libraries: Libraries,\n  })\n\n  const handlePlaceChanged = (location: google.maps.LatLngLiteral) => {\n    map?.panTo(location)\n    setCurrentZoom(8)\n  }\n\n  useEffect(() => {\n    onMarkersChanged && onMarkersChanged(currentMarks)\n  }, [currentMarks, onMarkersChanged])\n\n  if (!isLoaded) return null\n  return (\n    <GoogleMap\n      mapContainerStyle={ContainerStyle}\n      center={currentCenter}\n      zoom={currentZoom}\n      onClick={mapClick}\n      onLoad={handleLoad}\n      onUnmount={handleUnmount}\n    >\n      {enableSearch && <SearchInput onPlaceChanged={handlePlaceChanged} />}\n      {enableClustering && (\n        <MarkerClusterer averageCenter enableRetinaIcons gridSize={60}>\n          {(clusterer) => (\n            <div>\n              {currentMarks &&\n                currentMarks.map(\n                  ({ lat, lng }: LatLng, i: number) =>\n                    lat !== undefined &&\n                    lng !== undefined && (\n                      <Marker\n                        key={`${i}${lat}${lng}`}\n                        position={{ lat, lng }}\n                        clusterer={clusterer}\n                        onClick={() => {\n                          onMarkerSelected && onMarkerSelected({ lat, lng })\n                        }}\n                      />\n                    ),\n                )}\n            </div>\n          )}\n        </MarkerClusterer>\n      )}\n      {!enableClustering &&\n        currentMarks &&\n        currentMarks.map(\n          ({ lat, lng }: LatLng, i: number) =>\n            lat !== undefined &&\n            lng !== undefined && (\n              <Marker\n                key={`${i}${lat}${lng}`}\n                position={{ lat, lng }}\n                onClick={() => {\n                  onMarkerSelected && onMarkerSelected({ lat, lng })\n                }}\n              />\n            ),\n        )}\n    </GoogleMap>\n  )\n}\n\nMapBox.displayName = \"MapBox\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { MAP_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/MapBoxWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"map\"\nexport const MAP_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-initial-location`,\n        labelName: i18n.t(\"editor.inspect.setter_label.map.initial_location\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.map.initial_location\"),\n        attrName: \"center\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.OBJECT,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-default-markers`,\n        labelName: i18n.t(\"editor.inspect.setter_label.map.default_markers\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.map.default_markers\"),\n        attrName: \"markers\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.ARRAY,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-default-latitude-field-name`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.map.latitude_field_name\",\n        ),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.map.latitude_field_name\"),\n        isSetterSingleRow: true,\n        attrName: \"latitudeFieldName\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-default-longitude-field-name`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.map.longitude_field_name\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.map.longitude_field_name\",\n        ),\n        isSetterSingleRow: true,\n        attrName: \"longitudeFieldName\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-default-zoom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.map.zoom\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.map.zoom\"),\n        attrName: \"zoom\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          MAP_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-loading`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n        attrName: \"loading\",\n        placeholder: \"{{false}}\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"submit\"],\n        shown: (value) => {\n          return !value\n        },\n      },\n      {\n        id: `${baseWidgetName}-interaction-enableAddMark`,\n        labelName: i18n.t(\"editor.inspect.setter_label.map.enable_add_markers\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.map.enable_add_markers\"),\n        attrName: \"enableAddMark\",\n        placeholder: \"{{true}}\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-enableSearch`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.map.enable_search_locati\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.map.enable_search_locati\",\n        ),\n        attrName: \"enableSearch\",\n        placeholder: \"{{true}}\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-enableClustering`,\n        labelName: i18n.t(\"editor.inspect.setter_label.map.enable_clustering\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.map.enable_clustering\"),\n        attrName: \"enableClustering\",\n        placeholder: \"{{false}}\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const applyInput = `\n    background: #fff;\n    position: absolute;\n    width: 30%;\n    border-radius: 8px;\n    margin-top: 20px;\n    left: 50%;\n    transform: translateX(-50%);\n`\nexport const ApplyLoadingStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  color: ${getColor(\"black\", \"01\")};\n`\n\nexport const applyMapContainer = css`\n  width: 100%;\n  height: 100%;\n`\n\nexport const applyValidStyle = css`\n  position: absolute;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/useCenter.ts",
    "content": "import { debounce } from \"lodash-es\"\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { DefaultCenter } from \"./content\"\nimport { LatLng } from \"./interface\"\nimport { getCenter, getSafeZoom } from \"./utils\"\n\nexport const useCenter = (\n  center: string,\n  zoom: number,\n  latitudeFieldName: string,\n  longitudeFieldName: string,\n) => {\n  const centerChangedRef = useRef<google.maps.MapsEventListener>()\n  const zoomChangedRef = useRef<google.maps.MapsEventListener>()\n  const mapRef = useRef<google.maps.Map>()\n\n  const [currentCenter, setCurrentCenter] = useState<\n    google.maps.LatLng | LatLng\n  >(getCenter(center, latitudeFieldName, longitudeFieldName))\n\n  const [currentZoom, setCurrentZoom] = useState<number>(zoom)\n  const defaultCenter = useMemo(() => JSON.parse(DefaultCenter), [])\n  const handleLoad = useCallback(\n    (map: google.maps.Map) => {\n      mapRef.current = map\n      centerChangedRef.current = mapRef.current.addListener(\n        \"dragend\",\n        debounce(() => {\n          setCurrentCenter(mapRef.current?.getCenter() || defaultCenter)\n        }, 200),\n      )\n\n      zoomChangedRef.current = mapRef.current.addListener(\n        \"zoom_changed\",\n        debounce(() => {\n          setCurrentCenter(mapRef.current?.getCenter() || defaultCenter)\n        }, 200),\n      )\n    },\n    [defaultCenter],\n  )\n\n  const handleUnmount = useCallback(() => {\n    zoomChangedRef.current?.remove()\n    centerChangedRef.current?.remove()\n  }, [])\n\n  useEffect(() => {\n    setCurrentCenter(getCenter(center, latitudeFieldName, longitudeFieldName))\n  }, [center, latitudeFieldName, longitudeFieldName])\n\n  useEffect(() => {\n    const safeZoom = getSafeZoom(zoom)\n    setCurrentZoom(safeZoom)\n  }, [zoom])\n\n  return {\n    map: mapRef.current,\n    currentCenter,\n    currentZoom,\n    setCurrentZoom,\n    handleLoad,\n    handleUnmount,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/useMark.ts",
    "content": "import { useEffect, useState } from \"react\"\nimport { LatLng } from \"./interface\"\nimport { getMarkers } from \"./utils\"\n\nexport const useMark = (\n  markers: string,\n  latitudeFieldName: string,\n  longitudeFieldName: string,\n) => {\n  const tempMarks = JSON.parse(markers || \"[]\")\n  const [currentMarks, setCurrentMarks] = useState<LatLng[]>(\n    getMarkers(tempMarks, latitudeFieldName, longitudeFieldName),\n  )\n\n  const addMark = (lat: number, lng: number) => {\n    const marks = [...currentMarks, { lat, lng }]\n    setCurrentMarks(marks)\n  }\n\n  useEffect(() => {\n    const currentMarkers = getMarkers(\n      JSON.parse(markers || \"[]\"),\n      latitudeFieldName,\n      longitudeFieldName,\n    )\n    setCurrentMarks(currentMarkers)\n  }, [latitudeFieldName, longitudeFieldName, markers])\n  return {\n    currentMarks,\n    addMark,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/utils.ts",
    "content": "import { CustomLatLing, LatLng, MarkersType } from \"./interface\"\n\nexport const getMarkers = (\n  markers: MarkersType,\n  latitudeFieldName: string,\n  longitudeFieldName: string,\n): LatLng[] => {\n  if (latitudeFieldName !== \"lat\" || longitudeFieldName !== \"lng\") {\n    return (markers as CustomLatLing[]).map((item) => {\n      const lat = item[\"lat\"] ?? item[latitudeFieldName]\n      const lng = item[\"lng\"] ?? item[longitudeFieldName]\n      return { lat, lng }\n    })\n  }\n  return markers as LatLng[]\n}\n\nexport const getCenter = (\n  center: string,\n  latitudeFieldName: string,\n  longitudeFieldName: string,\n): LatLng => {\n  const strCenter = JSON.parse(center || \"{}\")\n  if (latitudeFieldName !== \"lat\" || longitudeFieldName !== \"lng\") {\n    const lat =\n      strCenter[\"lat\"] ?? (strCenter as CustomLatLing)[latitudeFieldName]\n    const lng =\n      strCenter[\"lng\"] ?? (strCenter as CustomLatLing)[longitudeFieldName]\n    return { lat, lng }\n  }\n  return strCenter as LatLng\n}\n\nexport const getSafeZoom = (zoom: number) => {\n  if (zoom > 22) {\n    return 22\n  } else if (zoom < 1) {\n    return 1\n  }\n  return zoom\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MapBoxWidget/widgetConfig.tsx",
    "content": "import MapWidgetIcon from \"@/assets/widgetCover/map.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\nimport { DefaultCenter, DefaultMarkers } from \"./content\"\n\nexport const MAP_WIDGET_CONFIG: WidgetConfig = {\n  type: \"MAP_WIDGET\",\n  displayName: \"map\",\n  widgetName: i18n.t(\"widget.map.name\"),\n  icon: <MapWidgetIcon />,\n  keywords: [\"MAP\", \"地图\"],\n  sessionType: \"PRESENTATION\",\n  w: 20,\n  h: 50,\n  version: 0,\n  defaults: {\n    latitudeFieldName: \"lat\",\n    longitudeFieldName: \"lng\",\n    hidden: false,\n    center: `{{${DefaultCenter}}}`,\n    zoom: \"{{3}}\",\n    markers: `{{${DefaultMarkers}}}`,\n    loading: \"{{false}}\",\n    enableAddMark: \"{{true}}\",\n    enableSearch: \"{{true}}\",\n    enableClustering: false,\n    selectMarker: \"{{{}}}\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MenuWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const MENU_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.click\",\n      ),\n      value: \"clickMenuItem\",\n    },\n  ],\n  methods: [],\n}\n\nexport const MAIN_MENU_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.on_menu_select\",\n      ),\n      value: \"onMenuSelect\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onMenuLogoClick\",\n      ),\n      value: \"onMenuLogoClick\",\n    },\n  ],\n  methods: [],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MenuWidget/index.ts",
    "content": "export { MENU_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { MENU_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\nexport { MENU_PANEL_CONFIG } from \"./panelConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MenuWidget/interface.ts",
    "content": "import { MenuProps } from \"@illa-design/react\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedMenuProps extends MenuProps {\n  menuLogo?: string\n  menuTitle?: string\n  onClickMenuLogo: () => void\n}\n\nexport interface MenuWidgetProps\n  extends Omit<WrappedMenuProps, \"handleOnClickMenuItem\" | \"w\" | \"h\">,\n    BaseWidgetProps {\n  menuLogo?: string\n  menuTitle?: string\n  optionConfigureMode?: \"dynamic\" | \"static\"\n  mappedOption?: {\n    labels: string[]\n    values: any[]\n    icons: string[]\n    disables: boolean[]\n    hidden: boolean[]\n    groupLabels: string[]\n  }\n  onClickMenuLogo: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MenuWidget/menu.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { toPath } from \"lodash-es\"\nimport { FC, useCallback, useMemo } from \"react\"\nimport { Image, Menu, MenuItemProps, SubMenuProps } from \"@illa-design/react\"\nimport {\n  applyMenuBrandContainerStyle,\n  applyMenuTitleStyle,\n  applyMenuWidgetContainerStyle,\n} from \"@/widgetLibrary/MenuWidget/style\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { MenuWidgetProps, WrappedMenuProps } from \"./interface\"\n\nexport const WrappedMenu: FC<WrappedMenuProps> = (props) => {\n  const {\n    menuTitle,\n    menuLogo,\n    bgColor,\n    colorScheme,\n    hoverColorScheme,\n    mode = \"horizontal\",\n    horizontalAlign,\n    selectedValues,\n    items,\n    onClickSubMenu,\n    onClickMenuItem,\n    onMenuSelect,\n    onClickMenuLogo,\n  } = props\n\n  const menuBrandContainer = useMemo(() => {\n    if (!menuTitle && !menuLogo) {\n      return <></>\n    } else {\n      return (\n        <div css={applyMenuBrandContainerStyle(mode)}>\n          {menuLogo && (\n            <Image\n              src={menuLogo}\n              width=\"unset\"\n              height={mode === \"horizontal\" ? \"24px\" : \"32px\"}\n              objectFit=\"scale-down\"\n              onClick={onClickMenuLogo}\n            />\n          )}\n          {menuTitle && <div css={applyMenuTitleStyle(mode)}>{menuTitle}</div>}\n        </div>\n      )\n    }\n  }, [menuLogo, menuTitle, mode, onClickMenuLogo])\n\n  return (\n    <div css={applyMenuWidgetContainerStyle(mode)}>\n      {menuBrandContainer}\n      <Menu\n        flexGrow=\"1\"\n        w=\"100%\"\n        colorScheme={colorScheme}\n        hoverColorScheme={hoverColorScheme}\n        bgColor={bgColor}\n        mode={mode}\n        selectedValues={selectedValues}\n        onClickSubMenu={onClickSubMenu}\n        horizontalAlign={horizontalAlign}\n        onClickMenuItem={onClickMenuItem}\n        items={items}\n        onMenuSelect={onMenuSelect}\n      />\n    </div>\n  )\n}\n\nexport const StaticMenuWidget: FC<MenuWidgetProps> = (props) => {\n  const {\n    menuTitle,\n    menuLogo,\n    bgColor,\n    colorScheme,\n    mode,\n    selectedValues,\n    hoverColorScheme,\n    horizontalAlign,\n    items,\n    displayName,\n    handleUpdateMultiExecutionResult,\n    updateComponentHeight,\n    triggerEventHandler,\n    onClickMenuLogo,\n  } = props\n  const handleOnClickMenuItem = useCallback(\n    (value: string, valuePath: string[]) => {\n      if (valuePath.length === 1) {\n        const index = items?.findIndex((i) => i.value === value) ?? 0\n        const pathArray = [\"items\", `${index}`, \"events\"]\n        triggerEventHandler(\n          \"clickMenuItem\",\n          convertPathToString(pathArray),\n          undefined,\n          (path) => {\n            return convertPathToString(toPath(path).slice(3))\n          },\n        )\n      } else if (valuePath.length === 2) {\n        const sub = items?.findIndex((i) => i.value === valuePath[0])\n        if (\n          sub != undefined &&\n          sub !== -1 &&\n          items &&\n          \"subItems\" in items[sub]\n        ) {\n          const subIndex = (items[sub] as SubMenuProps).subItems?.findIndex(\n            (i) => i.value === valuePath[1],\n          )\n          const pathArray = [\n            \"items\",\n            `${sub}`,\n            \"subItems\",\n            `${subIndex}`,\n            \"events\",\n          ]\n          triggerEventHandler(\n            \"clickMenuItem\",\n            convertPathToString(pathArray),\n            undefined,\n            (path) => {\n              return convertPathToString(toPath(path).slice(5))\n            },\n          )\n        }\n      }\n    },\n    [items, triggerEventHandler],\n  )\n\n  const handleClickSubMenu = useCallback(\n    (value: string) => {\n      const index = items?.findIndex((i) => i.value === value)\n      if (index != undefined && index !== -1) {\n        const paths = [\"items\", `${index}`, \"events\"]\n        triggerEventHandler(\n          \"clickMenuItem\",\n          convertPathToString(paths),\n          undefined,\n          (path) => {\n            return convertPathToString(toPath(path).slice(3))\n          },\n        )\n      }\n    },\n    [items, triggerEventHandler],\n  )\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <WrappedMenu\n        menuTitle={menuTitle}\n        menuLogo={menuLogo}\n        selectedValues={\n          Array.isArray(selectedValues)\n            ? selectedValues\n            : [JSON.stringify(selectedValues)]\n        }\n        colorScheme={colorScheme}\n        hoverColorScheme={hoverColorScheme}\n        bgColor={bgColor}\n        mode={mode}\n        horizontalAlign={horizontalAlign}\n        onClickMenuItem={handleOnClickMenuItem}\n        onClickSubMenu={handleClickSubMenu}\n        items={items}\n        onMenuSelect={(value, valuePath, selectedValues) => {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                selectedValues: selectedValues,\n              },\n            },\n          ])\n          triggerEventHandler(\"onMenuSelect\")\n        }}\n        onClickMenuLogo={onClickMenuLogo}\n      />\n    </AutoHeightContainer>\n  )\n}\n\nexport const DynamicMenuWidget: FC<MenuWidgetProps> = (props) => {\n  const {\n    menuTitle,\n    menuLogo,\n    bgColor,\n    colorScheme,\n    mode,\n    selectedValues,\n    hoverColorScheme,\n    horizontalAlign,\n    updateComponentHeight,\n    mappedOption,\n    triggerEventHandler,\n    displayName,\n    handleUpdateMultiExecutionResult,\n    onClickMenuLogo,\n  } = props\n\n  const total = mappedOption?.values?.length ?? 0\n\n  const items: MenuItemProps[] = []\n\n  if (mappedOption && total !== 0) {\n    for (let i = 0; i < total; i++) {\n      if (mappedOption.groupLabels?.[i]) {\n        let parent = items.find(\n          (v) => v.label === mappedOption.groupLabels?.[i],\n        ) as SubMenuProps\n\n        if (!parent) {\n          parent = {\n            label:\n              typeof mappedOption.groupLabels?.[i] === \"string\"\n                ? mappedOption.groupLabels?.[i]\n                : JSON.stringify(mappedOption.groupLabels?.[i]),\n            value:\n              typeof mappedOption.groupLabels?.[i] === \"string\"\n                ? mappedOption.groupLabels?.[i]\n                : JSON.stringify(mappedOption.groupLabels?.[i]),\n            subItems: [],\n          } as SubMenuProps\n          items.push(parent)\n        }\n        parent.subItems!!.push({\n          disabled: mappedOption.disables?.[i],\n          hidden: mappedOption.hidden?.[i],\n          label: mappedOption.labels?.[i],\n          value: mappedOption.values?.[i],\n        } as MenuItemProps)\n      } else {\n        items.push({\n          disabled: mappedOption.disables?.[i],\n          hidden: mappedOption.hidden?.[i],\n          label: mappedOption.labels?.[i],\n          value: mappedOption.values?.[i],\n        } as SubMenuProps)\n      }\n    }\n  }\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <WrappedMenu\n        menuTitle={menuTitle}\n        menuLogo={menuLogo}\n        selectedValues={\n          Array.isArray(selectedValues)\n            ? selectedValues\n            : [JSON.stringify(selectedValues)]\n        }\n        colorScheme={colorScheme}\n        hoverColorScheme={hoverColorScheme}\n        bgColor={bgColor}\n        items={items}\n        mode={mode}\n        horizontalAlign={horizontalAlign}\n        onMenuSelect={(value, valuePath, selectedValues) => {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                selectedValues: selectedValues,\n              },\n            },\n          ])\n          triggerEventHandler(\"onMenuSelect\")\n        }}\n        onClickMenuLogo={onClickMenuLogo}\n      />\n    </AutoHeightContainer>\n  )\n}\n\nexport const MenuWidget: FC<MenuWidgetProps> = (props) => {\n  const { optionConfigureMode, triggerEventHandler } = props\n\n  const handleClickMenuLogo = useCallback(() => {\n    triggerEventHandler(\"onMenuLogoClick\")\n  }, [triggerEventHandler])\n\n  if (optionConfigureMode === \"static\") {\n    return <StaticMenuWidget {...props} onClickMenuLogo={handleClickMenuLogo} />\n  } else {\n    return (\n      <DynamicMenuWidget {...props} onClickMenuLogo={handleClickMenuLogo} />\n    )\n  }\n}\n\nStaticMenuWidget.displayName = \"StaticMenuWidget\"\nDynamicMenuWidget.displayName = \"DynamicMenuWidget\"\nWrappedMenu.displayName = \"WrappedMenu\"\nexport default MenuWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MenuWidget/panelConfig.tsx",
    "content": "import {\n  HorizontalCenterIcon,\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n} from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport {\n  MAIN_MENU_EVENT_HANDLER_CONFIG,\n  MENU_EVENT_HANDLER_CONFIG,\n} from \"@/widgetLibrary/MenuWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"menu\"\n\nexport const MENU_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-menu`,\n    groupName: i18n.t(\"editor.inspect.setter_group.menu\"),\n    children: [\n      {\n        id: `${baseWidgetName}-options-mode`,\n        attrName: \"optionConfigureMode\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: i18n.t(\"widget.public.select_options.manual\"),\n            value: \"static\",\n          },\n          {\n            label: i18n.t(\"widget.public.select_options.mapped\"),\n            value: \"dynamic\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-items`,\n        useCustomLayout: true,\n        attrName: \"items\",\n        setterType: \"MENU_OPTION_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        openDynamic: true,\n        shown: (value) => !value || value === \"static\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-menu-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-menu-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"value\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-menu-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            setterType: \"DYNAMIC_SWITCH_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n            openDynamic: true,\n            useCustomLayout: true,\n          },\n          {\n            id: `${baseWidgetName}-menu-hidden`,\n            labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n            attrName: \"hidden\",\n            setterType: \"DYNAMIC_SWITCH_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n            openDynamic: true,\n            useCustomLayout: true,\n          },\n          {\n            ...generatorEventHandlerConfig(\n              baseWidgetName,\n              MENU_EVENT_HANDLER_CONFIG.events,\n            ),\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-options-data-sources`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_sources\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        expectedType: VALIDATION_TYPES.ARRAY,\n        shown: (value) => value === \"dynamic\",\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-options-mapped`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedOption\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => value === \"dynamic\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-mappedOption-labels`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"labels\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-values`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"values\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-disables`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disables\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-hidden`,\n            labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n            attrName: \"hidden\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-groupLabels`,\n            labelName: i18n.t(\"editor.inspect.setter_label.menu.groupLabels\"),\n            attrName: \"groupLabels\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-options-default-value`,\n        bindAttrName: [\"optionConfigureMode\"],\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"selectedValues\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          MAIN_MENU_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-logo`,\n        labelName: i18n.t(\"editor.inspect.setter_label.menu.logo\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.menu.logo\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"menuLogo\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-adornments-title`,\n        labelName: i18n.t(\"editor.inspect.setter_label.menu.title\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.menu.title\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"menuTitle\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-direction`,\n        labelName: i18n.t(\"editor.inspect.setter_label.direction\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.timeline_direction\"),\n        setterType: \"RADIO_GROUP_SETTER\",\n        attrName: \"mode\",\n        options: [\n          { label: i18n.t(\"widget.timeline.vertical\"), value: \"vertical\" },\n          {\n            label: i18n.t(\"widget.timeline.horizontal\"),\n            value: \"horizontal\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-align`,\n        labelName: i18n.t(\"editor.inspect.setter_label.align\"),\n        attrName: \"horizontalAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"mode\"],\n        shown: (mode) => mode === \"horizontal\",\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"flex-start\",\n          },\n          {\n            label: <HorizontalCenterIcon />,\n            value: \"center\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"flex-end\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-colors-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n          {\n            id: `${baseWidgetName}-colors-hoverBackgroundColor`,\n            labelName: i18n.t(\"editor.inspect.setter_label.hover_bg_color\"),\n            attrName: \"hoverColorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"gray\",\n          },\n          {\n            id: `${baseWidgetName}-colors-backgroundColor`,\n            labelName: i18n.t(\"editor.inspect.setter_label.background_color\"),\n            attrName: \"bgColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"transparent\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MenuWidget/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { MenuMode, getColor } from \"@illa-design/react\"\n\nexport function applyMenuBrandContainerStyle(mode: MenuMode): SerializedStyles {\n  return css`\n    display: inline-flex;\n    flex-direction: row;\n    align-items: center;\n    padding: ${mode === \"horizontal\" ? \"0px\" : \"16px\"} 16px;\n    padding-bottom: ${mode === \"horizontal\" ? \"0px\" : \"8px\"};\n    margin-right: ${mode === \"horizontal\" ? \"16px\" : \"0px\"};\n  `\n}\n\nexport function applyMenuTitleStyle(mode: MenuMode): SerializedStyles {\n  return css`\n    margin-left: ${mode === \"horizontal\" ? \"8px\" : \"12px\"};\n    color: ${getColor(\"grayBlue\", \"02\")};\n    font-size: 14px;\n    font-style: normal;\n    white-space: nowrap;\n    font-weight: 500;\n  `\n}\n\nexport function applyMenuWidgetContainerStyle(\n  mode: MenuMode,\n): SerializedStyles {\n  return css`\n    display: flex;\n    flex-direction: ${mode === \"horizontal\" ? \"row\" : \"column\"};\n    align-items: ${mode === \"horizontal\" ? \"center\" : \"flex-start\"};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MenuWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport MenuWidgetIcon from \"@/assets/widgetCover/menu.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nconst items = [\n  {\n    id: v4(),\n    value: \"menu0\",\n    label: \"Menu 0\",\n  },\n  {\n    id: v4(),\n    value: \"menu1\",\n    label: \"Menu 1\",\n    subItems: [\n      {\n        id: v4(),\n        value: \"menu1:subMenu0\",\n        label: \"Sub Menu 0\",\n      },\n      {\n        id: v4(),\n        value: \"menu1:subMenu1\",\n        label: \"Sub Menu 1\",\n      },\n    ],\n  },\n  {\n    id: v4(),\n    value: \"menu2\",\n    label: \"Menu 2\",\n    subItems: [\n      {\n        id: v4(),\n        value: \"menu2:subMenu0\",\n        label: \"Sub Menu 0\",\n      },\n      {\n        id: v4(),\n        value: \"menu2:subMenu1\",\n        label: \"Sub Menu 1\",\n      },\n    ],\n  },\n]\n\nexport const MENU_WIDGET_CONFIG: WidgetConfig = {\n  displayName: \"menu\",\n  widgetName: i18n.t(\"widget.menu.name\"),\n  h: 7,\n  w: 15,\n  type: \"MENU_WIDGET\",\n  icon: <MenuWidgetIcon />,\n  keywords: [\"Menu\", \"菜单\"],\n  sessionType: \"NAVIGATION\",\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 1,\n  defaults: {\n    items,\n    optionConfigureMode: \"static\",\n    dataSources: \"{{[]}}\",\n    selectedValues: \"{{[]}}\",\n    mode: \"horizontal\",\n    horizontalAlign: \"flex-start\",\n    colorScheme: \"blue\",\n    bgColor: \"transparent\",\n    hoverColorScheme: \"grayBlue\",\n    menuTitle: \"ILLA\",\n    menuLogo:\n      \"https://cloud-api.illacloud.com/drive/f/0f3ef4da-7741-45f8-b054-57458c244214\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ModalWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const MODAL_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onOpenModal\",\n      ),\n      value: \"onOpenModal\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onCloseModal\",\n      ),\n      value: \"onCloseModal\",\n    },\n  ],\n  methods: [\"openModal\", \"closeModal\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ModalWidget/index.ts",
    "content": "export * from \"./panelConfig\"\nexport * from \"./widgetConfig\"\nexport * from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ModalWidget/interface.ts",
    "content": "import { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface ModalWidgetProps extends BaseWidgetProps {\n  childrenNode: string[]\n  showFooter: boolean\n  showHeader: boolean\n  headerHeight: number\n  footerHeight: number\n  handleUpdateDsl: (value: Record<string, any>) => void\n  handleUpdateOriginalDSLMultiAttr: (updateSlice: Record<string, any>) => void\n  unitH: number\n  isVisible: boolean\n  columnNumber: number\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ModalWidget/modal.tsx",
    "content": "import { Resizable, ResizeCallback, ResizeStartCallback } from \"re-resizable\"\nimport {\n  FC,\n  MutableRefObject,\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport { useDrop } from \"react-dnd\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport useMeasure from \"react-use-measure\"\nimport ResizeBar from \"@/assets/resizeBar.svg?react\"\nimport { DropResultInfo } from \"@/page/App/components/DotPanel/components/Canvas/interface\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { DragInfo } from \"@/page/App/components/ScaleSquare/components/DragContainer/interface\"\nimport {\n  applyDashedLineStyle,\n  applyXDirectionDashedLineStyle,\n} from \"@/page/App/components/ScaleSquare/style\"\nimport { getIsILLAEditMode } from \"@/redux/config/configSelector\"\nimport { configActions } from \"@/redux/config/configSlice\"\nimport RenderChildrenCanvas from \"../PublicSector/RenderChildrenCanvas\"\nimport { ModalWidgetProps } from \"./interface\"\nimport {\n  formBodyStyle,\n  formContainerStyle,\n  formHeaderStyle,\n  resizeBarStyle,\n  resizeLineStyle,\n} from \"./style\"\nimport {\n  MODAL_BODY_MARGIN,\n  MODAL_BODY_MIN_HEIGHT,\n  MODAL_MIN_FOOTER_HEIGHT_ROW_NUMBER,\n  MODAL_MIN_HEADER_HEIGHT_ROW_NUMBER,\n} from \"./widgetConfig\"\n\ninterface DragCollection {\n  isDraggingActive: boolean\n}\n\nexport const ModalWidget: FC<ModalWidgetProps> = (props) => {\n  const {\n    childrenNode,\n    showFooter,\n    showHeader,\n    headerHeight,\n    footerHeight,\n    isVisible,\n    columnNumber,\n    displayName,\n    handleUpdateOriginalDSLMultiAttr,\n    triggerEventHandler,\n  } = props\n\n  const prevVisible = useRef<boolean>()\n  const isMount = useRef(false)\n  const dispatch = useDispatch()\n\n  useEffect(() => {\n    isMount.current = true\n\n    return () => {\n      isMount.current = false\n    }\n  }, [])\n\n  useEffect(() => {\n    if (isVisible && prevVisible.current !== isVisible && isMount.current) {\n      triggerEventHandler(\"onOpenModal\")\n      prevVisible.current = true\n    }\n\n    return () => {\n      if (isVisible && !isMount.current) {\n        triggerEventHandler(\"onCloseModal\")\n      }\n    }\n  }, [isVisible, triggerEventHandler])\n\n  const [containerRef, containerBounds] = useMeasure()\n  const containerNodeRef = useRef<HTMLDivElement>(\n    null,\n  ) as MutableRefObject<HTMLDivElement | null>\n  const [isMouseHover, setIsMouseHover] = useState(false)\n\n  const headerMinHeight = useMemo(\n    () => MODAL_MIN_HEADER_HEIGHT_ROW_NUMBER * UNIT_HEIGHT,\n    [],\n  )\n  const footerMinHeight = useMemo(\n    () => MODAL_MIN_FOOTER_HEIGHT_ROW_NUMBER * UNIT_HEIGHT,\n    [],\n  )\n\n  const headerMaxHeight = useMemo(() => {\n    return (\n      Math.floor(\n        (containerBounds.height -\n          (MODAL_BODY_MIN_HEIGHT + 2 * MODAL_BODY_MARGIN) -\n          footerHeight * UNIT_HEIGHT) /\n          UNIT_HEIGHT,\n      ) * UNIT_HEIGHT\n    )\n  }, [containerBounds.height, footerHeight])\n\n  const footerMaxHeight = useMemo(() => {\n    return (\n      Math.floor(\n        (containerBounds.height -\n          (MODAL_BODY_MIN_HEIGHT + 2 * MODAL_BODY_MARGIN) -\n          headerHeight * UNIT_HEIGHT) /\n          UNIT_HEIGHT,\n      ) * UNIT_HEIGHT\n    )\n  }, [containerBounds.height, headerHeight])\n\n  const isEditMode = useSelector(getIsILLAEditMode)\n\n  const handleUpdateHeight = useCallback((_height: number) => {\n    // TODO: auto height\n  }, [])\n\n  const resizeTopHandler = useMemo(() => {\n    return {\n      bottom: (\n        <div css={resizeLineStyle}>\n          <ResizeBar css={resizeBarStyle} />\n        </div>\n      ),\n    }\n  }, [])\n\n  const resizeBottomHandler = useMemo(() => {\n    return {\n      top: (\n        <div css={resizeLineStyle}>\n          <ResizeBar css={resizeBarStyle} />\n        </div>\n      ),\n    }\n  }, [])\n\n  const handleResizeStart: ResizeStartCallback = (e) => {\n    e.preventDefault()\n    e.stopPropagation()\n    dispatch(\n      configActions.setResizingNodeIDsReducer([\n        `${displayName}-resize-modal-header`,\n      ]),\n    )\n  }\n\n  const handleOnResizeTopStop: ResizeCallback = useCallback(\n    (e, dir, elementRef, delta) => {\n      const { height } = delta\n      let finalHeight = Math.floor(\n        (headerHeight * UNIT_HEIGHT + height) / UNIT_HEIGHT,\n      )\n      if (finalHeight * UNIT_HEIGHT >= headerMaxHeight) {\n        finalHeight = Math.floor(headerMaxHeight / UNIT_HEIGHT)\n      }\n      handleUpdateOriginalDSLMultiAttr({\n        headerHeight: finalHeight,\n      })\n      dispatch(configActions.setResizingNodeIDsReducer([]))\n    },\n    [dispatch, handleUpdateOriginalDSLMultiAttr, headerHeight, headerMaxHeight],\n  )\n\n  const handleOnResizeBottomStop: ResizeCallback = useCallback(\n    (e, dir, elementRef, delta) => {\n      const { height } = delta\n      let finalHeight = Math.floor(\n        (footerHeight * UNIT_HEIGHT + height) / UNIT_HEIGHT,\n      )\n      if (finalHeight * UNIT_HEIGHT > footerMaxHeight) {\n        finalHeight = Math.floor(footerMaxHeight / UNIT_HEIGHT)\n      }\n      handleUpdateOriginalDSLMultiAttr({\n        footerHeight: finalHeight,\n      })\n      dispatch(configActions.setResizingNodeIDsReducer([]))\n    },\n    [dispatch, footerHeight, footerMaxHeight, handleUpdateOriginalDSLMultiAttr],\n  )\n\n  const [{ isDraggingActive }, dropRef] = useDrop<\n    DragInfo,\n    DropResultInfo,\n    DragCollection\n  >(\n    () => ({\n      accept: [\"components\"],\n      collect: (monitor) => {\n        return {\n          isDraggingActive: monitor.isOver(),\n        }\n      },\n    }),\n    [],\n  )\n\n  return (\n    <div\n      css={formContainerStyle}\n      ref={(node) => {\n        dropRef(node)\n        containerRef(node)\n        containerNodeRef.current = node\n      }}\n      onMouseEnter={() => {\n        setIsMouseHover(true)\n      }}\n      onMouseLeave={() => {\n        setIsMouseHover(false)\n      }}\n    >\n      {showHeader && (\n        <Resizable\n          size={{\n            width: \"100%\",\n            height: headerHeight * UNIT_HEIGHT,\n          }}\n          minHeight={headerMinHeight}\n          maxHeight={headerMaxHeight}\n          handleComponent={\n            isMouseHover && !isDraggingActive ? resizeTopHandler : undefined\n          }\n          enable={{\n            bottom: isEditMode,\n          }}\n          onResizeStart={handleResizeStart}\n          onResizeStop={handleOnResizeTopStop}\n        >\n          <div css={formHeaderStyle}>\n            <RenderChildrenCanvas\n              displayName={childrenNode[0]}\n              columnNumber={columnNumber}\n              handleUpdateHeight={handleUpdateHeight}\n            />\n          </div>\n          {isEditMode && isMouseHover && !isDraggingActive && (\n            <div css={applyDashedLineStyle(false, true, false)} />\n          )}\n        </Resizable>\n      )}\n      <div css={formBodyStyle}>\n        <RenderChildrenCanvas\n          displayName={childrenNode[1]}\n          columnNumber={columnNumber}\n          handleUpdateHeight={handleUpdateHeight}\n        />\n        {isEditMode && isMouseHover && !isDraggingActive && (\n          <div css={applyXDirectionDashedLineStyle(false, true, false)} />\n        )}\n      </div>\n      {showFooter && (\n        <Resizable\n          size={{\n            width: \"100%\",\n            height: footerHeight * UNIT_HEIGHT,\n          }}\n          minHeight={footerMinHeight}\n          maxHeight={footerMaxHeight}\n          handleComponent={\n            isMouseHover && !isDraggingActive ? resizeBottomHandler : undefined\n          }\n          enable={{\n            top: isEditMode,\n          }}\n          onResizeStart={handleResizeStart}\n          onResizeStop={handleOnResizeBottomStop}\n        >\n          <div css={formHeaderStyle}>\n            <RenderChildrenCanvas\n              displayName={childrenNode[2]}\n              columnNumber={columnNumber}\n              handleUpdateHeight={handleUpdateHeight}\n            />\n          </div>\n          {isEditMode && isMouseHover && !isDraggingActive && (\n            <div\n              css={applyDashedLineStyle(false, true, false, footerMaxHeight)}\n            />\n          )}\n        </Resizable>\n      )}\n    </div>\n  )\n}\n\nModalWidget.displayName = \"ModalWidget\"\nexport default ModalWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ModalWidget/panelConfig.tsx",
    "content": "import RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { MODAL_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/ModalWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"modal\"\nexport const MODAL_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          MODAL_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-closeOnMaskClick`,\n        labelName: i18n.t(\"editor.inspect.setter.click_mask_close\"),\n        attrName: \"clickMaskClose\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-show-header`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_header\"),\n        attrName: \"showHeader\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n      {\n        id: `${baseWidgetName}-layout-show-footer`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_footer\"),\n        attrName: \"showFooter\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-styles`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"border\",\n      },\n      {\n        id: `${baseWidgetName}-styles-color`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"border\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-background`,\n            labelName: i18n.t(\"editor.inspect.setter_label.background\"),\n            attrName: \"backgroundColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"#ffffffff\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            attrName: \"radius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ModalWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const formContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  position: relative;\n  overflow: hidden;\n`\n\nexport const formHeaderStyle = css`\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n`\nexport const formBodyStyle = css`\n  width: 100%;\n  height: 100%;\n  min-height: 100px;\n  flex: 1;\n  overflow-y: auto;\n  position: relative;\n`\nexport const resizeLineStyle = css`\n  width: 100%;\n  height: 100%;\n  cursor: row-resize;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n\nexport const resizeBarStyle = css`\n  fill: ${globalColor(`--${illaPrefix}-white-01`)};\n  stroke: ${globalColor(`--${illaPrefix}-techPurple-03`)};\n  :hover {\n    fill: ${globalColor(`--${illaPrefix}-techPurple-03`)};\n    stroke: ${globalColor(`--${illaPrefix}-white-01`)};\n  }\n  :active {\n    fill: ${globalColor(`--${illaPrefix}-techPurple-03`)};\n    stroke: ${globalColor(`--${illaPrefix}-white-01`)};\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/ModalWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport ModalWidgetIcon from \"@/assets/widgetCover/modal.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { BasicContainerConfig } from \"@/widgetLibrary/BasicContainer/BasicContainer\"\nimport { BUTTON_WIDGET_CONFIG } from \"@/widgetLibrary/ButtonWidget\"\nimport { TEXT_WIDGET_CONFIG } from \"@/widgetLibrary/TextWidget\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const MODAL_WIDGET_CONFIG: WidgetConfig = {\n  type: \"MODAL_WIDGET\",\n  displayName: \"modal\",\n  widgetName: i18n.t(\"widget.modal.name\"),\n  keywords: [\"modal\", \"对话框\"],\n  icon: <ModalWidgetIcon />,\n  sessionType: \"CONTAINER\",\n  w: 16,\n  h: 40,\n  version: 0,\n  childrenNode: [\n    {\n      ...BasicContainerConfig,\n      childrenNode: [\n        {\n          ...TEXT_WIDGET_CONFIG,\n          w: 5,\n          h: 5,\n          x: 0,\n          y: 0,\n          defaults: {\n            ...TEXT_WIDGET_CONFIG.defaults,\n            value: \"### Modal\",\n          },\n        },\n      ],\n    },\n    BasicContainerConfig,\n    {\n      ...BasicContainerConfig,\n      childrenNode: [\n        {\n          ...BUTTON_WIDGET_CONFIG,\n          w: 8,\n          h: 5,\n          x: 24,\n          y: 0,\n          defaults: {\n            ...BUTTON_WIDGET_CONFIG.defaults,\n            text: \"Confirm\",\n            events: [\n              {\n                actionType: \"widget\",\n                id: v4(),\n                eventType: \"click\",\n                widgetID: \"modal\",\n                widgetMethod: \"closeModal\",\n              },\n            ],\n          },\n        },\n        {\n          ...BUTTON_WIDGET_CONFIG,\n          w: 8,\n          h: 5,\n          x: 16,\n          y: 0,\n          defaults: {\n            ...BUTTON_WIDGET_CONFIG.defaults,\n            text: \"Cancel\",\n            variant: \"outline\",\n            events: [\n              {\n                actionType: \"widget\",\n                id: v4(),\n                eventType: \"click\",\n                widgetID: \"modal\",\n                widgetMethod: \"closeModal\",\n              },\n            ],\n          },\n        },\n      ],\n    },\n  ],\n  defaults: {\n    clickMaskClose: false,\n    showHeader: true,\n    showFooter: true,\n    backgroundColor: \"#ffffffff\",\n    radius: \"4px\",\n    shadow: \"small\",\n    headerHeight: 11,\n    footerHeight: 7,\n  },\n}\n\nexport const MODAL_BODY_MIN_HEIGHT = 100\nexport const MODAL_MIN_FOOTER_HEIGHT_ROW_NUMBER = 7\nexport const MODAL_MIN_HEADER_HEIGHT_ROW_NUMBER = 7\nexport const MODAL_BODY_MARGIN = 7\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MultiselectWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const MULTISELECT_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.focus\",\n      ),\n      value: \"focus\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.blur\",\n      ),\n      value: \"blur\",\n    },\n  ],\n  methods: [\"setSelectedValue\", \"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MultiselectWidget/index.tsx",
    "content": "export { MULTISELECT_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\nexport { MULTISELECT_PANEL_CONFIG } from \"./panelConfig\"\nexport { MULTISELECT_WIDGET_CONFIG } from \"./widgetConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MultiselectWidget/interface.ts",
    "content": "import { SelectProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedMultiselectProps\n  extends Omit<ValidateMessageOldProps, \"value\">,\n    Pick<\n      SelectProps,\n      | \"options\"\n      | \"value\"\n      | \"placeholder\"\n      | \"disabled\"\n      | \"loading\"\n      | \"readOnly\"\n      | \"showSearch\"\n      | \"colorScheme\"\n    > {\n  showClear?: SelectProps[\"allowClear\"]\n  invalid?: boolean\n  displayName: string\n  handleUpdateDsl: (value: any) => void\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n  handleOnBlur?: () => void\n  handleOnFocus?: () => void\n}\n\nexport interface MultiselectWidgetProps\n  extends WrappedMultiselectProps,\n    BaseWidgetProps,\n    LabelProps,\n    Omit<TooltipWrapperProps, \"children\"> {\n  validateMessage: string\n  dataSources: unknown[]\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  dynamicMinHeight?: number\n  dynamicMaxHeight?: number\n  atLeastNumber?: number\n  upToNumber?: number\n  optionConfigureMode?: \"dynamic\" | \"static\"\n  manualOptions?: {\n    label: string\n    value: string | number\n    disabled?: boolean\n    extra?: any\n  }[]\n  mappedOption?: {\n    labels: string[]\n    values: any[]\n    disables: boolean[]\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MultiselectWidget/multiselect.tsx",
    "content": "import { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { Select } from \"@illa-design/react\"\nimport {\n  MultiselectWidgetProps,\n  WrappedMultiselectProps,\n} from \"@/widgetLibrary/MultiselectWidget/interface\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { formatSelectOptions } from \"@/widgetLibrary/PublicSector/utils/formatSelectOptions\"\n\nexport const WrappedMultiselect: FC<WrappedMultiselectProps> = (props) => {\n  const {\n    showClear,\n    value,\n    options,\n    placeholder,\n    disabled,\n    loading,\n    readOnly,\n    colorScheme,\n    handleUpdateMultiExecutionResult,\n    handleOnChange,\n    getValidateMessage,\n    displayName,\n  } = props\n\n  const onChangeSelectValue = useCallback(\n    (value: unknown) => {\n      new Promise((resolve) => {\n        const message = getValidateMessage(value)\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: value || [],\n              validateMessage: message,\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        handleOnChange?.()\n      })\n    },\n    [\n      displayName,\n      getValidateMessage,\n      handleOnChange,\n      handleUpdateMultiExecutionResult,\n    ],\n  )\n\n  return (\n    <Select\n      allowClear={showClear}\n      multiple\n      options={options}\n      value={Array.isArray(value) ? value : []}\n      placeholder={placeholder}\n      disabled={disabled}\n      loading={loading}\n      readOnly={readOnly}\n      showSearch\n      colorScheme={colorScheme}\n      onChange={onChangeSelectValue}\n    />\n  )\n}\nWrappedMultiselect.displayName = \"WrappedMultiselect\"\n\nexport const MultiselectWidget: FC<MultiselectWidgetProps> = (props) => {\n  const {\n    value,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    dynamicHeight,\n    atLeastNumber,\n    upToNumber,\n    required,\n    labelHidden,\n    tooltipText,\n    customRule,\n    hideValidationMessage,\n    validateMessage,\n    optionConfigureMode,\n    mappedOption,\n    manualOptions,\n    updateComponentHeight,\n    triggerEventHandler,\n  } = props\n\n  const getValidateMessage = useCallback(\n    (value: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n          atLeastNumber,\n          upToNumber,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required, atLeastNumber, upToNumber],\n  )\n\n  const handleValidate = useCallback(\n    (value: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [getValidateMessage, handleUpdateDsl],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setSelectedValue: (value: any) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: undefined })\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {\n        handleUpdateDsl({\n          validateMessage: undefined,\n        })\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    handleValidate,\n    updateComponentRuntimeProps,\n    value,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  const handleOnFocus = useCallback(() => {\n    triggerEventHandler(\"focus\")\n  }, [triggerEventHandler])\n\n  const handleOnBlur = useCallback(() => {\n    triggerEventHandler(\"blur\")\n  }, [triggerEventHandler])\n\n  const enableAutoHeight =\n    dynamicHeight !== \"fixed\" && dynamicHeight != undefined\n\n  const finalOptions = useMemo(() => {\n    return formatSelectOptions(optionConfigureMode, manualOptions, mappedOption)\n  }, [optionConfigureMode, manualOptions, mappedOption])\n\n  return (\n    <AutoHeightContainer\n      updateComponentHeight={updateComponentHeight}\n      enable={enableAutoHeight}\n    >\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedMultiselect\n            {...props}\n            options={finalOptions}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n            handleOnBlur={handleOnBlur}\n            handleOnFocus={handleOnFocus}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\n\nMultiselectWidget.displayName = \"MultiselectWidget\"\nexport default MultiselectWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MultiselectWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { MULTISELECT_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/MultiselectWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst baseWidgetName = \"multiselect\"\nexport const MULTISELECT_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-options`,\n    groupName: i18n.t(\"editor.inspect.setter_group.options\"),\n    children: [\n      {\n        id: `${baseWidgetName}-options-mode`,\n        attrName: \"optionConfigureMode\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: i18n.t(\"widget.public.select_options.manual\"),\n            value: \"static\",\n          },\n          {\n            label: i18n.t(\"widget.public.select_options.mapped\"),\n            value: \"dynamic\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-options`,\n        useCustomLayout: true,\n        attrName: \"manualOptions\",\n        setterType: \"OPTION_LIST_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => !value || value === \"static\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-options-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"value\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-option-data-sources`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_sources\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        expectedType: VALIDATION_TYPES.ARRAY,\n        shown: (value) => value === \"dynamic\",\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-option-mapped`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.map_data_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedOption\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => value === \"dynamic\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-mappedOption-labels`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"labels\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-values`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"values\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-disables`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disables\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"placeholder\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\", \"labelPosition\"],\n        shown: (hidden, position) => !hidden && position === \"left\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          MULTISELECT_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readOnly\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        attrName: \"showClear\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-leastNumber`,\n        labelName: i18n.t(\"editor.inspect.setter_label.choose_at_least\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_message.choose_at_least\"),\n        isSetterSingleRow: true,\n        attrName: \"atLeastNumber\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-upNumber`,\n        labelName: i18n.t(\"editor.inspect.setter_label.choose_up_to\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_message.choose_up_to\"),\n        isSetterSingleRow: true,\n        attrName: \"upToNumber\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-height`,\n        labelName: i18n.t(\"editor.inspect.setter_label.height\"),\n        attrName: \"dynamicHeight\",\n        setterType: \"HEIGHT_MODE_SELECT\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.fixed\"),\n            value: \"fixed\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_limited\"),\n            value: \"limited\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_height\"),\n            value: \"auto\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"false\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-colors-theme-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/MultiselectWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport MultiselectWidgetIcon from \"@/assets/widgetCover/multiselect.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const MULTISELECT_WIDGET_CONFIG: WidgetConfig = {\n  type: \"MULTISELECT_WIDGET\",\n  displayName: \"multiselect\",\n  widgetName: i18n.t(\"widget.multiselect.name\"),\n  icon: <MultiselectWidgetIcon />,\n  keywords: [\"Multiselect\", \"多项选择\"],\n  sessionType: \"SELECT\",\n  w: 7,\n  h: 5,\n  version: 0,\n  defaults: {\n    label: \"Label\",\n    optionConfigureMode: \"static\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    dataSources: \"{{[]}}\",\n    colorScheme: \"blue\",\n    hidden: false,\n    manualOptions: [\n      { id: `option-${v4()}`, label: \"Option 1\", value: \"Option 1\" },\n      { id: `option-${v4()}`, label: \"Option 2\", value: \"Option 2\" },\n      { id: `option-${v4()}`, label: \"Option 3\", value: \"Option 3\" },\n    ],\n    dynamicHeight: \"auto\",\n    formDataKey: \"multiselect\",\n    resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/NumberInputWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const INPUT_NUMBER_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.focus\",\n      ),\n      value: \"focus\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.blur\",\n      ),\n      value: \"blur\",\n    },\n  ],\n  methods: [\"focus\", \"setValue\", \"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/NumberInputWidget/index.ts",
    "content": "export { NUMBER_INPUT_PANEL_CONFIG } from \"./panelConfig\"\nexport { NUMBER_INPUT_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { INPUT_NUMBER_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/NumberInputWidget/interface.ts",
    "content": "import { InputNumberProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedNumberInputProps\n  extends Pick<\n    InputNumberProps,\n    | \"value\"\n    | \"placeholder\"\n    | \"max\"\n    | \"min\"\n    | \"precision\"\n    | \"disabled\"\n    | \"readOnly\"\n    | \"prefix\"\n    | \"suffix\"\n  > {\n  openThousandSeparator?: boolean\n  loading?: boolean\n  colorScheme?: InputNumberProps[\"colorScheme\"]\n  displayName: string\n  handleUpdateDsl: (value: any) => void\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange: (value?: number | undefined) => void\n  handleOnBlur?: () => void\n  handleOnFocus?: () => void\n}\n\nexport interface NumberInputWidgetProps\n  extends Omit<\n      WrappedNumberInputProps,\n      \"handleOnChange\" | \"handleOnFocus\" | \"handleOnBlur\"\n    >,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    ValidateMessageOldProps {\n  defaultValue?: number\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/NumberInputWidget/numberInput.tsx",
    "content": "import { debounce } from \"lodash-es\"\nimport { FC, forwardRef, useCallback, useEffect, useRef, useState } from \"react\"\nimport { InputNumber, LoadingIcon } from \"@illa-design/react\"\nimport {\n  NumberInputWidgetProps,\n  WrappedNumberInputProps,\n} from \"@/widgetLibrary/NumberInputWidget/interface\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { getValidateMessageFunc } from \"./utils\"\n\nconst parserThousand = (value: number | string) =>\n  `${value}`.replace(/\\d+/, function (s) {\n    return s.replace(/(\\d)(?=(\\d{3})+$)/g, \"$1,\")\n  })\n\nexport const WrappedInputNumber = forwardRef<\n  HTMLInputElement,\n  WrappedNumberInputProps\n>((props, ref) => {\n  const {\n    openThousandSeparator,\n    max,\n    min,\n    placeholder,\n    value,\n    precision,\n    disabled,\n    readOnly,\n    prefix,\n    suffix,\n    loading,\n    colorScheme,\n    handleOnChange,\n    handleOnBlur,\n    handleOnFocus,\n  } = props\n\n  return (\n    <InputNumber\n      inputRef={ref}\n      max={max}\n      min={min}\n      formatter={openThousandSeparator ? parserThousand : undefined}\n      placeholder={placeholder}\n      value={value}\n      precision={precision}\n      disabled={disabled}\n      readOnly={readOnly}\n      prefix={prefix}\n      suffix={loading ? <LoadingIcon spin /> : suffix}\n      mode=\"button\"\n      onChange={handleOnChange}\n      onBlur={handleOnBlur}\n      onFocus={handleOnFocus}\n      colorScheme={colorScheme}\n    />\n  )\n})\nWrappedInputNumber.displayName = \"WrappedInputNumber\"\nexport const NumberInputWidget: FC<NumberInputWidgetProps> = (props) => {\n  const {\n    displayName,\n    value,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    pattern,\n    regex,\n    customRule,\n    hideValidationMessage,\n    updateComponentHeight,\n    validateMessage,\n    defaultValue,\n    triggerEventHandler,\n    handleUpdateMultiExecutionResult,\n  } = props\n  const numberInputRef = useRef<HTMLInputElement>(null)\n  const [numberInputValue, setNumberInputValue] = useState(\n    value || defaultValue,\n  )\n\n  useEffect(() => {\n    if (\n      typeof defaultValue === \"undefined\" ||\n      typeof defaultValue === \"number\"\n    ) {\n      setNumberInputValue(defaultValue)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value: (defaultValue as unknown) === \"\" ? undefined : defaultValue,\n          },\n        },\n      ])\n    }\n  }, [defaultValue, displayName, handleUpdateMultiExecutionResult])\n\n  const debounceOnChange = useRef(\n    debounce(\n      (\n        value: number | undefined,\n        triggerEventHandler: NumberInputWidgetProps[\"triggerEventHandler\"],\n        options?: {\n          hideValidationMessage?: NumberInputWidgetProps[\"hideValidationMessage\"]\n          pattern?: NumberInputWidgetProps[\"pattern\"]\n          regex?: NumberInputWidgetProps[\"regex\"]\n          required?: NumberInputWidgetProps[\"required\"]\n          customRule?: NumberInputWidgetProps[\"customRule\"]\n        },\n      ) => {\n        new Promise((resolve) => {\n          const message = getValidateMessageFunc(value, options)\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                value: (value as unknown) === \"\" ? undefined : value,\n                validateMessage: message,\n              },\n            },\n          ])\n          resolve(true)\n        }).then(() => {\n          triggerEventHandler(\"change\")\n        })\n      },\n\n      180,\n    ),\n  )\n\n  const handleOnChange = useCallback(\n    (value?: number | undefined) => {\n      setNumberInputValue(value)\n      debounceOnChange.current(value, triggerEventHandler, {\n        hideValidationMessage,\n        pattern,\n        regex,\n        required,\n        customRule,\n      })\n    },\n    [\n      customRule,\n      hideValidationMessage,\n      pattern,\n      regex,\n      required,\n      triggerEventHandler,\n    ],\n  )\n\n  const handleValidate = useCallback(\n    (value?: unknown) => {\n      const message = getValidateMessageFunc(value, {\n        hideValidationMessage: hideValidationMessage,\n        pattern: pattern,\n        regex: regex,\n        required: required,\n        customRule: customRule,\n      })\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [\n      customRule,\n      handleUpdateDsl,\n      hideValidationMessage,\n      pattern,\n      regex,\n      required,\n    ],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      focus: () => {\n        numberInputRef.current?.focus()\n      },\n      setValue: (value: number) => {\n        if (typeof value === \"number\" || typeof value === \"undefined\") {\n          handleOnChange(value)\n        }\n      },\n      clearValue: () => {\n        handleOnChange(0)\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {\n        handleUpdateDsl({\n          validateMessage: \"\",\n        })\n      },\n    })\n\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleOnChange,\n    handleUpdateDsl,\n    handleValidate,\n    updateComponentRuntimeProps,\n    value,\n  ])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedInputNumber\n            {...props}\n            value={numberInputValue}\n            ref={numberInputRef}\n            handleOnChange={handleOnChange}\n            handleOnBlur={() => {\n              triggerEventHandler(\"blur\")\n            }}\n            handleOnFocus={() => {\n              triggerEventHandler(\"focus\")\n            }}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nNumberInputWidget.displayName = \"NumberInputWidget\"\nexport default NumberInputWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/NumberInputWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { INPUT_NUMBER_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/NumberInputWidget/eventHandlerConfig\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\n\nconst widgetBaseName = \"number-input\"\nexport const NUMBER_INPUT_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${widgetBaseName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${widgetBaseName}-basic-default-value`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.input_default_value\"),\n        attrName: \"defaultValue\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${widgetBaseName}-basic-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"placeholder\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${widgetBaseName}-basic-decimal-place`,\n        labelName: i18n.t(\"editor.inspect.setter_label.decimal_place\"),\n        attrName: \"precision\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${widgetBaseName}-basic-minimum`,\n        labelName: i18n.t(\"editor.inspect.setter_label.minimum\"),\n        attrName: \"min\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${widgetBaseName}-basic-maximum  `,\n        labelName: i18n.t(\"editor.inspect.setter_label.maximum\"),\n        attrName: \"max\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${widgetBaseName}-separator`,\n        labelName: i18n.t(\"editor.inspect.setter_label.thousand_separator\"),\n        attrName: \"openThousandSeparator\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${widgetBaseName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${widgetBaseName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${widgetBaseName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${widgetBaseName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${widgetBaseName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${widgetBaseName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${widgetBaseName}-label-width`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n      },\n    ],\n  },\n  {\n    id: `${widgetBaseName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          widgetBaseName,\n          INPUT_NUMBER_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${widgetBaseName}-interaction-loading`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n        attrName: \"loading\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${widgetBaseName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${widgetBaseName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readOnly\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${widgetBaseName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${widgetBaseName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${widgetBaseName}-adornments-prefix`,\n        labelName: i18n.t(\"editor.inspect.setter_label.prefix_text\"),\n        attrName: \"prefix\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${widgetBaseName}-adornments-suffix`,\n        labelName: i18n.t(\"editor.inspect.setter_label.suffix_text\"),\n        attrName: \"suffix\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${widgetBaseName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${widgetBaseName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${widgetBaseName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${widgetBaseName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${widgetBaseName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${widgetBaseName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${widgetBaseName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${widgetBaseName}-styles`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${widgetBaseName}-styles-styles`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${widgetBaseName}-styles-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/NumberInputWidget/utils.ts",
    "content": "import {\n  getValidateVFromString,\n  handleValidateCheck,\n} from \"../PublicSector/InvalidMessage/utils\"\nimport { NumberInputWidgetProps } from \"./interface\"\n\nexport const getValidateMessageFunc = (\n  value: unknown,\n  options: {\n    hideValidationMessage?: NumberInputWidgetProps[\"hideValidationMessage\"]\n    pattern?: NumberInputWidgetProps[\"pattern\"]\n    regex?: NumberInputWidgetProps[\"regex\"]\n    required?: NumberInputWidgetProps[\"required\"]\n    customRule?: NumberInputWidgetProps[\"customRule\"]\n  } = {},\n) => {\n  const {\n    hideValidationMessage,\n    pattern,\n    regex,\n\n    required,\n    customRule,\n  } = options\n  if (!hideValidationMessage) {\n    const message = handleValidateCheck({\n      value: getValidateVFromString(value),\n      pattern,\n      regex,\n      required,\n      customRule,\n    })\n    const showMessage = message && message.length > 0\n    return showMessage ? message : \"\"\n  }\n  return \"\"\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/NumberInputWidget/widgetConfig.tsx",
    "content": "import NumberInputWidgetIcon from \"@/assets/widgetCover/numberInput.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const NUMBER_INPUT_WIDGET_CONFIG: WidgetConfig = {\n  type: \"NUMBER_INPUT_WIDGET\",\n  widgetName: i18n.t(\"widget.number_input.name\"),\n  displayName: \"numberInput\",\n  icon: <NumberInputWidgetIcon />,\n  keywords: [\"Number Input\", \"数字输入框\"],\n  sessionType: \"INPUTS\",\n  w: 6,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    label: \"Label\",\n    defaultValue: \"\",\n    value: undefined,\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    colorScheme: \"blue\",\n    hidden: false,\n    formDataKey: \"numberInput\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PdfWidget/button.tsx",
    "content": "import { ButtonHTMLAttributes, ReactNode, forwardRef } from \"react\"\nimport { LoadingIcon } from \"@illa-design/react\"\nimport {\n  applyCursor,\n  applyShape,\n  buttonIconStyle,\n  buttonStyle,\n} from \"@/widgetLibrary/PdfWidget/style\"\n\nexport type ToolButtonShape = \"square\" | \"round\"\n\nexport interface ToolButtonProps\n  extends ButtonHTMLAttributes<HTMLButtonElement> {\n  loading?: boolean\n  icon?: ReactNode\n  shape?: ToolButtonShape\n}\n\nexport const ToolButton = forwardRef<HTMLButtonElement, ToolButtonProps>(\n  (props, ref) => {\n    const { loading, icon, shape = \"square\", ...rest } = props\n    return (\n      <button\n        css={[buttonStyle, applyCursor(loading), applyShape(shape)]}\n        ref={ref}\n        {...rest}\n      >\n        {(loading || icon) && (\n          <span css={buttonIconStyle}>\n            {loading ? <LoadingIcon spin={true} /> : icon}\n          </span>\n        )}\n      </button>\n    )\n  },\n)\n\nToolButton.displayName = \"ToolButton\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PdfWidget/eventHandlerConfig.ts",
    "content": "import { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const PDF_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [],\n  methods: [\"setFileUrl\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PdfWidget/index.tsx",
    "content": "export { PDF_PANEL_CONFIG } from \"./panelConfig\"\nexport { PDF_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { PDF_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PdfWidget/interface.tsx",
    "content": "import { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport {\n  BaseComponentNodeProps,\n  BaseWidgetProps,\n} from \"@/widgetLibrary/interface\"\n\n// todo: @echoxyc error extends.Refactor.\nexport interface WrappedPdfProps\n  extends Omit<BaseWidgetProps, \"w\" | \"h\" | \"unitH\" | \"unitW\"> {\n  width?: number\n  height?: number\n  scaleMode?: \"width\" | \"height\"\n  url?: string\n  showToolBar?: boolean\n}\n\nexport interface PdfWidgetProps\n  extends WrappedPdfProps,\n    TooltipWrapperProps,\n    BaseComponentNodeProps {}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PdfWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst baseWidgetName = \"pdf\"\nexport const PDF_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-source-self-host`,\n        attrName: \"url\",\n        expectedType: VALIDATION_TYPES.STRING,\n        labelName: i18n.t(\"editor.inspect.setter_label.file_url\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.file_url\"),\n        isSetterSingleRow: true,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-show-tool-bar`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_tool_bar\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"showToolBar\",\n        placeholder: \"{{false}}\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-scaleMode`,\n        labelName: i18n.t(\"editor.inspect.setter_label.scale\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.scale\"),\n        setterType: \"RADIO_GROUP_SETTER\",\n        attrName: \"scaleMode\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.scale_width\"),\n            value: \"width\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.scale_height\"),\n            value: \"height\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PdfWidget/pdf.tsx",
    "content": "import { debounce } from \"lodash-es\"\nimport pdfWorker from \"pdfjs-dist/build/pdf.worker.js?url\"\nimport {\n  FC,\n  forwardRef,\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Document, Page, pdfjs } from \"react-pdf\"\nimport \"react-pdf/dist/esm/Page/AnnotationLayer.css\"\nimport \"react-pdf/dist/esm/Page/TextLayer.css\"\nimport {\n  DownloadIcon,\n  Loading,\n  NextIcon,\n  PreviousIcon,\n} from \"@illa-design/react\"\nimport { ToolButton } from \"@/widgetLibrary/PdfWidget/button\"\nimport {\n  applyHiddenStyle,\n  documentInitStyle,\n  fullPageStyle,\n  pageStyle,\n  pdfContainerStyle,\n  pdfStyle,\n  pdfWrapperStyle,\n  toolBarStyle,\n} from \"@/widgetLibrary/PdfWidget/style\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { PdfWidgetProps, WrappedPdfProps } from \"./interface\"\n\npdfjs.GlobalWorkerOptions.workerSrc = pdfWorker\n\nexport const Pdf = forwardRef<HTMLDivElement, WrappedPdfProps>((props, ref) => {\n  const { displayName, width, height, scaleMode, url, showToolBar } = props\n  const { t } = useTranslation()\n  const pageRef = useRef<HTMLDivElement[]>([])\n  const documentRef = useRef<HTMLDivElement>(null)\n  const [numPages, setNumPages] = useState<number>(0)\n  const [pageNumber, setPageNumber] = useState<number>(1)\n  const [loading, setLoading] = useState<boolean>(true)\n  const [error, setError] = useState<boolean>(false)\n  const [hasButtonClicked, setButtonClick] = useState(false)\n  const hasScrollRef = useRef(false)\n  const timeoutRef = useRef<number | null>(null)\n\n  const { scaleWidth, scaleHeight } = useMemo(() => {\n    if (scaleMode === \"width\") {\n      return { scaleWidth: width }\n    }\n    return { scaleHeight: height }\n  }, [width, height, scaleMode])\n\n  const updatePage = useCallback(\n    (offset: number) => {\n      const { offsetTop } = pageRef.current[pageNumber + offset - 1]\n      if (documentRef.current) {\n        documentRef.current.scrollTop = offsetTop - 40\n        setButtonClick(true)\n      }\n      setPageNumber((prevPageNumber) => (prevPageNumber || 1) + offset)\n    },\n    [pageNumber],\n  )\n\n  const updateCurrentPage = debounce(() => {\n    if (hasScrollRef.current) {\n      hasScrollRef.current = false\n      // get current page\n      const { scrollTop } = documentRef.current || {}\n      if (!scrollTop) return\n      const currentPage = pageRef.current.findIndex(\n        (elem) => elem.offsetTop - 40 >= scrollTop,\n      )\n      setPageNumber(currentPage === -1 ? numPages : currentPage)\n    }\n  }, 150)\n\n  const downloadFile = useCallback(async () => {\n    if (!url) return\n    const pdf = await fetch(url)\n    const pdfBlob = await pdf.blob()\n    const pdfURL = URL.createObjectURL(pdfBlob)\n    const anchor = document.createElement(\"a\")\n    anchor.href = pdfURL\n    anchor.download = displayName\n    document.body.appendChild(anchor)\n    anchor.click()\n    document.body.removeChild(anchor)\n    URL.revokeObjectURL(pdfURL)\n  }, [url, displayName])\n\n  const handleScroll = () => {\n    if (hasButtonClicked) return setButtonClick(false)\n    if (!hasScrollRef.current) {\n      hasScrollRef.current = true\n      updateCurrentPage()\n    }\n  }\n\n  useEffect(() => {\n    return () => {\n      if (timeoutRef.current) {\n        clearTimeout(timeoutRef.current)\n        timeoutRef.current = null\n      }\n    }\n  }, [])\n\n  if (!url) {\n    return <div css={fullPageStyle}>{t(\"widget.pdf.empty\")}</div>\n  }\n\n  return (\n    <div css={pdfContainerStyle} ref={ref}>\n      {loading ? (\n        <div css={fullPageStyle}>\n          <Loading />\n        </div>\n      ) : null}\n      {showToolBar && !error && !loading ? (\n        <div css={[toolBarStyle, applyHiddenStyle(loading)]}>\n          <ToolButton\n            disabled={pageNumber <= 1}\n            onClick={() => updatePage(-1)}\n            type=\"button\"\n            shape=\"round\"\n            aria-label=\"Previous page\"\n            icon={<PreviousIcon />}\n          />\n          <ToolButton\n            disabled={pageNumber >= numPages}\n            onClick={() => updatePage(1)}\n            type=\"button\"\n            shape=\"round\"\n            aria-label=\"Next page\"\n            icon={<NextIcon />}\n          />\n          <ToolButton\n            type=\"button\"\n            shape=\"round\"\n            onClick={downloadFile}\n            icon={<DownloadIcon />}\n          />\n        </div>\n      ) : null}\n      <div\n        css={[pdfStyle, applyHiddenStyle(loading)]}\n        ref={documentRef}\n        onScroll={handleScroll}\n      >\n        <Document\n          css={documentInitStyle}\n          loading={\n            <div css={fullPageStyle}>\n              <Loading />\n            </div>\n          }\n          error={<div css={fullPageStyle}>{t(\"widget.pdf.failed\")}</div>}\n          file={url}\n          onLoadSuccess={({ numPages: nextNumPages }) => {\n            setNumPages(nextNumPages)\n            // [TODO] wait react-pdf fix\n            clearTimeout(timeoutRef.current as number)\n            timeoutRef.current = window.setTimeout(() => {\n              setLoading(false)\n              setError(false)\n            }, 200)\n          }}\n          onLoadError={() => {\n            setLoading(false)\n            setError(true)\n          }}\n        >\n          {Array.from(new Array(numPages), (el, index) => (\n            <Page\n              css={pageStyle}\n              loading={\"\"}\n              width={scaleWidth}\n              height={scaleHeight}\n              key={`page_${index + 1}`}\n              pageNumber={index + 1}\n              inputRef={(el) => {\n                if (!el) return\n                pageRef.current[index] = el\n              }}\n            />\n          ))}\n        </Document>\n      </div>\n    </div>\n  )\n})\n\nPdf.displayName = \"Pdf\"\n\nexport const PdfWidget: FC<PdfWidgetProps> = (props) => {\n  const {\n    displayName,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    handleUpdateOriginalDSLMultiAttr,\n    tooltipText,\n    width,\n    height,\n    scaleMode,\n    url,\n    showToolBar,\n    w,\n    h,\n  } = props\n\n  const wrapperRef = useRef<HTMLDivElement>(null)\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setFileUrl: (url: string) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { url },\n          },\n        ])\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  ])\n\n  useEffect(() => {\n    const offsetWidth = wrapperRef.current?.offsetWidth\n    const offsetHeight = wrapperRef.current?.offsetHeight\n    if (\n      offsetWidth &&\n      offsetHeight &&\n      (offsetWidth !== width || offsetHeight !== height)\n    ) {\n      handleUpdateOriginalDSLMultiAttr?.(\n        {\n          width: wrapperRef.current.offsetWidth,\n          height: wrapperRef.current.offsetHeight,\n        },\n        true,\n      )\n    }\n  }, [w, h, handleUpdateOriginalDSLMultiAttr, width, height])\n\n  return (\n    <div css={pdfWrapperStyle} ref={wrapperRef}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <Pdf\n          {...props}\n          updateComponentRuntimeProps={updateComponentRuntimeProps}\n          deleteComponentRuntimeProps={deleteComponentRuntimeProps}\n          displayName={displayName}\n          width={width}\n          height={height}\n          scaleMode={scaleMode}\n          url={url}\n          showToolBar={showToolBar}\n        />\n      </TooltipWrapper>\n    </div>\n  )\n}\n\nPdfWidget.displayName = \"PdfWidget\"\nexport default PdfWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PdfWidget/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\nimport { ToolButtonShape } from \"@/widgetLibrary/PdfWidget/button\"\n\nexport const pdfWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n`\n\nexport const pdfContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  position: relative;\n  width: 100%;\n  height: 100%;\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n`\nexport const fullPageStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n`\n\nexport const pdfStyle = css`\n  width: 100%;\n  height: 100%;\n  overflow: auto;\n  scroll-snap-type: y mandatory;\n  display: flex;\n  flex-grow: 1;\n  flex-shrink: 0;\n  flex-basis: 0;\n  background-color: ${getColor(\"grayBlue\", \"09\")};\n`\n\nexport const documentInitStyle = css`\n  margin: 0 auto;\n\n  .react-pdf__message {\n    height: 100%;\n  }\n`\n\nexport const toolBarStyle = css`\n  background: ${getColor(\"grayBlue\", \"02\")};\n  text-align: end;\n  height: 40px;\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n  padding: 0 8px;\n  flex: 0 0 auto;\n`\n\nexport const pageStyle = css`\n  &:not(:last-of-type) {\n    margin-bottom: 8px;\n  }\n`\n\nexport const applyHiddenStyle = (hidden: boolean): SerializedStyles => {\n  return css`\n    visibility: ${hidden ? \"hidden\" : \"visible\"};\n  `\n}\n\n// button\n\nexport const buttonStyle = css`\n  color: ${getColor(\"white\", \"01\")};\n  transition:\n    color 200ms ease-in-out,\n    background-color 200ms ease-in-out;\n  vertical-align: middle;\n  white-space: nowrap;\n  outline: none;\n  border: 0;\n  background-color: transparent;\n  display: inline-flex;\n  flex-direction: row;\n  align-items: center;\n  justify-content: center;\n  padding: 10px;\n`\n\nexport const buttonIconStyle = css`\n  display: inline-flex;\n  flex-direction: row;\n  align-items: center;\n  font-size: 12px;\n`\n\nexport function applyCursor(loading?: boolean): SerializedStyles {\n  if (loading) {\n    return css`\n      cursor: default;\n\n      &:disabled {\n        cursor: not-allowed;\n        background-color: transparent;\n      }\n    `\n  } else {\n    return css`\n      cursor: pointer;\n\n      &:disabled {\n        cursor: not-allowed;\n      }\n    `\n  }\n}\n\nexport function applyShape(shape: ToolButtonShape): SerializedStyles {\n  if (shape === \"round\") {\n    return css`\n      border-radius: 50%;\n    `\n  } else {\n    return css`\n      border-radius: 8px;\n    `\n  }\n}\n\nexport function applyIframeContainer(isDragging: boolean): SerializedStyles {\n  return css`\n    pointer-events: ${isDragging ? \"none\" : \"auto\"};\n    border: none;\n    height: 100%;\n    width: 100%;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PdfWidget/widgetConfig.tsx",
    "content": "import PdfWidgetIcon from \"@/assets/widgetCover/pdf.svg?react\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const PDF_WIDGET_CONFIG: WidgetConfig = {\n  type: \"PDF_WIDGET\",\n  displayName: \"pdf\",\n  widgetName: \"PDF\",\n  icon: <PdfWidgetIcon />,\n  keywords: [\"PDF\", \"pdf\"],\n  sessionType: \"PRESENTATION\",\n  w: 10,\n  h: 45,\n  version: 0,\n  defaults: {\n    url: \"https://upload.wikimedia.org/wikipedia/commons/e/ee/Guideline_No._GD-Ed-2214_Marman_Clamp_Systems_Design_Guidelines.pdf\",\n    hidden: false,\n    showToolBar: true,\n    scaleMode: \"width\",\n    width: undefined,\n    height: undefined,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/AutoHeightContainer/index.tsx",
    "content": "import { FC, ReactNode, useEffect, useRef } from \"react\"\nimport {\n  autoHeightContainerStyle,\n  fixedHeightContainerStyle,\n} from \"@/widgetLibrary/PublicSector/AutoHeightContainer/style\"\n\ninterface AutoHeightContainerProps {\n  updateComponentHeight: (height: number) => void\n  enable?: boolean\n  children: ReactNode\n}\n\nexport const AutoHeightContainer: FC<AutoHeightContainerProps> = ({\n  updateComponentHeight,\n  children,\n  enable = true,\n}) => {\n  const containerRef = useRef<HTMLDivElement | null>(null)\n\n  useEffect(() => {\n    const containerDom = containerRef.current\n    const observerRef = new ResizeObserver((entries) => {\n      if (!updateComponentHeight) return\n      const height = entries[0].contentRect.height\n      updateComponentHeight?.(height)\n    })\n    if (observerRef && containerDom && enable) {\n      observerRef.observe(containerDom)\n    }\n\n    return () => {\n      if (containerDom && enable) {\n        observerRef.unobserve(containerDom)\n      }\n    }\n  }, [enable, updateComponentHeight])\n\n  return (\n    <div\n      ref={containerRef}\n      css={enable ? autoHeightContainerStyle : fixedHeightContainerStyle}\n    >\n      {children}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/AutoHeightContainer/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const autoHeightContainerStyle = css`\n  flex: 1;\n`\n\nexport const fixedHeightContainerStyle = css`\n  height: 100%;\n  width: 100%;\n  flex: 1;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/InvalidMessage/index.tsx",
    "content": "import { FC } from \"react\"\nimport { WarningCircleIcon } from \"@illa-design/react\"\nimport { ValidateMessageNewProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport { invalidateMessageCss } from \"./style\"\n\nexport const InvalidMessage: FC<ValidateMessageNewProps> = (props) => {\n  const { validateMessage } = props\n\n  return (\n    <>\n      {typeof validateMessage === \"string\" && validateMessage.length > 0 && (\n        <span css={invalidateMessageCss}>\n          <WarningCircleIcon />\n          {validateMessage}\n        </span>\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/InvalidMessage/interface.tsx",
    "content": "export interface ValidateMessageNewProps {\n  validateMessage: string\n}\n\nexport interface ValidateMessageOldProps {\n  pattern?: \"Email\" | \"URL\" | \"Regex\"\n  regex?: string\n  minLength?: number\n  maxLength?: number\n  required?: boolean\n  customRule?: string\n  hideValidationMessage?: boolean\n}\n\nexport interface ValidateCheckProps {\n  value?: unknown\n  pattern?: \"Email\" | \"URL\" | \"Regex\"\n  regex?: string\n  minLength?: number\n  maxLength?: number\n  required?: boolean\n  customRule?: string\n  maxFiles?: number\n  minFiles?: number\n  maxSize?: number\n  minSize?: number\n  sizeType?: string\n  atLeastNumber?: number\n  upToNumber?: number\n  minDuration?: number\n  maxDuration?: number\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/InvalidMessage/style.tsx",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const invalidateMessageCss = css`\n  display: flex;\n  padding: 8px 0;\n  width: 100%;\n  align-items: center;\n  color: ${globalColor(`--${illaPrefix}-orange-03`)};\n  font-size: 14px;\n\n  svg {\n    margin-right: 8px;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/InvalidMessage/utils.tsx",
    "content": "import { isString } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { ValidateCheckProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\n\nconst validateEmail = (email: string) => {\n  const str =\n    /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/\n  const emailMatchPattern = new RegExp(str)\n  return emailMatchPattern.test(email)\n}\n\nfunction isValidURL(str: string) {\n  const matchStr = /^(?:\\w+:)?\\/\\/([^\\s\\.]+\\.\\S{2}|localhost[\\:?\\d]*)\\S*$/\n  const urlMatchPattern = new RegExp(matchStr)\n  return urlMatchPattern.test(str)\n}\n\nexport const handleCheckCustomRule = (customRule: unknown) => {\n  if (customRule != undefined && customRule !== \"\") {\n    return true\n  }\n}\n\nexport const handleCheckMinSelectedItems = (\n  value: unknown,\n  minCount?: number,\n) => {\n  if (\n    typeof minCount === \"number\" &&\n    ((Array.isArray(value) && value.length < minCount) ||\n      typeof value === \"undefined\")\n  ) {\n    return true\n  }\n}\n\nexport const handleCheckMaxSelectedItems = (\n  value: unknown,\n  maxCount?: number,\n) => {\n  if (\n    typeof maxCount === \"number\" &&\n    ((Array.isArray(value) && value.length > maxCount) ||\n      typeof value === \"undefined\")\n  ) {\n    return true\n  }\n}\n\nexport const handleCheckIsRequired = (value: unknown, required?: boolean) => {\n  if (\n    required &&\n    (typeof value === \"undefined\" ||\n      (Array.isArray(value) && value.length === 0))\n  )\n    return true\n}\n\nexport const handleCheckMaxLength = (value: unknown, maxLength?: number) => {\n  if (\n    typeof maxLength === \"number\" &&\n    ((typeof value === \"string\" && value.length > maxLength) ||\n      typeof value === \"undefined\")\n  )\n    return true\n}\n\nexport const handleCheckMinLength = (value: unknown, minLength?: number) => {\n  if (\n    typeof minLength === \"number\" &&\n    ((typeof value === \"string\" && value.length < minLength) ||\n      typeof value === \"undefined\")\n  )\n    return true\n}\n\nexport const handleCheckMinDuration = (\n  value: unknown,\n  minDuration?: number,\n) => {\n  if (\n    typeof minDuration === \"number\" &&\n    ((typeof value === \"number\" && value < minDuration) ||\n      typeof value === \"undefined\")\n  )\n    return true\n}\n\nexport const handleCheckMaxDuration = (\n  value: unknown,\n  maxDuration?: number,\n) => {\n  if (\n    typeof maxDuration === \"number\" &&\n    ((typeof value === \"number\" && value > maxDuration) ||\n      typeof value === \"undefined\")\n  )\n    return true\n}\n\nexport const handleCheckPattern = (\n  value: unknown,\n  pattern: ValidateCheckProps[\"pattern\"],\n  reg?: string,\n) => {\n  switch (pattern) {\n    case \"Email\": {\n      if (\n        (typeof value === \"string\" && !validateEmail(value)) ||\n        typeof value === \"undefined\"\n      ) {\n        return i18n.t(\"editor.validate_message.email\")\n      }\n      break\n    }\n    case \"URL\": {\n      if (\n        (typeof value === \"string\" && !isValidURL(value)) ||\n        typeof value === \"undefined\"\n      ) {\n        return i18n.t(\"editor.validate_message.url\")\n      }\n      break\n    }\n    case \"Regex\":\n      if (!reg || typeof value === undefined) return\n      try {\n        let finalReg = reg\n        if (reg.startsWith(\"/\") && reg.endsWith(\"/\")) {\n          finalReg = reg.slice(1, reg.length - 1)\n        }\n        const matchPattern = new RegExp(finalReg)\n        if (typeof value !== \"string\" || !matchPattern.test(value)) {\n          return i18n.t(\"editor.validate_message.regex\")\n        }\n      } catch (e) {\n        console.error(\"regex error\", e)\n      }\n  }\n}\n\nexport const calculateFileSize = (data: unknown) => {\n  const blobArr = Array.isArray(data) ? data : [data]\n  const byteSize = new Blob(blobArr).size\n  return byteSize\n}\n\nconst handleCheckFileSize = (\n  value: unknown,\n  maxSize?: number,\n  minSize?: number,\n  sizeType?: string,\n) => {\n  if (value && (value as []).length) {\n    // default to MB\n    const getFileSizeNumber = (type?: string) =>\n      type !== \"mb\" ? 1024 : 1024 * 1024\n\n    const maxSizeNumber = maxSize ? maxSize * getFileSizeNumber(sizeType) : 0\n    const minSizeNumber = minSize ? minSize * getFileSizeNumber(sizeType) : 0\n\n    for (let i = 0; i < (value as []).length; i++) {\n      const size =\n        (value as any)[i].originFile?.size ||\n        calculateFileSize((value as any)[i].originFile)\n\n      if (!!maxSizeNumber && size > maxSizeNumber) {\n        return {\n          hasError: true,\n          errorMessage: i18n.t(\"editor.validate_message.max_size\", {\n            maxSize,\n            type: (sizeType || \"MB\").toUpperCase(),\n          }),\n        }\n      }\n      if (!!minSizeNumber && size < minSizeNumber) {\n        return {\n          hasError: true,\n          errorMessage: i18n.t(\"editor.validate_message.min_size\", {\n            minSize,\n            type: (sizeType || \"MB\").toUpperCase(),\n          }),\n        }\n      }\n    }\n  }\n  return {\n    hasError: false,\n    errorMessage: \"\",\n  }\n}\n\nconst handleCheckFilesCount = (\n  value: unknown,\n  maxFiles?: number,\n  minFiles?: number,\n) => {\n  if (value) {\n    const length = (value as []).length\n    if (maxFiles && length > maxFiles) {\n      return {\n        fileCountInvalid: true,\n        countErrorMessage: i18n.t(\"editor.validate_message.max_files\", {\n          maxFiles,\n        }),\n      }\n    }\n    if (minFiles && length < minFiles) {\n      return {\n        fileCountInvalid: true,\n        countErrorMessage: i18n.t(\"editor.validate_message.min_files\", {\n          minFiles,\n        }),\n      }\n    }\n  }\n  return {\n    fileCountInvalid: false,\n    countErrorMessage: \"\",\n  }\n}\n\nexport const handleValidateCheck = (\n  options?: ValidateCheckProps,\n): string | undefined => {\n  if (typeof options === \"undefined\") return\n  if (handleCheckCustomRule(options.customRule)) {\n    try {\n      return typeof options.customRule === \"string\"\n        ? options.customRule\n        : JSON.stringify(options.customRule)\n    } catch (e) {\n      console.error(\"custom rule is error\")\n    }\n  }\n\n  const { hasError, errorMessage } = handleCheckFileSize(\n    options.value,\n    options.maxSize,\n    options.minSize,\n    options.sizeType,\n  )\n  if (hasError) {\n    return errorMessage\n  }\n\n  const { fileCountInvalid, countErrorMessage } = handleCheckFilesCount(\n    options.value,\n    options.maxFiles,\n    options.minFiles,\n  )\n  if (fileCountInvalid) {\n    return countErrorMessage\n  }\n\n  if (handleCheckMinSelectedItems(options.value, options.atLeastNumber)) {\n    return i18n.t(\"editor.inspect.setter_message.choose_at_least\", {\n      min: options.atLeastNumber,\n    })\n  }\n\n  if (handleCheckMaxSelectedItems(options.value, options.upToNumber)) {\n    return i18n.t(\"editor.inspect.setter_message.choose_up_to\", {\n      max: options.upToNumber,\n    })\n  }\n\n  if (handleCheckIsRequired(options.value, options.required)) {\n    return i18n.t(\"editor.validate_message.required\")\n  }\n\n  if (handleCheckMaxLength(options.value, options.maxLength)) {\n    return i18n.t(\"editor.validate_message.max_length\", {\n      number: options.maxLength,\n    })\n  }\n\n  if (handleCheckMinLength(options.value, options.minLength)) {\n    return i18n.t(\"editor.validate_message.min_value\", {\n      number: options.minLength,\n    })\n  }\n\n  if (handleCheckMaxDuration(options.value, options.maxDuration)) {\n    return i18n.t(\"editor.inspect.setter_message.recording.max_duration\", {\n      maximum: options.maxDuration,\n    })\n  }\n\n  if (handleCheckMinDuration(options.value, options.minDuration)) {\n    return i18n.t(\"editor.inspect.setter_message.recording.min_duration\", {\n      minimum: options.minDuration,\n    })\n  }\n\n  return handleCheckPattern(options.value, options.pattern, options.regex)\n}\n\nexport const getValidateVFromString = (value: unknown) => {\n  return isString(value) && !value ? undefined : value\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/Label/index.tsx",
    "content": "import { forwardRef, useMemo } from \"react\"\nimport LabelProps from \"./interface\"\nimport {\n  applyLabelNameStyle,\n  applyLabelStyle,\n  labelCaptionCss,\n  labelRequiredCss,\n  labelTitleStyle,\n} from \"./styles\"\n\nexport const Label = forwardRef<HTMLLabelElement, LabelProps>((props, ref) => {\n  const {\n    label,\n    labelAlign = \"left\",\n    labelCaption,\n    labelPosition = \"left\",\n    labelHidden,\n    labelWidth = 0,\n    labelWidthUnit = \"%\",\n    labelFull = false,\n    required,\n    hasTooltip = false,\n  } = props\n\n  const renderLabelTitleRequired = useMemo(() => {\n    return required ? <span css={labelRequiredCss}>*</span> : null\n  }, [required])\n\n  const renderLabelTitle = useMemo(() => {\n    return (\n      <span css={labelTitleStyle}>\n        <span css={applyLabelNameStyle(hasTooltip)}>{label}</span>\n        {renderLabelTitleRequired}\n      </span>\n    )\n  }, [label, renderLabelTitleRequired, hasTooltip])\n\n  const renderLabelCaption = useMemo(() => {\n    return labelCaption ? <div css={labelCaptionCss}>{labelCaption}</div> : null\n  }, [labelCaption])\n\n  const realLabelWidth = !labelWidth ? undefined : labelWidth + labelWidthUnit\n\n  return !labelHidden && label ? (\n    <label\n      css={applyLabelStyle(\n        labelPosition,\n        labelAlign,\n        realLabelWidth,\n        labelFull,\n      )}\n      ref={ref}\n    >\n      {renderLabelTitle}\n      {renderLabelCaption}\n    </label>\n  ) : null\n})\n\nLabel.displayName = \"SetterLabel\"\n\nexport default Label\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/Label/interface.ts",
    "content": "import { HTMLAttributes } from \"react\"\n\nexport type LabelPositionType = \"left\" | \"top\" | \"right\"\nexport type LabelAlignType = \"left\" | \"right\"\n\nexport default interface LabelProps\n  extends Omit<HTMLAttributes<HTMLLabelElement>, \"prefix\" | \"placeholder\"> {\n  label?: string\n  required?: boolean\n  hideLabel?: boolean\n  labelAlign?: LabelAlignType\n  labelCaption?: string\n  labelHidden?: boolean\n  labelPosition?: LabelPositionType\n  labelWidth?: number\n  labelFull?: boolean\n  labelWidthUnit?: \"px\" | \"%\"\n  hasTooltip?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/Label/styles.tsx",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\nimport { LabelAlignType, LabelPositionType } from \"./interface\"\n\nconst baseLabelCss = css`\n  display: block;\n  font-size: 12px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  line-height: 16px;\n`\n\nfunction applyLeftLabelStyle(\n  position: \"left\" | \"right\",\n  alignment: LabelAlignType,\n  w?: string,\n  full?: boolean,\n): SerializedStyles {\n  const isOnLeft = position === \"left\"\n  const hasWidth = !!w\n  const marginCss = isOnLeft\n    ? css`\n        margin-right: 8px;\n      `\n    : css`\n        margin-left: 8px;\n      `\n  return css`\n    ${baseLabelCss};\n    overflow: hidden;\n    align-self: center;\n    width: ${hasWidth ? w : 0};\n    min-width: ${hasWidth ? w : 0};\n    flex-grow: ${full ? 1 : 0};\n    flex-shrink: 0;\n    text-align: ${alignment};\n    ${hasWidth && marginCss}\n  `\n}\n\nfunction applyTopLabelStyle(alignment: \"left\" | \"right\"): SerializedStyles {\n  return css`\n    ${baseLabelCss};\n    margin-bottom: 8px;\n    overflow: hidden;\n    width: 100%;\n    text-align: ${alignment};\n  `\n}\n\nexport function applyLabelStyle(\n  position: LabelPositionType,\n  alignment: LabelAlignType,\n  width?: string,\n  full?: boolean,\n): SerializedStyles {\n  if (position === \"top\") {\n    return applyTopLabelStyle(alignment)\n  } else {\n    return applyLeftLabelStyle(position, alignment, width, full)\n  }\n}\n\nexport const labelTooltipStyle = css`\n  &:after {\n    background-image: repeating-linear-gradient(\n      90deg,\n      ${globalColor(`--${illaPrefix}-grayBlue-06`)} 0,\n      ${globalColor(`--${illaPrefix}-grayBlue-06`)} 1px,\n      transparent 0,\n      transparent 3px,\n      ${globalColor(`--${illaPrefix}-grayBlue-06`)} 0,\n      ${globalColor(`--${illaPrefix}-grayBlue-06`)} 4px\n    );\n    background-position: 50%;\n    background-size: 4px 1px;\n    content: \"\";\n    height: 1px;\n    left: 0;\n    position: absolute;\n    top: 100%;\n    width: 100%;\n  }\n`\n\nexport const labelTitleStyle = css`\n  white-space: nowrap;\n`\n\nexport const applyLabelNameStyle = (hasTooltip: boolean) => {\n  return css`\n    position: relative;\n    ${hasTooltip && labelTooltipStyle}\n  `\n}\n\nexport const labelCaptionCss = css`\n  overflow: hidden;\n  color: ${globalColor(`--${illaPrefix}-gray-04`)};\n  text-overflow: ellipsis;\n`\n\nexport const labelRequiredCss = css`\n  color: ${globalColor(`--${illaPrefix}-red-03`)};\n  margin-left: 2px;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/RenderChildrenCanvas/index.tsx",
    "content": "import { ComponentMapNode } from \"@illa-public/public-types\"\nimport { FC, memo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport RenderComponentCanvasContainer from \"@/page/App/components/DotPanel/components/Canvas/renderComponentCanvasContainer\"\nimport {\n  SAFE_ROWS,\n  UNIT_HEIGHT,\n} from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { LIKE_CONTAINER_WIDGET_PADDING } from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { getIsILLAEditMode, isShowDot } from \"@/redux/config/configSelector\"\nimport { getComponentMap } from \"@/redux/currentApp/components/componentsSelector\"\nimport { RootState } from \"@/store\"\nimport { ContainerEmptyState } from \"@/widgetLibrary/ContainerWidget/emptyState\"\nimport { IRenderChildrenCanvasProps } from \"./interface\"\n\nconst RenderChildrenCanvas: FC<IRenderChildrenCanvasProps> = (props) => {\n  const {\n    columnNumber,\n    canResizeCanvas = false,\n    handleUpdateHeight,\n    containerPadding,\n    displayName,\n  } = props\n  const isEditMode = useSelector(getIsILLAEditMode)\n  const canShowDots = useSelector(isShowDot)\n  const targetNode = useSelector<RootState, ComponentMapNode>((state) => {\n    const components = getComponentMap(state)\n    return components[displayName]\n  })\n\n  const hasChildrenNode = targetNode?.childrenNode?.length > 0\n\n  if (isEditMode && ((!canShowDots && !hasChildrenNode) || !displayName)) {\n    return (\n      <ContainerEmptyState\n        handleUpdateHeight={handleUpdateHeight}\n        containerPadding={containerPadding}\n      />\n    )\n  }\n\n  return (\n    <RenderComponentCanvasContainer\n      displayName={displayName}\n      containerPadding={containerPadding ?? `${LIKE_CONTAINER_WIDGET_PADDING}`}\n      columnNumber={columnNumber}\n      handleUpdateHeight={handleUpdateHeight}\n      canResizeCanvas={canResizeCanvas}\n      safeRowNumber={canResizeCanvas ? 0 : SAFE_ROWS}\n      minHeight={canResizeCanvas ? 13 * UNIT_HEIGHT : undefined}\n    />\n  )\n}\n\nexport default memo(RenderChildrenCanvas)\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/RenderChildrenCanvas/interface.ts",
    "content": "export interface IRenderChildrenCanvasProps {\n  columnNumber: number\n  handleUpdateHeight: (height: number) => void\n  canResizeCanvas?: boolean\n  containerPadding?: string\n  displayName: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/TooltipWrapper/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { Trigger } from \"@illa-design/react\"\nimport { ILLAMarkdown } from \"@/components/ILLAMarkdown\"\nimport { TooltipWrapperProps } from \"./interface\"\n\nexport const TooltipWrapper: FC<TooltipWrapperProps> = memo(\n  (props: TooltipWrapperProps) => {\n    const { children, tooltipText, tooltipDisabled } = props\n\n    return (\n      <Trigger\n        content={<ILLAMarkdown textString={tooltipText} />}\n        colorScheme=\"grayBlue\"\n        disabled={tooltipDisabled}\n        position=\"top\"\n        autoFitPosition={false}\n        trigger=\"hover\"\n      >\n        {children}\n      </Trigger>\n    )\n  },\n)\n\nTooltipWrapper.displayName = \"TooltipWrapper\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/TooltipWrapper/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface TooltipWrapperProps {\n  children?: ReactNode\n  tooltipText?: string\n  tooltipDisabled?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/TransformWidgetWrapper/config.tsx",
    "content": "export const MIN_HEIGHT = 3\nexport const MIN_WIDTH = 2\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/TransformWidgetWrapper/index.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { klona } from \"klona\"\nimport { get, isFunction, isNumber, set, toPath } from \"lodash-es\"\nimport { FC, Suspense, memo, useCallback, useMemo } from \"react\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Skeleton } from \"@illa-design/react\"\nimport ErrorBoundary from \"@/components/ErrorBoundary\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport {\n  WIDGET_PADDING,\n  WIDGET_SCALE_SQUARE_BORDER_WIDTH,\n} from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { LayoutInfo } from \"@/redux/currentApp/components/componentsPayload\"\nimport {\n  getContainerListDisplayNameMappedChildrenNodeDisplayName,\n  searchDSLByDisplayName,\n} from \"@/redux/currentApp/components/componentsSelector\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport {\n  getExecutionResult,\n  getIsDragging,\n} from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { RootState } from \"@/store\"\nimport store from \"@/store\"\nimport { evaluateDynamicString } from \"@/utils/evaluateDynamicString\"\nimport { runEventHandler } from \"@/utils/eventHandlerHelper\"\nimport { ILLAEditorRuntimePropsCollectorInstance } from \"@/utils/executionTreeHelper/runtimePropsCollector\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport { TransformWidgetProps } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/interface\"\nimport { applyWrapperStylesStyle } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\nimport { getClientWidgetLayoutInfo } from \"../../../redux/currentApp/layoutInfo/layoutInfoSelector\"\nimport { layoutInfoActions } from \"../../../redux/currentApp/layoutInfo/layoutInfoSlice\"\nimport { MIN_HEIGHT } from \"./config\"\n\nexport const TransformWidgetWrapper: FC<TransformWidgetProps> = memo(\n  (props: TransformWidgetProps) => {\n    const { columnNumber, displayName, widgetType, parentNodeDisplayName } =\n      props\n\n    const displayNameMapProps = useSelector(getExecutionResult)\n    const layoutInfo = useSelector<RootState, LayoutInfo>((rootState) => {\n      const layoutInfos = getClientWidgetLayoutInfo(rootState)\n      return layoutInfos[displayName].layoutInfo\n    })\n    const originComponentNode = searchDSLByDisplayName(displayName)\n\n    const realProps = useMemo(\n      () => displayNameMapProps[displayName] ?? {},\n      [displayName, displayNameMapProps],\n    )\n\n    const dispatch = useDispatch()\n\n    const containerListMapChildName = useSelector(\n      getContainerListDisplayNameMappedChildrenNodeDisplayName,\n    )\n\n    const isDraggingInGlobal = useSelector(getIsDragging)\n\n    const listContainerDisplayName = useMemo(() => {\n      const listWidgetDisplayNames = Object.keys(containerListMapChildName)\n      let currentListDisplayName = \"\"\n      for (let i = 0; i < listWidgetDisplayNames.length; i++) {\n        if (\n          containerListMapChildName[listWidgetDisplayNames[i]].includes(\n            displayName,\n          )\n        ) {\n          currentListDisplayName = listWidgetDisplayNames[i]\n          break\n        }\n      }\n      return currentListDisplayName\n    }, [containerListMapChildName, displayName])\n\n    const listContainerDisabled = useMemo(() => {\n      const currentListDisplayName = listContainerDisplayName\n      const listWidgetProps = displayNameMapProps[currentListDisplayName]\n      if (\n        isObject(listWidgetProps) &&\n        listWidgetProps.hasOwnProperty(\"disabled\") &&\n        listWidgetProps.disabled != undefined\n      )\n        return listWidgetProps.disabled\n      return realProps?.disabled\n    }, [displayNameMapProps, listContainerDisplayName, realProps?.disabled])\n\n    const updateComponentRuntimeProps = useCallback(\n      (runtimeProp: unknown) => {\n        ILLAEditorRuntimePropsCollectorInstance.addRuntimeProp(\n          displayName,\n          runtimeProp,\n        )\n      },\n      [displayName],\n    )\n\n    const deleteComponentRuntimeProps = useCallback(() => {\n      ILLAEditorRuntimePropsCollectorInstance.deleteRuntimeProp(displayName)\n    }, [displayName])\n\n    const {\n      dynamicHeight = \"fixed\",\n      dynamicMinHeight,\n      dynamicMaxHeight,\n    } = realProps\n\n    const updateComponentHeight = useCallback(\n      (newHeight: number) => {\n        if (isDraggingInGlobal) return\n        const rootState = store.getState()\n        const widgetLayoutInfos = getClientWidgetLayoutInfo(rootState)\n        const oldH = widgetLayoutInfos[displayName]?.layoutInfo.h ?? 0\n\n        if (dynamicHeight !== \"fixed\") {\n          if (\n            dynamicMaxHeight &&\n            newHeight >\n              dynamicMaxHeight -\n                (WIDGET_PADDING + WIDGET_SCALE_SQUARE_BORDER_WIDTH) * 2\n          ) {\n            newHeight =\n              dynamicMaxHeight -\n              (WIDGET_PADDING + WIDGET_SCALE_SQUARE_BORDER_WIDTH) * 2\n          }\n\n          if (\n            dynamicMinHeight &&\n            newHeight <=\n              dynamicMinHeight -\n                (WIDGET_PADDING + WIDGET_SCALE_SQUARE_BORDER_WIDTH) * 2\n          ) {\n            newHeight =\n              dynamicMinHeight -\n              (WIDGET_PADDING + WIDGET_SCALE_SQUARE_BORDER_WIDTH) * 2\n          }\n        }\n\n        const newH = Math.max(\n          Math.ceil(\n            (newHeight +\n              (WIDGET_PADDING + WIDGET_SCALE_SQUARE_BORDER_WIDTH) * 2) /\n              UNIT_HEIGHT,\n          ),\n          MIN_HEIGHT,\n        )\n\n        if (newH === oldH) return\n\n        dispatch(\n          layoutInfoActions.updateWidgetLayoutInfoReducer({\n            displayName,\n            layoutInfo: {\n              h: newH,\n            },\n            parentNode: parentNodeDisplayName,\n            effectRows: newH - oldH,\n          }),\n        )\n      },\n      [\n        dispatch,\n        displayName,\n        dynamicHeight,\n        dynamicMaxHeight,\n        dynamicMinHeight,\n        isDraggingInGlobal,\n        parentNodeDisplayName,\n      ],\n    )\n\n    const handleUpdateDsl = useCallback(\n      (value: Record<string, any>) => {\n        dispatch(\n          executionActions.updateExecutionByDisplayNameReducer({\n            displayName,\n            value,\n          }),\n        )\n      },\n      [dispatch, displayName],\n    )\n\n    const handleUpdateMultiExecutionResult = useCallback(\n      (allUpdate: { displayName: string; value: Record<string, any> }[]) => {\n        dispatch(\n          executionActions.updateExecutionByMultiDisplayNameReducer(allUpdate),\n        )\n      },\n      [dispatch],\n    )\n\n    const handleUpdateOriginalDSLMultiAttr = useCallback(\n      (updateSlice: Record<string, any>, notUseUndoRedo?: boolean) => {\n        if (!isObject(updateSlice)) return\n        dispatch(\n          componentsActions.updateComponentPropsReducer({\n            displayName: displayName,\n            updateSlice,\n            notUseUndoRedo,\n          }),\n        )\n      },\n      [dispatch, displayName],\n    )\n\n    const handleUpdateOriginalDSLOtherMultiAttr = useCallback(\n      (\n        displayName: string,\n        updateSlice: Record<string, any>,\n        notUseUndoRedo?: boolean,\n      ) => {\n        if (!displayName || !isObject(updateSlice)) return\n        dispatch(\n          componentsActions.updateComponentPropsReducer({\n            displayName,\n            updateSlice,\n            notUseUndoRedo,\n          }),\n        )\n      },\n      [dispatch],\n    )\n\n    const getRunEvents = useCallback(\n      (\n        eventType: string,\n        path: string,\n        otherCalcContext?: Record<string, any>,\n      ) => {\n        const originEvents = get(originComponentNode.props, path, []) as any[]\n        const dynamicPaths = get(\n          originComponentNode.props,\n          \"$dynamicAttrPaths\",\n          [],\n        )\n\n        const needRunEvents = klona(originEvents)\n          .filter((originEvent) => {\n            return originEvent.eventType === eventType\n          })\n          .map((originEvent) => {\n            return {\n              ...originEvent,\n              originEnable: originEvent.enabled,\n            }\n          })\n        const finalContext =\n          ILLAEditorRuntimePropsCollectorInstance.getCurrentPageCalcContext(\n            otherCalcContext,\n          )\n        return {\n          dynamicPaths,\n          needRunEvents,\n          finalContext,\n        }\n      },\n      [originComponentNode?.props],\n    )\n\n    const triggerEventHandler = useCallback(\n      (\n        eventType: string,\n        path: string = \"events\",\n        otherCalcContext?: Record<string, any>,\n        formatPath?: (path: string) => string,\n      ) => {\n        const { dynamicPaths, needRunEvents, finalContext } = getRunEvents(\n          eventType,\n          path,\n          otherCalcContext,\n        )\n\n        dynamicPaths?.forEach((path: string) => {\n          const realPath = isFunction(formatPath)\n            ? formatPath(path)\n            : convertPathToString(toPath(path).slice(1))\n          const dynamicString = get(needRunEvents, realPath, \"\")\n          if (dynamicString) {\n            try {\n              const calcValue = evaluateDynamicString(\n                `events${realPath}`,\n                dynamicString,\n                finalContext,\n              )\n              if (listContainerDisplayName) {\n                set(\n                  needRunEvents,\n                  realPath,\n                  Array.isArray(calcValue) ? calcValue[0] : calcValue,\n                )\n              } else {\n                set(needRunEvents, realPath, calcValue)\n              }\n            } catch {\n              set(needRunEvents, realPath, undefined)\n            }\n          }\n        })\n\n        needRunEvents.forEach((scriptObj: any) => {\n          runEventHandler(scriptObj, finalContext)\n        })\n      },\n      [getRunEvents, listContainerDisplayName],\n    )\n\n    const triggerMappedEventHandler = useCallback(\n      (\n        eventType: string,\n        path: string = \"events\",\n        index?: number,\n        formatPath?: (path: string) => string,\n        isMapped?: (dynamicString: string, calcValue: unknown) => boolean,\n      ) => {\n        const { dynamicPaths, needRunEvents, finalContext } = getRunEvents(\n          eventType,\n          path,\n        )\n        dynamicPaths?.forEach((path: string) => {\n          const realPath = isFunction(formatPath)\n            ? formatPath(path)\n            : convertPathToString(toPath(path).slice(2))\n\n          const dynamicString = get(needRunEvents, realPath, \"\")\n\n          if (dynamicString) {\n            try {\n              const calcValue = evaluateDynamicString(\n                `events${realPath}`,\n                dynamicString,\n                finalContext,\n              )\n              let valueToSet = calcValue\n\n              if (listContainerDisplayName) {\n                valueToSet = Array.isArray(calcValue) ? calcValue[0] : calcValue\n              }\n\n              if (Array.isArray(calcValue) && isNumber(index)) {\n                if (\n                  !isFunction(isMapped) ||\n                  isMapped(dynamicString, calcValue)\n                ) {\n                  valueToSet = calcValue[index]\n                }\n              }\n              set(needRunEvents, realPath, valueToSet)\n            } catch {\n              set(needRunEvents, realPath, undefined)\n            }\n          }\n        })\n        needRunEvents.forEach((scriptObj: any) => {\n          runEventHandler(scriptObj, finalContext)\n        })\n      },\n      [getRunEvents, listContainerDisplayName],\n    )\n\n    const widgetConfig = widgetBuilder(widgetType)\n    if (!widgetConfig) return null\n    const Component = widgetConfig.widget\n    const {\n      hidden,\n      borderColor,\n      backgroundColor,\n      radius,\n      borderWidth,\n      shadow,\n    } = realProps\n\n    const _radius = !isNaN(Number(radius)) ? radius + \"px\" : radius?.toString()\n    const _borderWidth = !isNaN(Number(borderWidth))\n      ? borderWidth + \"px\"\n      : borderWidth?.toString()\n\n    return (\n      <ErrorBoundary>\n        {hidden ? null : (\n          <div\n            css={applyWrapperStylesStyle(\n              borderColor,\n              _borderWidth,\n              _radius,\n              backgroundColor,\n              shadow,\n              widgetType,\n            )}\n            id={displayName}\n          >\n            <Suspense\n              fallback={\n                <Skeleton\n                  animation\n                  text={false}\n                  image={{\n                    shape: \"square\",\n                    w: \"100%\",\n                    h: \"100%\",\n                    mr: \"0 !important\",\n                  }}\n                  h=\"100%\"\n                  w=\"100%\"\n                />\n              }\n            >\n              <Component\n                {...realProps}\n                h={layoutInfo.h}\n                w={layoutInfo.w}\n                columnNumber={columnNumber}\n                handleUpdateOriginalDSLMultiAttr={\n                  handleUpdateOriginalDSLMultiAttr\n                }\n                handleUpdateOriginalDSLOtherMultiAttr={\n                  handleUpdateOriginalDSLOtherMultiAttr\n                }\n                handleUpdateDsl={handleUpdateDsl}\n                updateComponentHeight={updateComponentHeight}\n                handleUpdateMultiExecutionResult={\n                  handleUpdateMultiExecutionResult\n                }\n                displayName={displayName}\n                childrenNode={originComponentNode.childrenNode}\n                componentNode={originComponentNode}\n                disabled={listContainerDisabled}\n                triggerEventHandler={triggerEventHandler}\n                triggerMappedEventHandler={triggerMappedEventHandler}\n                updateComponentRuntimeProps={updateComponentRuntimeProps}\n                deleteComponentRuntimeProps={deleteComponentRuntimeProps}\n              />\n            </Suspense>\n          </div>\n        )}\n      </ErrorBoundary>\n    )\n  },\n)\n\nTransformWidgetWrapper.displayName = \"TransformWidgetWrapper\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/TransformWidgetWrapper/interface.ts",
    "content": "import { ComponentTreeNode } from \"@illa-public/public-types\"\n\nexport interface TransformWidgetProps {\n  displayName: string\n  widgetType: string\n  parentNodeDisplayName: string\n  columnNumber?: number\n}\n\nexport interface TransformWidgetWrapperWithJsonProps {\n  componentNode: ComponentTreeNode\n  unitW: number\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/TransformWidgetWrapper/renderWithJSON.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { klona } from \"klona\"\nimport { get, isFunction, isNumber, set, toPath } from \"lodash-es\"\nimport { FC, Suspense, memo, useCallback, useMemo } from \"react\"\nimport { useDispatch } from \"react-redux\"\nimport { Skeleton } from \"@illa-design/react\"\nimport ErrorBoundary from \"@/components/ErrorBoundary\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport { componentsActions } from \"@/redux/currentApp/components/componentsSlice\"\nimport { executionActions } from \"@/redux/currentApp/executionTree/executionSlice\"\nimport { evaluateDynamicString } from \"@/utils/evaluateDynamicString\"\nimport { runEventHandler } from \"@/utils/eventHandlerHelper\"\nimport { ILLAEditorRuntimePropsCollectorInstance } from \"@/utils/executionTreeHelper/runtimePropsCollector\"\nimport { isObject } from \"@/utils/typeHelper\"\nimport { TransformWidgetWrapperWithJsonProps } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/interface\"\nimport { applyWrapperStylesStyle } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { EventsInProps } from \"@/widgetLibrary/interface\"\nimport { widgetBuilder } from \"@/widgetLibrary/widgetBuilder\"\n\nexport const getEventScripts = (events: EventsInProps[], eventType: string) => {\n  return events.filter((event) => {\n    return event.eventType === eventType\n  })\n}\n\nexport const TransformWidgetWrapperWithJson: FC<TransformWidgetWrapperWithJsonProps> =\n  memo((props: TransformWidgetWrapperWithJsonProps) => {\n    const { componentNode, unitW } = props\n\n    const {\n      displayName,\n      type,\n      w,\n      h,\n      childrenNode,\n      props: nodeProps,\n    } = componentNode\n\n    const dispatch = useDispatch()\n\n    const updateComponentRuntimeProps = useCallback(\n      (runtimeProp: unknown) => {\n        ILLAEditorRuntimePropsCollectorInstance.addRuntimeProp(\n          displayName,\n          runtimeProp,\n        )\n      },\n      [displayName],\n    )\n\n    const deleteComponentRuntimeProps = useCallback(() => {\n      ILLAEditorRuntimePropsCollectorInstance.deleteRuntimeProp(displayName)\n    }, [displayName])\n\n    const realProps = useMemo(() => nodeProps ?? {}, [nodeProps])\n\n    const handleUpdateDsl = useCallback(\n      (value: Record<string, any>) => {\n        dispatch(\n          executionActions.updateExecutionByDisplayNameReducer({\n            displayName,\n            value,\n          }),\n        )\n      },\n      [dispatch, displayName],\n    )\n\n    const handleUpdateMultiExecutionResult = useCallback(\n      (allUpdate: { displayName: string; value: Record<string, any> }[]) => {\n        dispatch(\n          executionActions.updateExecutionByMultiDisplayNameReducer(allUpdate),\n        )\n      },\n      [dispatch],\n    )\n\n    const handleUpdateOriginalDSLMultiAttr = useCallback(\n      (updateSlice: Record<string, any>, notUseUndoRedo?: boolean) => {\n        if (!isObject(updateSlice)) return\n        dispatch(\n          componentsActions.updateComponentPropsReducer({\n            displayName: displayName,\n            updateSlice,\n            notUseUndoRedo,\n          }),\n        )\n      },\n      [dispatch, displayName],\n    )\n\n    const handleUpdateOriginalDSLOtherMultiAttr = useCallback(\n      (\n        displayName: string,\n        updateSlice: Record<string, any>,\n        notUseUndoRedo?: boolean,\n      ) => {\n        if (!displayName || !isObject(updateSlice)) return\n        dispatch(\n          componentsActions.updateComponentPropsReducer({\n            displayName,\n            updateSlice,\n            notUseUndoRedo,\n          }),\n        )\n      },\n      [dispatch],\n    )\n\n    const getRunEvents = useCallback(\n      (\n        eventType: string,\n        path: string,\n        otherCalcContext?: Record<string, any>,\n      ) => {\n        const originEvents = get(componentNode.props, path, []) as any[]\n        const dynamicPaths = get(componentNode.props, \"$dynamicAttrPaths\", [])\n        const needRunEvents = klona(originEvents)\n          .filter((originEvent) => {\n            return originEvent.eventType === eventType\n          })\n          .map((originEvent) => {\n            return {\n              ...originEvent,\n              originEnable: originEvent.enabled,\n            }\n          })\n        const finalContext =\n          ILLAEditorRuntimePropsCollectorInstance.getCurrentPageCalcContext(\n            otherCalcContext,\n          )\n        return {\n          dynamicPaths,\n          needRunEvents,\n          finalContext,\n        }\n      },\n      [componentNode.props],\n    )\n\n    const triggerEventHandler = useCallback(\n      (\n        eventType: string,\n        path: string = \"events\",\n        otherCalcContext?: Record<string, any>,\n        formatPath?: (path: string) => string,\n      ) => {\n        const { dynamicPaths, needRunEvents, finalContext } = getRunEvents(\n          eventType,\n          path,\n          otherCalcContext,\n        )\n        dynamicPaths?.forEach((path: string) => {\n          const realPath = isFunction(formatPath)\n            ? formatPath(path)\n            : convertPathToString(toPath(path).slice(1))\n\n          const dynamicString = get(needRunEvents, realPath, \"\")\n          if (dynamicString) {\n            try {\n              const calcValue = evaluateDynamicString(\n                \"\",\n                dynamicString,\n                finalContext,\n              )\n              set(needRunEvents, realPath, calcValue)\n            } catch {\n              set(needRunEvents, realPath, undefined)\n            }\n          }\n        })\n        needRunEvents.forEach((scriptObj: any) => {\n          runEventHandler(scriptObj, finalContext)\n        })\n      },\n      [getRunEvents],\n    )\n\n    const triggerMappedEventHandler = useCallback(\n      (eventType: string, path: string = \"events\", index?: number) => {\n        const { dynamicPaths, needRunEvents, finalContext } = getRunEvents(\n          eventType,\n          path,\n        )\n        dynamicPaths?.forEach((path: string) => {\n          const realPath = convertPathToString(toPath(path).slice(2))\n          const dynamicString = get(needRunEvents, realPath, \"\")\n          if (dynamicString) {\n            try {\n              const calcValue = evaluateDynamicString(\n                \"\",\n                dynamicString,\n                finalContext,\n              )\n              if (Array.isArray(calcValue) && isNumber(index)) {\n                set(needRunEvents, realPath, calcValue[index])\n              } else {\n                set(needRunEvents, realPath, calcValue)\n              }\n            } catch {\n              set(needRunEvents, realPath, undefined)\n            }\n          }\n        })\n        needRunEvents.forEach((scriptObj: any) => {\n          runEventHandler(scriptObj, finalContext)\n        })\n      },\n      [getRunEvents],\n    )\n\n    if (!type) return null\n    const widgetConfig = widgetBuilder(type)\n    if (!widgetConfig) return null\n    const Component = widgetConfig.widget\n\n    const {\n      hidden,\n      borderColor,\n      backgroundColor,\n      radius,\n      borderWidth,\n      shadow,\n    } = realProps\n\n    const _radius = !isNaN(Number(radius)) ? radius + \"px\" : radius?.toString()\n    const _borderWidth = !isNaN(Number(borderWidth))\n      ? borderWidth + \"px\"\n      : borderWidth?.toString()\n\n    return (\n      <ErrorBoundary>\n        {hidden ? null : (\n          <div\n            css={applyWrapperStylesStyle(\n              borderColor,\n              _borderWidth,\n              _radius,\n              backgroundColor,\n              shadow,\n              type,\n            )}\n          >\n            <Suspense\n              fallback={\n                <Skeleton\n                  animation\n                  text={false}\n                  image={{\n                    shape: \"square\",\n                    w: \"100%\",\n                    h: \"100%\",\n                    mr: \"0 !important\",\n                  }}\n                  h=\"100%\"\n                  w=\"100%\"\n                />\n              }\n            >\n              <Component\n                {...realProps}\n                w={w}\n                h={h}\n                unitW={unitW}\n                unitH={UNIT_HEIGHT}\n                updateComponentRuntimeProps={updateComponentRuntimeProps}\n                deleteComponentRuntimeProps={deleteComponentRuntimeProps}\n                handleUpdateOriginalDSLMultiAttr={\n                  handleUpdateOriginalDSLMultiAttr\n                }\n                handleUpdateOriginalDSLOtherMultiAttr={\n                  handleUpdateOriginalDSLOtherMultiAttr\n                }\n                handleUpdateDsl={handleUpdateDsl}\n                handleUpdateMultiExecutionResult={\n                  handleUpdateMultiExecutionResult\n                }\n                displayName={displayName}\n                childrenNode={childrenNode}\n                componentNode={componentNode}\n                triggerEventHandler={triggerEventHandler}\n                triggerMappedEventHandler={triggerMappedEventHandler}\n              />\n            </Suspense>\n          </div>\n        )}\n      </ErrorBoundary>\n    )\n  })\n\nTransformWidgetWrapperWithJson.displayName = \"TransformWidgetWrapper\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/TransformWidgetWrapper/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\nimport { getShadowStyle } from \"@/utils/styleUtils/shadow\"\n\nexport const applyValidateMessageWrapperStyle = (\n  labelWidth: number,\n  labelPosition: \"left\" | \"right\" | \"top\" = \"left\",\n  labelHidden: boolean = false,\n): SerializedStyles => {\n  return css`\n    width: 100%;\n    padding-left: ${labelPosition === \"top\" || labelHidden\n      ? 0\n      : `calc(${labelWidth}% + 8px)`};\n  `\n}\n\nexport const applyLabelAndComponentWrapperStyle = (\n  labelPosition: \"left\" | \"right\" | \"top\" = \"left\",\n) => {\n  if (labelPosition === \"top\") {\n    return css``\n  }\n  if (labelPosition === \"left\") {\n    return css`\n      display: flex;\n    `\n  }\n  if (labelPosition === \"right\") {\n    return css`\n      display: flex;\n      flex-direction: row-reverse;\n    `\n  }\n}\n\nexport const applyCenterLabelAndComponentWrapperStyle = (\n  labelPosition: \"left\" | \"right\" | \"top\" = \"left\",\n) => {\n  const layoutCss = applyLabelAndComponentWrapperStyle(labelPosition)\n  return css`\n    ${layoutCss};\n    width: 100%;\n    height: 100%;\n    align-items: center;\n  `\n}\n\nconst getWrapperBackgroundColor = (\n  widgetType?: string,\n  backgroundColor?: string,\n) => {\n  if (\n    widgetType === \"CONTAINER_WIDGET\" ||\n    widgetType === \"LIST_WIDGET\" ||\n    widgetType === \"MODAL_WIDGET\" ||\n    widgetType === \"FORM_WIDGET\"\n  ) {\n    return backgroundColor\n      ? getSpecialThemeColor(backgroundColor) || backgroundColor\n      : \"white\"\n  }\n  return \"transparent\"\n}\n\nexport const applyWrapperStylesStyle = (\n  borderColor?: string,\n  borderWidth?: string,\n  radius?: string,\n  backgroundColor?: string,\n  shadowSize?: \"none\" | \"small\" | \"medium\" | \"large\",\n  widgetType?: string,\n) => {\n  let borderStyle = \"unset\"\n  if (borderColor && borderWidth) {\n    borderStyle = `${borderWidth} solid ${\n      borderColor\n        ? getSpecialThemeColor(borderColor) || borderColor\n        : \"transparent\"\n    }`\n  }\n  const shadowStyle = getShadowStyle(shadowSize)\n  return css`\n    width: 100%;\n    height: 100%;\n    border: ${borderStyle};\n    border-radius: ${radius};\n    background-color: ${getWrapperBackgroundColor(widgetType, backgroundColor)};\n    box-shadow: ${shadowStyle};\n    overflow-x: hidden;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/WidgetLoading/index.tsx",
    "content": "import { FC, memo } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { widgetLoadingWrapperStyle } from \"./style\"\n\nconst WidgetLoading: FC = () => {\n  return (\n    <div css={widgetLoadingWrapperStyle}>\n      <Loading colorScheme=\"techPurple\" />\n    </div>\n  )\n}\n\nWidgetLoading.displayName = \"WidgetLoading\"\n\nexport default memo(WidgetLoading)\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/WidgetLoading/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const widgetLoadingWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/containerStyle.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  display: flex;\n  width: 100%;\n  align-items: center;\n  justify-content: end;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/utils/autoUpdateHeight.ts",
    "content": "import { useLayoutEffect } from \"react\"\n\nexport const useAutoUpdateCanvasHeight = (\n  handleUpdateHeight: (height: number) => void,\n  containerDom: HTMLElement | null,\n  enable: boolean = true,\n) => {\n  useLayoutEffect(() => {\n    const observerRef = new ResizeObserver((entries) => {\n      if (!handleUpdateHeight) return\n      const height = entries[0].contentRect.height\n      handleUpdateHeight(height)\n    })\n    if (observerRef && containerDom && enable) {\n      observerRef.unobserve(containerDom)\n      observerRef.observe(containerDom)\n    }\n\n    return () => {\n      if (containerDom && enable) {\n        observerRef.unobserve(containerDom)\n      }\n    }\n  }, [containerDom, enable, handleUpdateHeight])\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/utils/formatSelectOptions.ts",
    "content": "// TODO:@aruseito - abstract this function to a common library\nexport const formatSelectOptions = (\n  optionConfigureMode: \"dynamic\" | \"static\" = \"static\",\n  manualOptions: {\n    label: string\n    value: string | number\n    disabled?: boolean\n  }[] = [],\n  mappedOption: {\n    labels: string[]\n    values: any[]\n    disables: boolean[]\n  } = {\n    labels: [],\n    values: [],\n    disables: [],\n  },\n) => {\n  if (optionConfigureMode === \"dynamic\") {\n    const label = mappedOption.labels ?? []\n    const value = mappedOption.values ?? []\n    const disabled = mappedOption.disables ?? []\n    const maxLength = Math.max(label.length, value.length, disabled.length)\n    const options: {\n      label: string\n      value: string | number\n      disabled?: boolean\n    }[] = []\n    for (let i = 0; i < maxLength; i++) {\n      let labelItem = label[i] || value[i] || i\n      const valueItem = value[i] || label[i] || i\n      const disabledItem = disabled[i]\n      if (typeof labelItem === \"object\") {\n        labelItem = i\n      }\n      options.push({\n        label: labelItem,\n        value: valueItem,\n        disabled: disabledItem,\n      })\n    }\n    return options\n  } else {\n    if (!Array.isArray(manualOptions)) {\n      return []\n    }\n    const options: {\n      label: string | number\n      value: string | number\n      disabled?: boolean\n    }[] = []\n    manualOptions.forEach((option, index) => {\n      let labelItem = option.label || option.value || index\n      const valueItem = option.value || labelItem || index\n      const disabledItem = option.disabled\n      if (typeof labelItem === \"object\") {\n        labelItem = index\n      }\n      options.push({\n        label: labelItem,\n        value: valueItem,\n        disabled: disabledItem,\n      })\n    })\n    return options\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerPanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nexport const generatorEventHandlerConfig = (\n  baseWidgetName: string,\n  events: { label: string; value: string }[] = [],\n  labelName: string = i18n.t(\"editor.inspect.setter_label.event_handler\"),\n  attrName: string = \"events\",\n  defaultValue?: string,\n  labelDesc?: string,\n): EventHandlerPanelConfig => {\n  return {\n    id: `${baseWidgetName}-interaction-event-handler`,\n    attrName: attrName,\n    labelName: labelName,\n    labelDesc: labelDesc,\n    setterType: \"EVENT_HANDLER_SETTER\",\n    useCustomLayout: true,\n    defaultValue: defaultValue,\n    eventHandlerConfig: { events, methods: [] },\n    childrenSetter: [\n      {\n        id: `${baseWidgetName}-interaction-event-handler-event`,\n        labelName: i18n.t(\"editor.inspect.setter_label.event\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"eventType\",\n        options: events,\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-action`,\n        labelName: i18n.t(\"editor.inspect.setter_label.action\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.action\"),\n        setterType: \"EVENT_ACTION_SELECT_SETTER\",\n        attrName: \"actionType\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_label.trigger_query\"),\n            value: \"datasource\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.control_component\"),\n            value: \"widget\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.run_script\"),\n            value: \"script\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.go_to_url\"),\n            value: \"openUrl\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.show_notification\"),\n            value: \"showNotification\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.copy_to_clipboard\"),\n            value: \"copyToClipboard\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.set_router\"),\n            value: \"setRouter\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.save_to_drive\"),\n            value: \"saveToILLADrive\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.download_from_drive\"),\n            value: \"downloadFromILLADrive\",\n          },\n          {\n            label: i18n.t(\"editor.method.file_download.download\"),\n            value: \"downloadFile\",\n          },\n          {\n            label: i18n.t(\"editor.method.setGlobalData\"),\n            value: \"setGlobalState\",\n          },\n          {\n            label: i18n.t(\"editor.method.setLocalStorage\"),\n            value: \"setLocalStorage\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-query`,\n        labelName: i18n.t(\"editor.inspect.setter_label.action_name\"),\n        setterType: \"EVENT_TARGET_ACTION_SELECT_SETTER\",\n        attrName: \"queryID\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"datasource\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-actionMethod`,\n        labelName: i18n.t(\"editor.inspect.setter_label.method\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"widgetMethod\",\n        bindAttrName: [\"queryID\"],\n        shown: (type) => type === \"datasource\",\n        options: [{ label: \"run\", value: \"executeAction\" }],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-component`,\n        labelName: i18n.t(\"editor.inspect.setter_label.component\"),\n        setterType: \"EVENT_TARGET_SELECT_SETTER\",\n        attrName: \"widgetID\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"widget\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-Method`,\n        labelName: i18n.t(\"editor.inspect.setter_label.method\"),\n        setterType: \"EVENT_WIDGET_METHOD_SELECT_SETTER\",\n        attrName: \"widgetMethod\",\n        bindAttrName: [\"widgetID\"],\n        shown: (widgetID) => !!widgetID,\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-Value`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-start-value`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.range_slider.start_value\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setStartOfRange\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-end-value`,\n        labelName: i18n.t(\"editor.inspect.setter_label.range_slider.end_value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setEndOfRange\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-valueInArray`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.switch_group.default_value\",\n        ),\n        placeholder: '{{[\"value1\", \"value2\"]}}',\n        isSetterSingleRow: true,\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setValueInArray\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-selectValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        placeholder: i18n.t(\n          \"editor.inspect.setter_placeholder.multiselect.value\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setSelectedValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-markers`,\n        labelName: i18n.t(\"editor.inspect.setter_label.map.markers\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.map.markers\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setMarkers\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-add-event`,\n        labelName: i18n.t(\"editor.method.eventCalendar.addevent\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.eventCalendar.event_value\",\n        ),\n        placeholder: i18n.t(\n          \"editor.inspect.setter_label.eventCalendar.event_value\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"addEvent\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-delete-event`,\n        labelName: i18n.t(\"editor.method.eventCalendar.deleteevent\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.eventCalendar.event_id\"),\n        placeholder: i18n.t(\n          \"editor.inspect.setter_label.eventCalendar.event_id\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"deleteEvent\",\n      },\n      {\n        // TODO: follow-up support @mengcheng\n        id: `${baseWidgetName}-interaction-event-handler-setHidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"widgetSwitchTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (widgetMethod) => widgetMethod === \"setHidden\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setDisabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"widgetSwitchTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (widgetMethod) => widgetMethod === \"setDisabled\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-startValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.start_date\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setStartValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-endValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.end_data\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setEndValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-startTime`,\n        labelName: i18n.t(\"editor.inspect.setter_label.time_range.start_time\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setStartTime\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-endTime`,\n        labelName: i18n.t(\"editor.inspect.setter_label.time_range.end_time\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setEndTime\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setPrimaryValue`,\n        labelName: i18n.t(\"editor.method.statistics.primary_value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        placeholder: \"{{ 1234 }}\",\n        // expectedType: VALIDATION_TYPES.NUMBER,\n        shown: (widgetMethod) => widgetMethod === \"setPrimaryValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-imageUrl`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) =>\n          widgetMethod === \"setImageUrl\" || widgetMethod === \"setSrc\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-pageIndex`,\n        labelName: i18n.t(\"editor.inspect.setter_label.range_slider.end_value\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        attrName: \"pageIndex\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"selectPage\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-sortKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_sort_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"sortKey\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setSort\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-sortOrder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_sort_order\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"sortOrder\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setSort\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-filters`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.filters\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.filters\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n        attrName: \"filters\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setFilters\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-operator`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.filter_mode\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.filter_mode\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"operator\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setFilters\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-rowSelection`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.table.default_selected_row\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"selectRow\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-copiedValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"copiedValue\",\n        bindAttrName: [\"actionType\"],\n        shown: (widgetMethod) => widgetMethod === \"copyToClipboard\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-fileUrl`,\n        labelName: i18n.t(\"editor.inspect.setter_label.file_url\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setFileUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-videoUrl`,\n        labelName: i18n.t(\"editor.inspect.setter_label.video_url\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setVideoUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-audioUrl`,\n        labelName: i18n.t(\"editor.inspect.setter_label.audio.audio_url\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setAudioUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-speed`,\n        labelName: i18n.t(\"editor.method.speed.speed\"),\n        placeholder: \"{{ 1.5 }}\",\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        // expectedType: VALIDATION_TYPES.NUMBER,\n        shown: (widgetMethod) => widgetMethod === \"setSpeed\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-volume`,\n        labelName: i18n.t(\"editor.method.set_volume.volume\"),\n        placeholder: \"{{ 0.5 }}\",\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        // expectedType: VALIDATION_TYPES.NUMBER,\n        shown: (widgetMethod) => widgetMethod === \"setVolume\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-seekTo`,\n        labelName:\n          i18n.t(\"editor.method.seek_to.time\") +\n          i18n.t(\"editor.method.seek_to.unit\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        // expectedType: VALIDATION_TYPES.NUMBER,\n        shown: (widgetMethod) => widgetMethod === \"seekTo\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-loop`,\n        labelName: i18n.t(\"editor.method.loop\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"widgetSwitchTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        // expectedType: VALIDATION_TYPES.BOOLEAN,\n        shown: (widgetMethod) => widgetMethod === \"setLoop\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-mute`,\n        labelName: i18n.t(\"editor.method.mute\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"widgetSwitchTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        // expectedType: VALIDATION_TYPES.BOOLEAN,\n        shown: (widgetMethod) => widgetMethod === \"mute\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-showControls`,\n        labelName: i18n.t(\"editor.method.show_controls\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"widgetSwitchTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        // expectedType: VALIDATION_TYPES.BOOLEAN,\n        shown: (widgetMethod) => widgetMethod === \"showControls\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-select-state`,\n        labelName: i18n.t(\"editor.inspect.setter_label.name\"),\n        setterType: \"EVENT_TARGET_STATE_SELECT_SETTER\",\n        attrName: \"stateDisplayName\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"setGlobalState\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-state-method`,\n        labelName: i18n.t(\"editor.inspect.setter_label.method\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"globalStateMethod\",\n        bindAttrName: [\"stateDisplayName\"],\n        shown: (stateDisplayName) => !!stateDisplayName,\n        options: [\n          {\n            label: \"Set In\",\n            value: \"setIn\",\n          },\n          {\n            label: \"Set Value\",\n            value: \"setValue\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-stateKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.variable.path_of_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.variable.available_in_objects\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"globalStateKeyPath\",\n        bindAttrName: [\"globalStateMethod\"],\n        shown: (globalStateMethod) => globalStateMethod === \"setIn\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-stateValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"globalStateValue\",\n        bindAttrName: [\"globalStateMethod\"],\n        shown: (globalStateMethod) =>\n          globalStateMethod === \"setValue\" || globalStateMethod === \"setIn\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-storage-method`,\n        labelName: i18n.t(\"editor.inspect.setter_label.method\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"localStorageMethod\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"setLocalStorage\",\n        options: [\n          {\n            label: \"Clear\",\n            value: \"clear\",\n          },\n          {\n            label: \"Set Value\",\n            value: \"setValue\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-localStorageKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.key\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"localStorageKey\",\n        bindAttrName: [\"localStorageMethod\"],\n        shown: (localStorageMethod) => localStorageMethod === \"setValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-localStorageValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"localStorageValue\",\n        bindAttrName: [\"localStorageMethod\"],\n        shown: (localStorageMethod) => localStorageMethod === \"setValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"disabled\",\n        bindAttrName: [\"type\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (type) => type === \"widget\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-script`,\n        setterType: \"SCRIPT_INPUT_SETTER\",\n        attrName: \"script\",\n        bindAttrName: [\"actionType\"],\n        expectedType: VALIDATION_TYPES.STRING,\n        shown: (type) => type === \"script\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-URL`,\n        labelName: \"URL\",\n        setterType: \"INPUT_SETTER\",\n        attrName: \"url\",\n        bindAttrName: [\"actionType\"],\n        expectedType: VALIDATION_TYPES.STRING,\n        shown: (type) => type === \"openUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-newTab`,\n        labelName: i18n.t(\"editor.inspect.setter_label.new_tab\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"newTab\",\n        bindAttrName: [\"actionType\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (type) => type === \"openUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setCurrentViewKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"key\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"setCurrentViewKey\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setCurrentViewIndex`,\n        labelName: i18n.t(\"editor.inspect.setter_label.index\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        attrName: \"index\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"setCurrentViewIndex\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-showNextView`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loop_back_to_start\"),\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"showNextViewLoopBack\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"showNextView\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-showNextVisibleView`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loop_back_to_start\"),\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"showNextVisibleViewLoopBack\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"showNextVisibleView\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-showPreviousView`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loop_start_to_back\"),\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"showPreviousViewLoopBack\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"showPreviousView\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-showPreviousVisibleView`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loop_start_to_back\"),\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"showPreviousVisibleViewLoopBack\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"showPreviousVisibleView\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-title`,\n        labelName: i18n.t(\"editor.inspect.setter_label.title\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"title\",\n        bindAttrName: [\"actionType\"],\n        expectedType: VALIDATION_TYPES.STRING,\n        shown: (type) => type === \"showNotification\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-description`,\n        labelName: i18n.t(\"editor.inspect.setter_label.description\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"description\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"showNotification\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-notification-type`,\n        labelName: i18n.t(\"editor.inspect.setter_label.type\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"notificationType\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"showNotification\",\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.message_type.success\",\n            ),\n            value: \"success\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.message_type.error\",\n            ),\n            value: \"error\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.message_type.warning\",\n            ),\n            value: \"warning\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.message_type.info\",\n            ),\n            value: \"info\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-page`,\n        labelName: i18n.t(\"editor.inspect.setter_label.page\"),\n        setterType: \"EVENT_TARGET_PAGE_SELECT_SETTER\",\n        placeholder: i18n.t(\n          \"editor.inspect.setter_content.select_page_setter.placeholder\",\n        ),\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"pagePath\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"setRouter\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-view-path`,\n        labelName: i18n.t(\"editor.page.label_name.view_path\"),\n        placeholder: i18n.t(\n          \"editor.inspect.setter_content.select_view_setter.placeholder\",\n        ),\n        setterType: \"EVENT_TARGET_VIEW_PATH_SELECT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"viewPath\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"setRouter\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-duration`,\n        labelName: `${i18n.t(\"editor.inspect.setter_label.duration\")}(ms)`,\n        setterType: \"INPUT_SETTER\",\n        attrName: \"duration\",\n        bindAttrName: [\"actionType\"],\n        expectedType: VALIDATION_TYPES.NUMBER,\n        placeholder: \"{{4500}}\",\n        shown: (type) => type === \"showNotification\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-fileName`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.file_download.file_name\",\n        ),\n        placeholder: i18n.t(\n          \"editor.inspect.setter_placeholder.file_download.file_name\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"fileName\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"downloadFile\" || type === \"saveToILLADrive\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-fileData`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.file_download.file_data\",\n        ),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.file_download.file_data\"),\n        placeholder: i18n.t(\n          \"editor.inspect.setter_placeholder.file_download.file_data\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"fileData\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"downloadFile\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-download-from-illa-drive-file-data`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.file_download.file_data\",\n        ),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.file_download.file_data\"),\n        placeholder: `{{filePicker1.value}}`,\n        setterType: \"INPUT_SETTER\",\n        attrName: \"fileData\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"saveToILLADrive\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-fileType`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.file_download.file_type\",\n        ),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"fileType\",\n        bindAttrName: [\"actionType\"],\n        defaultValue: \"auto\",\n        shown: (type) => type === \"downloadFile\" || type === \"saveToILLADrive\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.auto\"),\n            value: \"auto\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.file_download.plain_text\",\n            ),\n            value: \"txt\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.jpeg\"),\n            value: \"jpeg\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.png\"),\n            value: \"png\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.svg\"),\n            value: \"svg\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.json\"),\n            value: \"json\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.csv\"),\n            value: \"csv\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.tsv\"),\n            value: \"tsv\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.excel\"),\n            value: \"xlsx\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-allow-anonymous-use`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.allow_public_use\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.allow_public_use\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"allowAnonymous\",\n        bindAttrName: [\"actionType\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (type) =>\n          type === \"downloadFromILLADrive\" || type === \"saveToILLADrive\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-folder-path`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.illa_drive_folder\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.illa_drive_folder\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"folder\",\n        placeholder: \"folder/folder\",\n        bindAttrName: [\"actionType\", \"allowAnonymous\"],\n        shown: (type, allowAnonymous) =>\n          type === \"saveToILLADrive\" && !allowAnonymous,\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-duplication`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.file_name_duplicatio\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.file_name_duplicatio\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"duplicationHandler\",\n        bindAttrName: [\"actionType\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (type) => type === \"saveToILLADrive\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-download-info-with-drive`,\n        labelName: i18n.t(\"editor.inspect.setter_label.drive_builder.fileData\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.drive_builder.fileData\"),\n        placeholder: `{{filePicker1.value}}`,\n        setterType: \"INPUT_SETTER\",\n        attrName: \"downloadInfo\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"downloadFromILLADrive\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-as-zip-with-download`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.drive_builder.downloadZIP\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.drive_builder.downloadZIP\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"asZip\",\n        bindAttrName: [\"actionType\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (type) => type === \"downloadFromILLADrive\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setFilterModel`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (method) => method === \"setFilterModel\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setColumnVisibilityModel`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (method) => method === \"setColumnVisibilityModel\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setPage`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (method) => method === \"setPage\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setPageSize`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (method) => method === \"setPageSize\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setRowSelection`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (method) => method === \"setRowSelection\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-enabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.only_run_when\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.only_run_when\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"enabled\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-render`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        expectedType: VALIDATION_TYPES.STRING,\n        shown: (method) => method === \"renderEditor\",\n      },\n    ],\n  }\n}\n\nexport const actionSuccessEventHandlerConfig = generatorEventHandlerConfig(\n  \"success-event\",\n  [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.success\",\n      ),\n      value: \"success\",\n    },\n  ],\n  i18n.t(\"editor.inspect.setter_label.success\"),\n  \"successEvent\",\n  \"success\",\n)\n\nexport const actionFailedEventHandlerConfig = generatorEventHandlerConfig(\n  \"failed-event\",\n  [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.fail\",\n      ),\n      value: \"fail\",\n    },\n  ],\n  i18n.t(\"editor.inspect.setter_label.failure\"),\n  \"failedEvent\",\n  \"fail\",\n)\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/PublicSector/utils/generatorTableEventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerPanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\n// notice: [INPUT_SETTER] need to be replaced with [TABLE_MAPPED_VALUE_INPUT_SETTER] in table config\nexport const generatorTableEventHandlerConfig = (\n  baseWidgetName: string,\n  events: { label: string; value: string }[] = [],\n  labelName: string = i18n.t(\"editor.inspect.setter_label.event_handler\"),\n  attrName: string = \"events\",\n  defaultValue?: string,\n): EventHandlerPanelConfig => {\n  return {\n    id: `${baseWidgetName}-interaction-event-handler`,\n    attrName: attrName,\n    labelName: labelName,\n    setterType: \"EVENT_HANDLER_SETTER\",\n    useCustomLayout: true,\n    defaultValue: defaultValue,\n    eventHandlerConfig: { events, methods: [] },\n    childrenSetter: [\n      {\n        id: `${baseWidgetName}-interaction-event-handler-event`,\n        labelName: i18n.t(\"editor.inspect.setter_label.event\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"eventType\",\n        options: events,\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-action`,\n        labelName: i18n.t(\"editor.inspect.setter_label.action\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.action\"),\n        setterType: \"EVENT_ACTION_SELECT_SETTER\",\n        attrName: \"actionType\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_label.trigger_query\"),\n            value: \"datasource\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.control_component\"),\n            value: \"widget\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.go_to_url\"),\n            value: \"openUrl\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.show_notification\"),\n            value: \"showNotification\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.copy_to_clipboard\"),\n            value: \"copyToClipboard\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_label.set_router\"),\n            value: \"setRouter\",\n          },\n          {\n            label: i18n.t(\"editor.method.file_download.download\"),\n            value: \"downloadFile\",\n          },\n          {\n            label: i18n.t(\"editor.method.setGlobalData\"),\n            value: \"setGlobalState\",\n          },\n          {\n            label: i18n.t(\"editor.method.setLocalStorage\"),\n            value: \"setLocalStorage\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-query`,\n        labelName: i18n.t(\"editor.inspect.setter_label.action_name\"),\n        setterType: \"EVENT_TARGET_ACTION_SELECT_SETTER\",\n        attrName: \"queryID\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"datasource\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-actionMethod`,\n        labelName: i18n.t(\"editor.inspect.setter_label.method\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"widgetMethod\",\n        bindAttrName: [\"queryID\"],\n        shown: (type) => type === \"datasource\",\n        options: [{ label: \"run\", value: \"executeAction\" }],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-component`,\n        labelName: i18n.t(\"editor.inspect.setter_label.component\"),\n        setterType: \"EVENT_TARGET_SELECT_SETTER\",\n        attrName: \"widgetID\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"widget\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-Method`,\n        labelName: i18n.t(\"editor.inspect.setter_label.method\"),\n        setterType: \"EVENT_WIDGET_METHOD_SELECT_SETTER\",\n        attrName: \"widgetMethod\",\n        bindAttrName: [\"widgetID\"],\n        shown: (widgetID) => !!widgetID,\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-Value`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.table_set_value\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-selectValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        placeholder: i18n.t(\n          \"editor.inspect.setter_placeholder.multiselect.value\",\n        ),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setSelectedValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setHidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"widgetSwitchTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (widgetMethod) => widgetMethod === \"setHidden\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setDisabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"widgetSwitchTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (widgetMethod) => widgetMethod === \"setDisabled\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-startValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.start_date\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setStartValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-endValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.end_data\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setEndValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setPrimaryValue`,\n        labelName: i18n.t(\"editor.method.statistics.primary_value\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        placeholder: \"{{ 1234 }}\",\n        // expectedType: VALIDATION_TYPES.NUMBER,\n        shown: (widgetMethod) => widgetMethod === \"setPrimaryValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-imageUrl`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setImageUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-pageIndex`,\n        labelName: i18n.t(\"editor.inspect.setter_label.range_slider.end_value\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        attrName: \"pageIndex\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"selectPage\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-sortKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_sort_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"sortKey\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setSort\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-sortOrder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_sort_order\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"sortOrder\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setSort\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-filters`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.filters\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.filters\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n        attrName: \"filters\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setFilters\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-operator`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.filter_mode\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.filter_mode\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"operator\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setFilters\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-rowSelection`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.table.default_selected_row\",\n        ),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"selectRow\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-copiedValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"copiedValue\",\n        bindAttrName: [\"actionType\"],\n        shown: (widgetMethod) => widgetMethod === \"copyToClipboard\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-fileUrl`,\n        labelName: i18n.t(\"editor.inspect.setter_label.file_url\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setFileUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-videoUrl`,\n        labelName: i18n.t(\"editor.inspect.setter_label.video_url\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setVideoUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-audioUrl`,\n        labelName: i18n.t(\"editor.inspect.setter_label.audio.audio_url\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (widgetMethod) => widgetMethod === \"setAudioUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-speed`,\n        labelName: i18n.t(\"editor.method.speed.speed\"),\n        placeholder: \"{{ 1.5 }}\",\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        // expectedType: VALIDATION_TYPES.NUMBER,\n        shown: (widgetMethod) => widgetMethod === \"setSpeed\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-volume`,\n        labelName: i18n.t(\"editor.method.set_volume.volume\"),\n        placeholder: \"{{ 0.5 }}\",\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        // expectedType: VALIDATION_TYPES.NUMBER,\n        shown: (widgetMethod) => widgetMethod === \"setVolume\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-seekTo`,\n        labelName:\n          i18n.t(\"editor.method.seek_to.time\") +\n          i18n.t(\"editor.method.seek_to.unit\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"widgetTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        // expectedType: VALIDATION_TYPES.NUMBER,\n        shown: (widgetMethod) => widgetMethod === \"seekTo\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-loop`,\n        labelName: i18n.t(\"editor.method.loop\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"widgetSwitchTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        shown: (widgetMethod) => widgetMethod === \"setLoop\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-mute`,\n        labelName: i18n.t(\"editor.method.mute\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"widgetSwitchTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        shown: (widgetMethod) => widgetMethod === \"mute\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-showControls`,\n        labelName: i18n.t(\"editor.method.show_controls\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"widgetSwitchTargetValue\",\n        bindAttrName: [\"widgetMethod\"],\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        shown: (widgetMethod) => widgetMethod === \"showControls\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-select-state`,\n        labelName: i18n.t(\"editor.inspect.setter_label.name\"),\n        setterType: \"EVENT_TARGET_STATE_SELECT_SETTER\",\n        attrName: \"stateDisplayName\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"setGlobalState\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-state-method`,\n        labelName: i18n.t(\"editor.inspect.setter_label.method\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"globalStateMethod\",\n        bindAttrName: [\"stateDisplayName\"],\n        shown: (stateDisplayName) => !!stateDisplayName,\n        options: [\n          {\n            label: \"Set In\",\n            value: \"setIn\",\n          },\n          {\n            label: \"Set Value\",\n            value: \"setValue\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-stateKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.variable.path_of_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.variable.available_in_objects\",\n        ),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"globalStateKeyPath\",\n        bindAttrName: [\"globalStateMethod\"],\n        shown: (globalStateMethod) => globalStateMethod === \"setIn\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-stateValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"globalStateValue\",\n        bindAttrName: [\"globalStateMethod\"],\n        shown: (globalStateMethod) =>\n          globalStateMethod === \"setValue\" || globalStateMethod === \"setIn\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-storage-method`,\n        labelName: i18n.t(\"editor.inspect.setter_label.method\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"localStorageMethod\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"setLocalStorage\",\n        options: [\n          {\n            label: \"Clear\",\n            value: \"clear\",\n          },\n          {\n            label: \"Set Value\",\n            value: \"setValue\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-localStorageKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.key\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"localStorageKey\",\n        bindAttrName: [\"localStorageMethod\"],\n        shown: (localStorageMethod) => localStorageMethod === \"setValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-localStorageValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"localStorageValue\",\n        bindAttrName: [\"localStorageMethod\"],\n        shown: (localStorageMethod) => localStorageMethod === \"setValue\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"disabled\",\n        bindAttrName: [\"type\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (type) => type === \"widget\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-script`,\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"script\",\n        bindAttrName: [\"actionType\"],\n        expectedType: VALIDATION_TYPES.STRING,\n        shown: (type) => type === \"script\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-URL`,\n        labelName: \"URL\",\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.table_set_value\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"url\",\n        bindAttrName: [\"actionType\"],\n        expectedType: VALIDATION_TYPES.STRING,\n        shown: (type) => type === \"openUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-newTab`,\n        labelName: i18n.t(\"editor.inspect.setter_label.new_tab\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"newTab\",\n        bindAttrName: [\"actionType\"],\n        useCustomLayout: true,\n        openDynamic: true,\n        shown: (type) => type === \"openUrl\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setCurrentViewKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.key\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"key\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"setCurrentViewKey\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-setCurrentViewIndex`,\n        labelName: i18n.t(\"editor.inspect.setter_label.index\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        attrName: \"index\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"setCurrentViewIndex\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-showNextView`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loop_back_to_start\"),\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"showNextViewLoopBack\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"showNextView\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-showNextVisibleView`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loop_back_to_start\"),\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"showNextVisibleViewLoopBack\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"showNextVisibleView\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-showPreviousView`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loop_start_to_back\"),\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"showPreviousViewLoopBack\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"showPreviousView\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-showPreviousVisibleView`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loop_start_to_back\"),\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"showPreviousVisibleViewLoopBack\",\n        bindAttrName: [\"widgetMethod\"],\n        shown: (type) => type === \"showPreviousVisibleView\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-title`,\n        labelName: i18n.t(\"editor.inspect.setter_label.title\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"title\",\n        bindAttrName: [\"actionType\"],\n        // expectedType: VALIDATION_TYPES.STRING,\n        shown: (type) => type === \"showNotification\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-description`,\n        labelName: i18n.t(\"editor.inspect.setter_label.description\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        // expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"description\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"showNotification\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-notification-type`,\n        labelName: i18n.t(\"editor.inspect.setter_label.type\"),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        attrName: \"notificationType\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"showNotification\",\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.message_type.success\",\n            ),\n            value: \"success\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.message_type.error\",\n            ),\n            value: \"error\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.message_type.warning\",\n            ),\n            value: \"warning\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.message_type.info\",\n            ),\n            value: \"info\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-page`,\n        labelName: i18n.t(\"editor.inspect.setter_label.page\"),\n        setterType: \"EVENT_TARGET_PAGE_SELECT_SETTER\",\n        placeholder: i18n.t(\n          \"editor.inspect.setter_content.select_page_setter.placeholder\",\n        ),\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"pagePath\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"setRouter\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-view-path`,\n        labelName: i18n.t(\"editor.page.label_name.view_path\"),\n        placeholder: i18n.t(\n          \"editor.inspect.setter_content.select_view_setter.placeholder\",\n        ),\n        setterType: \"EVENT_TARGET_VIEW_PATH_SELECT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"viewPath\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"setRouter\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-duration`,\n        labelName: `${i18n.t(\"editor.inspect.setter_label.duration\")}(ms)`,\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"duration\",\n        bindAttrName: [\"actionType\"],\n        expectedType: VALIDATION_TYPES.NUMBER,\n        placeholder: \"{{4500}}\",\n        shown: (type) => type === \"showNotification\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-fileName`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.file_download.file_name\",\n        ),\n        placeholder: i18n.t(\n          \"editor.inspect.setter_placeholder.file_download.file_name\",\n        ),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        // expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"fileName\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"downloadFile\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-fileData`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.file_download.file_data\",\n        ),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.file_download.file_data\"),\n        placeholder: i18n.t(\n          \"editor.inspect.setter_placeholder.file_download.file_data\",\n        ),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        attrName: \"fileData\",\n        bindAttrName: [\"actionType\"],\n        shown: (type) => type === \"downloadFile\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-fileType`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.file_download.file_type\",\n        ),\n        setterType: \"SEARCH_SELECT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"fileType\",\n        bindAttrName: [\"actionType\"],\n        defaultValue: \"auto\",\n        shown: (type) => type === \"downloadFile\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.auto\"),\n            value: \"auto\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.file_download.plain_text\",\n            ),\n            value: \"txt\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.jpeg\"),\n            value: \"jpeg\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.png\"),\n            value: \"png\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.svg\"),\n            value: \"svg\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.json\"),\n            value: \"json\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.csv\"),\n            value: \"csv\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.tsv\"),\n            value: \"tsv\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.file_download.excel\"),\n            value: \"xlsx\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-interaction-event-handler-enabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.only_run_when\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.table_only_run_when\"),\n        setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        attrName: \"enabled\",\n      },\n    ],\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/QRCodeWidget/eventHandlerConfig.ts",
    "content": "import { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const QR_CODE_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [],\n  methods: [\"setValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/QRCodeWidget/index.ts",
    "content": "export { QR_CODE_PANEL_CONFIG } from \"./panelConfig\"\nexport { QR_CODE_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { QR_CODE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/QRCodeWidget/interface.ts",
    "content": "import { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedQRCodeProps extends QRCodeWidgetProps {}\n\nexport interface QRCodeWidgetProps\n  extends BaseWidgetProps,\n    TooltipWrapperProps {\n  value?: unknown\n  bgColorSchema?: string\n  fgColorSchema?: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/QRCodeWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst baseWidgetName = \"qrCode\"\nexport const QR_CODE_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-DefaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-colors-bg-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.background\"),\n            attrName: \"bgColorSchema\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"white\",\n          },\n          {\n            id: `${baseWidgetName}-style-colors-fg-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.qr_code.foreground\"),\n            attrName: \"fgColorSchema\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"black\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/QRCodeWidget/qrCode.tsx",
    "content": "import { QRCodeSVG } from \"qrcode.react\"\nimport { FC, useEffect } from \"react\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { AutoHeightContainer } from \"../PublicSector/AutoHeightContainer\"\nimport { QRCodeWidgetProps } from \"./interface\"\nimport { fullStyle, qrCodeStyle } from \"./style\"\n\nexport const WrappedQRCode: FC<QRCodeWidgetProps> = ({\n  value,\n  bgColorSchema,\n  fgColorSchema,\n}) => {\n  return (\n    <QRCodeSVG\n      value={`${value}`}\n      css={qrCodeStyle}\n      bgColor={bgColorSchema}\n      fgColor={fgColorSchema}\n    />\n  )\n}\n\nWrappedQRCode.displayName = \"WrappedQRCode\"\n\nexport const QRCodeWidget: FC<QRCodeWidgetProps> = (props) => {\n  const {\n    displayName,\n    tooltipText,\n    updateComponentHeight,\n    updateComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    deleteComponentRuntimeProps,\n  } = props\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: unknown) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: `${value}`,\n            },\n          },\n        ])\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    displayName,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n  ])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={fullStyle}>\n          <WrappedQRCode {...props} />\n        </div>\n      </TooltipWrapper>\n    </AutoHeightContainer>\n  )\n}\n\nQRCodeWidget.displayName = \"QRCodeWidget\"\nexport default QRCodeWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/QRCodeWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const fullStyle = css`\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n`\n\nexport const qrCodeStyle = css`\n  width: 100%;\n  height: auto;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/QRCodeWidget/widgetConfig.tsx",
    "content": "import QrCodeWidgetIcon from \"@/assets/widgetCover/qrcode.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const QR_CODE_WIDGET_CONFIG: WidgetConfig = {\n  type: \"QR_CODE_WIDGET\",\n  widgetName: i18n.t(\"widget.qr_code.name\"),\n  displayName: \"qrCode\",\n  w: 8,\n  h: 32,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  icon: <QrCodeWidgetIcon />,\n  keywords: [\"QR code\", \"二维码生成器\"],\n  sessionType: \"PRESENTATION\",\n  version: 0,\n  defaults: {\n    value: \"https://www.illacloud.com\",\n    bgColorSchema: \"white\",\n    fgColorSchema: \"black\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioButtonWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const RADIO_BUTTON_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioButtonWidget/index.tsx",
    "content": "export { RADIO_BUTTON_PANEL_CONFIG } from \"./panelConfig\"\nexport { RADIO_BUTTON_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { RADIO_BUTTON_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioButtonWidget/interface.ts",
    "content": "import { RadioGroupProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedRadioButtonProps\n  extends Pick<\n    RadioGroupProps<any>,\n    \"value\" | \"disabled\" | \"options\" | \"direction\" | \"colorScheme\"\n  > {\n  handleUpdateDsl: (value: any) => void\n  displayName: string\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n}\n\nexport interface RadioButtonWidgetProps\n  extends Omit<WrappedRadioButtonProps, \"handleOnChange\">,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  optionConfigureMode?: \"dynamic\" | \"static\"\n  manualOptions?: {\n    label: string\n    value: string | number\n    disabled?: boolean\n    extra?: any\n  }[]\n  mappedOption?: {\n    labels: string[]\n    values: any[]\n    disables: boolean[]\n  }\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioButtonWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { RADIO_BUTTON_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/RadioButtonWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"radioButton\"\nexport const RADIO_BUTTON_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-options`,\n    groupName: i18n.t(\"editor.inspect.setter_group.options\"),\n    children: [\n      {\n        id: `${baseWidgetName}-options-mode`,\n        attrName: \"optionConfigureMode\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: i18n.t(\"widget.public.select_options.manual\"),\n            value: \"static\",\n          },\n          {\n            label: i18n.t(\"widget.public.select_options.mapped\"),\n            value: \"dynamic\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-options`,\n        useCustomLayout: true,\n        attrName: \"manualOptions\",\n        setterType: \"OPTION_LIST_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => !value || value === \"static\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-options-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"value\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-options-data-sources`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_sources\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        expectedType: VALIDATION_TYPES.ARRAY,\n        shown: (value) => value === \"dynamic\",\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-options-mapped`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedOption\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => value === \"dynamic\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-mappedOption-labels`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"labels\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-values`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"values\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-disables`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disables\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-options-default-value`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          RADIO_BUTTON_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-styles`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioButtonWidget/radioButton.tsx",
    "content": "import { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { RadioGroup } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage/\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { formatSelectOptions } from \"@/widgetLibrary/PublicSector/utils/formatSelectOptions\"\nimport { RadioButtonWidgetProps, WrappedRadioButtonProps } from \"./interface\"\n\nexport const WrappedRadioButton: FC<WrappedRadioButtonProps> = (props) => {\n  const {\n    value,\n    options,\n    disabled,\n    direction,\n    colorScheme,\n    handleOnChange,\n    getValidateMessage,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  } = props\n\n  const changeValue = (value?: number | undefined) => {\n    new Promise((resolve) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value: value || \"\",\n            validateMessage: message,\n          },\n        },\n      ])\n      resolve(true)\n    }).then(() => {\n      handleOnChange?.()\n    })\n  }\n\n  return (\n    <RadioGroup\n      w=\"100%\"\n      minW=\"0\"\n      type=\"button\"\n      forceEqualWidth\n      value={value}\n      disabled={disabled}\n      options={options}\n      direction={direction}\n      colorScheme={colorScheme}\n      onChange={changeValue}\n    />\n  )\n}\n\nWrappedRadioButton.displayName = \"WrappedRadioButton\"\n\nexport const RadioButtonWidget: FC<RadioButtonWidgetProps> = (props) => {\n  const {\n    value,\n    optionConfigureMode,\n    manualOptions,\n    mappedOption,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    customRule,\n    hideValidationMessage,\n    validateMessage,\n    updateComponentHeight,\n    triggerEventHandler,\n  } = props\n\n  const finalOptions = useMemo(() => {\n    return formatSelectOptions(optionConfigureMode, manualOptions, mappedOption)\n  }, [optionConfigureMode, manualOptions, mappedOption])\n\n  const getValidateMessage = useCallback(\n    (value?: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required],\n  )\n\n  const handleValidate = useCallback(\n    (value?: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [getValidateMessage, handleUpdateDsl],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: any) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: undefined })\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {},\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    handleUpdateDsl,\n    deleteComponentRuntimeProps,\n    handleValidate,\n    value,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedRadioButton\n            {...props}\n            options={finalOptions}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      <div\n        css={applyValidateMessageWrapperStyle(\n          labelWidth,\n          labelPosition,\n          labelHidden || !label,\n        )}\n      >\n        <InvalidMessage validateMessage={validateMessage} />\n      </div>\n    </AutoHeightContainer>\n  )\n}\nRadioButtonWidget.displayName = \"RadioButtonWidget\"\nexport default RadioButtonWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioButtonWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport RadioButtonWidgetIcon from \"@/assets/widgetCover/radioButton.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const RADIO_BUTTON_WIDGET_CONFIG: WidgetConfig = {\n  type: \"RADIO_BUTTON_WIDGET\",\n  widgetName: i18n.t(\"widget.radio_button.name\"),\n  displayName: \"radioButton\",\n  w: 9,\n  h: 5,\n  icon: <RadioButtonWidgetIcon />,\n  keywords: [\"Radio Button\", \"按钮单选\"],\n  sessionType: \"SELECT\",\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    optionConfigureMode: \"static\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    manualOptions: [\n      { id: `option-${v4()}`, label: \"Option 1\", value: \"Option 1\" },\n      { id: `option-${v4()}`, label: \"Option 2\", value: \"Option 2\" },\n      { id: `option-${v4()}`, label: \"Option 3\", value: \"Option 3\" },\n    ],\n    dataSources: \"{{[]}}\",\n    colorScheme: \"blue\",\n    hidden: false,\n    formDataKey: \"radioButton\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioGroupWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const RADIO_GROUP_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioGroupWidget/index.tsx",
    "content": "export { RADIO_GROUP_PANEL_CONFIG } from \"./panelConfig\"\nexport { RADIO_GROUP_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { RADIO_GROUP_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioGroupWidget/interface.ts",
    "content": "import { RadioGroupProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedRadioGroupProps\n  extends Pick<\n    RadioGroupProps<any>,\n    \"value\" | \"disabled\" | \"options\" | \"direction\" | \"colorScheme\"\n  > {\n  handleUpdateDsl: (value: any) => void\n  displayName: string\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n}\n\nexport interface RadioGroupWidgetProps\n  extends Omit<WrappedRadioGroupProps, \"handleOnChange\">,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  optionConfigureMode?: \"static\" | \"dynamic\"\n  manualOptions?: {\n    label: string\n    value: string | number\n    disabled?: boolean\n    extra?: any\n  }[]\n  mappedOption?: {\n    labels: string[]\n    values: any[]\n    disables: boolean[]\n  }\n  w: number\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioGroupWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { RADIO_GROUP_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/RadioGroupWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"radio-group\"\nexport const RADIO_GROUP_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-options`,\n    groupName: i18n.t(\"editor.inspect.setter_group.options\"),\n    children: [\n      {\n        id: `${baseWidgetName}-options-mode`,\n        attrName: \"optionConfigureMode\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: i18n.t(\"widget.public.select_options.manual\"),\n            value: \"static\",\n          },\n          {\n            label: i18n.t(\"widget.public.select_options.mapped\"),\n            value: \"dynamic\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-options`,\n        useCustomLayout: true,\n        attrName: \"manualOptions\",\n        setterType: \"OPTION_LIST_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => !value || value === \"static\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-options-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"value\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-option-data-sources`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_sources\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        expectedType: VALIDATION_TYPES.ARRAY,\n        shown: (value) => value === \"dynamic\",\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-options-mapped`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedOption\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => value === \"dynamic\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-mappedOption-labels`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"labels\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-values`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"values\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-disables`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disables\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\", \"labelPosition\"],\n        shown: (hidden, position) => !hidden && position !== \"top\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          RADIO_GROUP_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-style-direction`,\n        labelName: i18n.t(\"editor.inspect.setter_label.group_layout\"),\n        setterType: \"RADIO_GROUP_SETTER\",\n        attrName: \"direction\",\n        options: [\n          {\n            label: \"horizontal\",\n            value: \"horizontal\",\n          },\n          {\n            label: \"vertical\",\n            value: \"vertical\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-styles`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioGroupWidget/radioGroup.tsx",
    "content": "import { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { RadioGroup } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage/\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyCenterLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { formatSelectOptions } from \"@/widgetLibrary/PublicSector/utils/formatSelectOptions\"\nimport { RadioGroupWidgetProps, WrappedRadioGroupProps } from \"./interface\"\n\nexport const WrappedRadioGroup: FC<WrappedRadioGroupProps> = (props) => {\n  const {\n    value,\n    disabled,\n    options,\n    direction,\n    colorScheme,\n    handleOnChange,\n    getValidateMessage,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  } = props\n\n  const changeValue = (value?: unknown) => {\n    new Promise((resolve) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value: value || \"\",\n            validateMessage: message,\n          },\n        },\n      ])\n      resolve(true)\n    }).then(() => {\n      handleOnChange?.()\n    })\n  }\n\n  return (\n    <RadioGroup\n      value={value}\n      disabled={disabled}\n      options={options}\n      direction={direction}\n      colorScheme={colorScheme}\n      onChange={changeValue}\n    />\n  )\n}\n\nWrappedRadioGroup.displayName = \"WrappedRadioGroup\"\n\nexport const RadioGroupWidget: FC<RadioGroupWidgetProps> = (props) => {\n  const {\n    value,\n    optionConfigureMode,\n    manualOptions,\n    mappedOption,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    updateComponentHeight,\n    customRule,\n    hideValidationMessage,\n    validateMessage,\n    triggerEventHandler,\n  } = props\n\n  const finalOptions = useMemo(() => {\n    return formatSelectOptions(optionConfigureMode, manualOptions, mappedOption)\n  }, [optionConfigureMode, manualOptions, mappedOption])\n\n  const getValidateMessage = useCallback(\n    (value?: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required],\n  )\n\n  const handleValidate = useCallback(\n    (value?: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [getValidateMessage, handleUpdateDsl],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: any) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: undefined })\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {},\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    handleUpdateDsl,\n    deleteComponentRuntimeProps,\n    handleValidate,\n    value,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyCenterLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedRadioGroup\n            {...props}\n            options={finalOptions}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nRadioGroupWidget.displayName = \"RadioGroupWidget\"\nexport default RadioGroupWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RadioGroupWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport RadioGroupWidgetIcon from \"@/assets/widgetCover/radioGroup.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const RADIO_GROUP_WIDGET_CONFIG: WidgetConfig = {\n  displayName: \"radioGroup\",\n  type: \"RADIO_GROUP_WIDGET\",\n  widgetName: i18n.t(\"widget.radio_group.name\"),\n  icon: <RadioGroupWidgetIcon />,\n  keywords: [\"Radio Group\", \"单选框组\"],\n  sessionType: \"SELECT\",\n  w: 13,\n  h: 3,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    optionConfigureMode: \"static\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    manualOptions: [\n      { id: `option-${v4()}`, label: \"Option 1\", value: \"Option 1\" },\n      { id: `option-${v4()}`, label: \"Option 2\", value: \"Option 2\" },\n      { id: `option-${v4()}`, label: \"Option 3\", value: \"Option 3\" },\n    ],\n    value: \"Option 1\",\n    direction: \"horizontal\",\n    dataSources: \"{{[]}}\",\n    colorScheme: \"blue\",\n    hidden: false,\n    formDataKey: \"radioButton\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RangeSliderWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const RANGE_SLIDER_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\n    \"setStartOfRange\",\n    \"setEndOfRange\",\n    \"validate\",\n    \"clearValidation\",\n    \"reset\",\n    \"focus\",\n  ],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RangeSliderWidget/index.tsx",
    "content": "export { RANGE_SLIDER_PANEL_CONFIG } from \"./panelConfig\"\nexport { RANGE_SLIDER_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { RANGE_SLIDER_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RangeSliderWidget/interface.ts",
    "content": "import { SliderProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedRangeSliderProps\n  extends Omit<ValidateMessageOldProps, \"value\">,\n    Pick<\n      SliderProps,\n      \"value\" | \"min\" | \"max\" | \"step\" | \"disabled\" | \"colorScheme\"\n    > {\n  startValue: number\n  endValue: number\n  hideOutput: boolean\n  displayName: string\n  validateMessage: string\n  labelWrapping?: boolean\n  prefixIcon?: string\n  suffixIcon?: string\n  required?: boolean\n  handleUpdateValue: (value: any) => void\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n}\n\nexport interface RangeSliderWidgetProps\n  extends WrappedRangeSliderProps,\n    BaseWidgetProps,\n    LabelProps,\n    Omit<TooltipWrapperProps, \"children\"> {\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RangeSliderWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { RANGE_SLIDER_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/RangeSliderWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"rangSlider\"\nexport const RANGE_SLIDER_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-default-start-value`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.range_slider.start_value\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.range_slider.start_value\",\n        ),\n        attrName: \"startValue\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-basic-default-value`,\n        labelName: i18n.t(\"editor.inspect.setter_label.range_slider.end_value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.range_slider.end_value\"),\n        attrName: \"endValue\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-basic-mini-num`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.minimum\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.minimum\"),\n        attrName: \"min\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-maxi-num`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.maximum\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.maximum\"),\n        attrName: \"max\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-step-size`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.step_size\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.step_size\"),\n        attrName: \"step\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.hide_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-allow-wrapping`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.allow_wrapping\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.allow_wrapping\"),\n        attrName: \"labelWrapping\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          RANGE_SLIDER_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-prefix-icon`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.prefix_icon\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.prefix_icon\"),\n        attrName: \"prefixIcon\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"ICON_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-adornments-suffix-icon`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.suffix_icon\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.suffix_icon\"),\n        attrName: \"suffixIcon\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"ICON_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-adornments-hide-output`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.hide_output\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.hide_output\"),\n        attrName: \"hideOutput\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"false\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-colors-theme-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RangeSliderWidget/rangeSlider.tsx",
    "content": "import { FC, forwardRef, useCallback, useEffect, useRef } from \"react\"\nimport { Slider } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage/\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { applyValidateMessageWrapperStyle } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { AllData } from \"../IconWidget/utils\"\nimport { RangeSliderWidgetProps, WrappedRangeSliderProps } from \"./interface\"\nimport {\n  applyIcon,\n  applyLabelAndComponentWrapperStyle,\n  applyWrapperSlider,\n} from \"./style\"\n\nexport const WrappedRangeSlider = forwardRef<\n  HTMLDivElement,\n  WrappedRangeSliderProps\n>((props, ref) => {\n  const {\n    startValue,\n    endValue,\n    prefixIcon,\n    suffixIcon,\n    hideOutput,\n    min,\n    max,\n    handleOnChange,\n    getValidateMessage,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  } = props\n\n  const onChangeSliderValue = useCallback(\n    (value: number | number[]) => {\n      new Promise((resolve) => {\n        const message = getValidateMessage(value)\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              startValue: (value as number[])[0] ?? min ?? 0,\n              endValue: (value as number[])[1] ?? max ?? 10,\n              validateMessage: message,\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        handleOnChange?.()\n      })\n    },\n    [\n      displayName,\n      getValidateMessage,\n      handleOnChange,\n      handleUpdateMultiExecutionResult,\n      max,\n      min,\n    ],\n  )\n  const getIcon = (iconName: string) => (iconName && AllData[iconName]) || null\n  const currentPrefixIcon = getIcon(prefixIcon ?? \"\")\n  const currentSuffixIcon = getIcon(suffixIcon ?? \"\")\n  return (\n    <div css={applyWrapperSlider}>\n      {currentPrefixIcon && (\n        <span css={applyIcon}>\n          {currentPrefixIcon && currentPrefixIcon({})}\n        </span>\n      )}\n      <Slider\n        value={[startValue, endValue]}\n        tooltipVisible={!hideOutput}\n        onChange={onChangeSliderValue}\n        isRange={true}\n        ref={ref}\n        {...props}\n      />\n      {currentSuffixIcon && (\n        <span css={applyIcon}>\n          {currentSuffixIcon && currentSuffixIcon({})}\n        </span>\n      )}\n    </div>\n  )\n})\n\nWrappedRangeSlider.displayName = \"WrappedRangeSlider\"\n\nexport const RangeSliderWidget: FC<RangeSliderWidgetProps> = (props) => {\n  const {\n    startValue,\n    endValue,\n    displayName,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    labelWrapping,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    customRule,\n    hideValidationMessage,\n    validateMessage,\n    updateComponentHeight,\n    triggerEventHandler,\n  } = props\n\n  const rangeSliderRef = useRef<HTMLDivElement>(null)\n  const defaultStartValue = useRef<number>(startValue)\n  const defaultEndValue = useRef<number>(endValue)\n\n  const getValidateMessage = useCallback(\n    (value: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required],\n  )\n\n  const handleValidate = useCallback(\n    (value: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            validateMessage: message || \"\",\n          },\n        },\n      ])\n      return message\n    },\n    [displayName, getValidateMessage, handleUpdateMultiExecutionResult],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setStartOfRange: (startValue: number) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { startValue },\n          },\n        ])\n      },\n      setEndOfRange: (endValue: number) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { endValue },\n          },\n        ])\n      },\n      validate: () => {\n        return handleValidate([\n          {\n            displayName,\n            value: { startValue, endValue },\n          },\n        ])\n      },\n      clearValidation: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              validateMessage: \"\",\n            },\n          },\n        ])\n      },\n      reset: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              startValue: defaultStartValue,\n              endValue: defaultEndValue,\n              validateMessage: \"\",\n            },\n          },\n        ])\n      },\n      focus: () => {\n        rangeSliderRef.current?.focus()\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    displayName,\n    endValue,\n    handleUpdateMultiExecutionResult,\n    handleValidate,\n    startValue,\n    updateComponentRuntimeProps,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div\n          css={applyLabelAndComponentWrapperStyle(\n            labelWrapping ? \"top\" : labelPosition,\n          )}\n        >\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedRangeSlider\n            {...props}\n            startValue={startValue}\n            endValue={endValue}\n            ref={rangeSliderRef}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nRangeSliderWidget.displayName = \"RangeSliderWidget\"\nexport default RangeSliderWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RangeSliderWidget/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\n\nexport const applyLabelAndComponentWrapperStyle = (\n  labelPosition: \"left\" | \"right\" | \"top\" = \"left\",\n): SerializedStyles => {\n  if (labelPosition === \"left\") {\n    return css`\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n    `\n  }\n  if (labelPosition === \"right\") {\n    return css`\n      display: flex;\n      flex-direction: row-reverse;\n      align-items: center;\n      justify-content: space-between;\n    `\n  }\n  return css``\n}\n\nexport const applyWrapperSlider = css`\n  width: 100%;\n  display: flex;\n  flex-direction: row;\n  gap: 8px;\n  padding: 0 8px;\n  align-items: center;\n`\n\nexport const applyIcon = css`\n  height: 16px;\n  width: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RangeSliderWidget/widgetConfig.tsx",
    "content": "import RangeSliderWidgetIcon from \"@/assets/widgetCover/rangeSlider.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const RANGE_SLIDER_WIDGET_CONFIG: WidgetConfig = {\n  type: \"RANGE_SLIDER_WIDGET\",\n  displayName: \"rangeSlider\",\n  widgetName: i18n.t(\"widget.range_slider.name\"),\n  icon: <RangeSliderWidgetIcon />,\n  keywords: [\"Range Slider\", \"范围滑动输入条\"],\n  sessionType: \"INPUTS\",\n  w: 10,\n  h: 10,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    startValue: \"{{3}}\",\n    endValue: \"{{7}}\",\n    min: \"{{0}}\",\n    max: \"{{10}}\",\n    step: \"{{1}}\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    hideOutput: false,\n    disabled: false,\n    colorScheme: \"blue\",\n    hidden: false,\n    formDataKey: \"slider\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RateWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const RATE_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RateWidget/index.tsx",
    "content": "export { RATE_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { RATE_PANEL_CONFIG } from \"./panelConfig\"\nexport { RATE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RateWidget/interface.tsx",
    "content": "import { RateProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedRateProps\n  extends Pick<\n    RateProps,\n    \"allowHalf\" | \"allowClear\" | \"disabled\" | \"readonly\"\n  > {\n  value?: number\n  loading?: boolean\n  icon?: \"star\" | \"heart\"\n  maxCount?: RateProps[\"count\"]\n  handleOnChange?: () => void\n}\n\nexport interface RateWidgetProps\n  extends WrappedRateProps,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    ValidateMessageOldProps {\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RateWidget/panelConfig.tsx",
    "content": "import {\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n  LikeFillIcon,\n  StarFillIcon,\n} from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { RATE_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/RateWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"rate\"\nexport const RATE_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-DefaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-basic-icon`,\n        labelName: i18n.t(\"editor.inspect.setter_label.icon\"),\n        attrName: \"icon\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: <LikeFillIcon />,\n            value: \"heart\",\n          },\n          {\n            label: <StarFillIcon />,\n            value: \"star\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-max-rate`,\n        labelName: i18n.t(\"editor.inspect.setter_label.max_count\"),\n        attrName: \"maxCount\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-basic-allow-half`,\n        labelName: i18n.t(\"editor.inspect.setter_label.allow_half\"),\n        attrName: \"allowHalf\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-allow-clear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.allow_clear\"),\n        attrName: \"allowClear\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: \"select-label-hidden\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          RATE_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readonly\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hidden\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RateWidget/rate.tsx",
    "content": "import { FC, useCallback, useEffect, useRef } from \"react\"\nimport { Rate } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { InvalidMessage } from \"../PublicSector/InvalidMessage\"\nimport { handleValidateCheck } from \"../PublicSector/InvalidMessage/utils\"\nimport { RateWidgetProps, WrappedRateProps } from \"./interface\"\nimport { rateStyle } from \"./style\"\n\nexport const WrappedRate: FC<WrappedRateProps> = (props) => {\n  const {\n    value,\n    allowClear,\n    disabled,\n    icon,\n    readonly,\n    allowHalf,\n    maxCount,\n    handleOnChange,\n  } = props\n\n  return (\n    <Rate\n      css={rateStyle}\n      count={maxCount}\n      allowHalf={allowHalf}\n      heart={icon === \"heart\"}\n      disabled={disabled}\n      readonly={readonly}\n      allowClear={allowClear}\n      value={value}\n      onChange={handleOnChange}\n    />\n  )\n}\n\nWrappedRate.displayName = \"WrappedRate\"\n\nexport const RateWidget: FC<RateWidgetProps> = (props) => {\n  const {\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    hideValidationMessage,\n    validateMessage,\n    customRule,\n    value,\n    updateComponentHeight,\n    triggerEventHandler,\n  } = props\n\n  const triggerRef = useRef<HTMLDivElement>(null)\n  const getValidateMessage = useCallback(\n    (value?: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required],\n  )\n\n  const handleValidate = useCallback(\n    (value?: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [getValidateMessage, handleUpdateDsl],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: number) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: 0 })\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {\n        handleUpdateDsl({\n          validateMessage: \"\",\n        })\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    handleUpdateDsl,\n    deleteComponentRuntimeProps,\n    handleValidate,\n    value,\n  ])\n\n  const handleOnChange = useCallback(\n    (value?: string) => {\n      new Promise((resolve) => {\n        const validateMessage = getValidateMessage(value)\n        handleUpdateDsl({ value, validateMessage })\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"change\")\n      })\n    },\n    [getValidateMessage, handleUpdateDsl, triggerEventHandler],\n  )\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div\n          css={applyLabelAndComponentWrapperStyle(labelPosition)}\n          ref={triggerRef}\n        >\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedRate {...props} handleOnChange={handleOnChange} />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nRateWidget.displayName = \"RateWidget\"\nexport default RateWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RateWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const rateStyle = css`\n  overflow: hidden;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RateWidget/widgetConfig.tsx",
    "content": "import RateWidgetIcon from \"@/assets/widgetCover/rate.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const RATE_WIDGET_CONFIG: WidgetConfig = {\n  type: \"RATE_WIDGET\",\n  displayName: \"rate\",\n  widgetName: i18n.t(\"widget.rate.name\"),\n  icon: <RateWidgetIcon />,\n  keywords: [\"Rate\", \"评分\"],\n  sessionType: \"PRESENTATION\",\n  w: 6,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    value: \"{{4}}\",\n    allowHalf: true,\n    maxCount: \"{{5}}\",\n    icon: \"star\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    hidden: false,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/baseRecord.tsx",
    "content": "import { FC, useEffect, useRef, useState } from \"react\"\nimport { Button } from \"@illa-design/react\"\nimport { WrappedAudio } from \"@/widgetLibrary/AudioWidget/audio\"\nimport {\n  DefaultClearText,\n  DefaultStartText,\n  DefaultStopText,\n  RecordPermission,\n} from \"@/widgetLibrary/RecordingWidget/constants\"\nimport { BaseAudioRecorder } from \"@/widgetLibrary/RecordingWidget/interface\"\nimport {\n  applyContainerStyle,\n  applyPreviewStyle,\n  applyTextButtonStyle,\n  audioContainerStyle,\n} from \"@/widgetLibrary/RecordingWidget/style\"\nimport { useHandleRecord } from \"@/widgetLibrary/RecordingWidget/useHandleRecord\"\nimport { getsSafeNodeValue } from \"@/widgetLibrary/RecordingWidget/utils\"\n\nexport const BaseRecorder: FC<BaseAudioRecorder> = (props) => {\n  const {\n    value,\n    loading = false,\n    disabled = false,\n    startText,\n    stopText,\n    clearText,\n    colorScheme = \"blue\",\n    handleUpdateStatus,\n    handleOnChange,\n  } = props\n  const permissionStatus = useRef<PermissionStatus | null>()\n  const [permissionDisabled, setPermissionDisabled] = useState<boolean>(true)\n\n  const { isRecording, url, recordingTime, handleButtonClick, clearData } =\n    useHandleRecord(handleUpdateStatus, handleOnChange)\n\n  const emptyFun = () => undefined\n\n  useEffect(() => {\n    const handlePermissionChange = (event: Event) => {\n      const result = event.target as PermissionStatus\n      if (result.state === \"granted\" || result.state === \"prompt\") {\n        handleUpdateStatus({ validateMessage: \"\" })\n        setPermissionDisabled(false)\n      } else if (result.state === \"denied\") {\n        handleUpdateStatus({ validateMessage: RecordPermission })\n        setPermissionDisabled(true)\n      }\n    }\n\n    navigator?.permissions\n      ?.query({ name: \"microphone\" as PermissionName })\n      .then((status) => {\n        permissionStatus.current = status\n        if (status.state === \"granted\" || status.state === \"prompt\") {\n          setPermissionDisabled(false)\n        } else if (status.state === \"denied\") {\n          handleUpdateStatus({\n            validateMessage: RecordPermission,\n          })\n          setPermissionDisabled(true)\n        }\n        status.addEventListener(\"change\", handlePermissionChange)\n      })\n\n    return () => {\n      permissionStatus.current?.removeEventListener(\n        \"change\",\n        handlePermissionChange,\n      )\n    }\n  }, [handleUpdateStatus])\n\n  useEffect(() => {\n    handleUpdateStatus({ isRecording })\n  }, [handleUpdateStatus, isRecording])\n\n  return (\n    <div css={applyContainerStyle}>\n      {!url && !value && (\n        <Button\n          onClick={handleButtonClick}\n          disabled={permissionDisabled || disabled}\n          loading={loading}\n          colorScheme={colorScheme}\n          size=\"large\"\n          w=\"100%\"\n        >\n          {!isRecording\n            ? getsSafeNodeValue(startText || DefaultStartText)\n            : `${getsSafeNodeValue(\n                stopText || DefaultStopText,\n              )} ${recordingTime.toFixed(1)}s`}\n        </Button>\n      )}\n      {(url || value) && !isRecording && (\n        <div css={applyPreviewStyle}>\n          <Button\n            onClick={clearData}\n            loading={loading}\n            colorScheme=\"grayBlue\"\n            variant=\"text\"\n            css={applyTextButtonStyle}\n          >\n            {getsSafeNodeValue(clearText || DefaultClearText)}\n          </Button>\n          <div css={audioContainerStyle}>\n            <WrappedAudio\n              {...props}\n              key={url}\n              url={url || value}\n              controls={true}\n              onPlay={emptyFun}\n              onPause={emptyFun}\n              onEnded={emptyFun}\n              onReady={emptyFun}\n              onPlaybackRateChange={emptyFun}\n            />\n          </div>\n        </div>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/constants.ts",
    "content": "import i18n from \"@/i18n/config\"\n\nexport const DefaultStartText = i18n.t(\n  \"editor.inspect.setter_default_value.recording.start_button_text\",\n)\nexport const DefaultStopText = i18n.t(\n  \"editor.inspect.setter_default_value.recording.stop_button_text\",\n)\nexport const DefaultClearText = i18n.t(\n  \"editor.inspect.setter_default_value.recording.clear_button_text\",\n)\nexport const RecordPermission = i18n.t(\n  \"editor.inspect.setter_message.recording.recording_permission\",\n)\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const RECORDING_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/index.tsx",
    "content": "export { RECORDING_PANEL_CONFIG } from \"./panelConfig\"\nexport { RECORDING_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { RECORDING_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/interface.ts",
    "content": "import { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface BaseAudioRecorder extends BaseWidgetProps {\n  value?: string\n  data?: string\n  isRecording?: boolean\n  loading?: boolean\n  disabled?: boolean\n  startText?: string\n  stopText?: string\n  clearText?: string\n  minDuration?: number\n  maxDuration?: number\n  colorScheme?: string\n  recordTime?: number\n  updateRecordTime: (time: number) => void\n  updateRecording: (status: boolean) => void\n  handleUpdateStatus: (value: Record<string, any>) => void\n  handleOnChange?: (value: string) => void\n}\n\nexport interface WrappedAudioRecorderProps extends BaseAudioRecorder {}\n\nexport interface AudioRecorderWidgetProps\n  extends WrappedAudioRecorderProps,\n    Omit<TooltipWrapperProps, \"children\">,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { RECORDING_HANDLER_CONFIG } from \"@/widgetLibrary/RecordingWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"recording\"\nexport const RECORDING_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          RECORDING_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-loading`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n        attrName: \"loading\",\n        placeholder: \"{{false}}\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"submit\"],\n        shown: (value) => {\n          return !value\n        },\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-start-text`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.recording.start_button_text\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.recording.start_button_text\",\n        ),\n        attrName: \"startText\",\n        isSetterSingleRow: true,\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-adornments-stop-text`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.recording.stop_button_text\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.recording.stop_button_text\",\n        ),\n        attrName: \"stopText\",\n        isSetterSingleRow: true,\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-adornments-clear-text`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.recording.clear_button_text\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.recording.clear_button_text\",\n        ),\n        attrName: \"clearText\",\n        isSetterSingleRow: true,\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-min-duration`,\n        labelName: i18n.t(\"editor.inspect.setter_label.recording.min_duration\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.recording.min_duration\"),\n        isSetterSingleRow: true,\n        attrName: \"minDuration\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{0}}\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-max-duration`,\n        labelName: i18n.t(\"editor.inspect.setter_label.recording.max_duration\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.recording.max_duration\"),\n        isSetterSingleRow: true,\n        attrName: \"maxDuration\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{10000}}\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"false\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-colors-theme-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/recording.tsx",
    "content": "import { FC, forwardRef, useCallback, useEffect } from \"react\"\nimport { useMessage } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { BaseRecorder } from \"@/widgetLibrary/RecordingWidget/baseRecord\"\nimport {\n  AudioRecorderWidgetProps,\n  WrappedAudioRecorderProps,\n} from \"@/widgetLibrary/RecordingWidget/interface\"\nimport { getDataFromVal } from \"@/widgetLibrary/RecordingWidget/utils\"\n\nexport const WrappedRecording = forwardRef<\n  HTMLDivElement,\n  WrappedAudioRecorderProps\n>((props, ref) => {\n  return (\n    <div ref={ref}>\n      <BaseRecorder {...props} />\n    </div>\n  )\n})\n\nWrappedRecording.displayName = \"WrappedRecording\"\n\nexport const RecordingWidget: FC<AudioRecorderWidgetProps> = (props) => {\n  const {\n    displayName,\n    minDuration,\n    maxDuration,\n    required,\n    value,\n    isRecording,\n    recordTime,\n    tooltipText,\n    customRule,\n    hideValidationMessage,\n    validateMessage,\n    triggerEventHandler,\n    updateComponentHeight,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n  } = props\n\n  const messageModal = useMessage()\n\n  const getValidateMessage = useCallback(() => {\n    if (!hideValidationMessage) {\n      let message: string | undefined\n      if (value && !recordTime) {\n        message = handleValidateCheck({\n          value,\n          customRule,\n        })\n      } else if (!value && !recordTime) {\n        message = handleValidateCheck({\n          value: undefined,\n          required,\n          customRule,\n        })\n      } else {\n        message = handleValidateCheck({\n          value: recordTime,\n          required,\n          maxDuration: maxDuration ?? 10000,\n          minDuration: minDuration ?? 0,\n          customRule,\n        })\n      }\n      const showMessage = message && message.length > 0\n      return showMessage ? message : \"\"\n    }\n    return \"\"\n  }, [\n    customRule,\n    hideValidationMessage,\n    maxDuration,\n    minDuration,\n    recordTime,\n    required,\n    value,\n  ])\n\n  const handleValidate = useCallback(() => {\n    const message = getValidateMessage()\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          validateMessage: message,\n        },\n      },\n    ])\n    return message\n  }, [displayName, getValidateMessage, handleUpdateMultiExecutionResult])\n\n  const handleOnChange = useCallback(\n    (value: string) => {\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: getDataFromVal(value),\n              dataURI: value,\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"change\")\n      })\n    },\n    [displayName, handleUpdateMultiExecutionResult, triggerEventHandler],\n  )\n\n  const handleUpdateStatus = useCallback(\n    (value: Record<string, number | string>) => {\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value,\n        },\n      ])\n    },\n    [displayName, handleUpdateMultiExecutionResult],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      clearValue: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: undefined,\n            },\n          },\n        ])\n      },\n      validate: () => {\n        return handleValidate()\n      },\n      clearValidation: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              validateMessage: undefined,\n            },\n          },\n        ])\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleValidate,\n    handleUpdateMultiExecutionResult,\n    displayName,\n    value,\n    recordTime,\n    isRecording,\n    messageModal,\n  ])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <WrappedRecording\n          {...props}\n          handleOnChange={handleOnChange}\n          handleUpdateStatus={handleUpdateStatus}\n          handleUpdateMultiExecutionResult={handleUpdateMultiExecutionResult}\n        />\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div>\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nRecordingWidget.displayName = \"RecordingWidget\"\nexport default RecordingWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const applyPreviewStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  gap: 15px;\n  height: 100%;\n  width: 100%;\n`\n\nexport const audioContainerStyle = css`\n  width: 100%;\n  height: 45px;\n`\n\nexport const applyContainerStyle = css`\n  flex-direction: row;\n  align-items: center;\n  gap: 15px;\n  height: 100%;\n  width: 100%;\n  box-sizing: border-box;\n`\n\nexport const applyTextButtonStyle = css`\n  &:hover,\n  &:active {\n    background-color: transparent !important;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/useHandleRecord.ts",
    "content": "import { useCallback, useEffect, useRef, useState } from \"react\"\nimport { setInternalByTimeout } from \"./utils\"\n\nexport const useHandleRecord = (\n  handleUpdateStatus: (value: Record<string, any>) => void,\n  handleOnChange: ((value: string) => void) | undefined,\n) => {\n  const [isRecording, setIsRecording] = useState<boolean>(false)\n  const startTime = useRef<number | undefined>()\n  const [recordingTime, setRecordingTime] = useState<number>(0)\n  const cancelTimer = useRef<() => void>()\n  const chunks = useRef<Blob[]>([])\n  const recorder = useRef<MediaRecorder | null>(null)\n  const stream = useRef<MediaStream | null>(null)\n  const [url, setUrl] = useState<string>()\n  const startRecordFnRef = useRef<() => void>()\n  const dataRecordFnRef = useRef<(e: BlobEvent) => void>()\n  const stopRecordFnRef = useRef<() => void>()\n\n  const handleButtonClick = useCallback(async () => {\n    cancelTimer.current && cancelTimer.current()\n    if (isRecording && recorder.current) {\n      recorder.current.stop()\n      handleUpdateStatus({ recordTime: parseFloat(recordingTime.toFixed(1)) })\n      setIsRecording(false)\n    } else {\n      try {\n        recorder.current = null\n        stream.current = await navigator.mediaDevices.getUserMedia({\n          audio: true,\n        })\n        const currentRecorder = new MediaRecorder(stream.current)\n        startRecordFnRef.current = () => {\n          startTime.current = window.performance.now()\n          cancelTimer.current = setInternalByTimeout(() => {\n            const now = window.performance.now()\n            const value = (now - (startTime.current as number)) / 1000\n            setRecordingTime(value)\n          }, 100)\n        }\n        dataRecordFnRef.current = (e) => {\n          chunks.current.push(e.data)\n        }\n        stopRecordFnRef.current = async () => {\n          if (stream.current) {\n            await stream.current.getTracks().forEach((track) => track.stop())\n          }\n          const audioBlob = new Blob(chunks.current, {\n            type: currentRecorder.mimeType,\n          })\n          const url = URL.createObjectURL(audioBlob)\n          setUrl(url)\n          var reader = new FileReader()\n          reader.onload = function (e) {\n            const data = e.target?.result\n            if (data && typeof data === \"string\") {\n              handleOnChange && handleOnChange(data || \"\")\n            }\n          }\n          reader.readAsDataURL(audioBlob)\n          if (recorder.current) {\n            startRecordFnRef.current &&\n              recorder.current.removeEventListener(\n                \"start\",\n                startRecordFnRef.current,\n              )\n            dataRecordFnRef.current &&\n              recorder.current.removeEventListener(\n                \"dataavailable\",\n                dataRecordFnRef.current,\n              )\n            stopRecordFnRef.current &&\n              recorder.current.removeEventListener(\n                \"stop\",\n                stopRecordFnRef.current,\n              )\n          }\n          stream.current = null\n          recorder.current = null\n        }\n        currentRecorder.addEventListener(\"start\", startRecordFnRef.current)\n\n        currentRecorder.addEventListener(\n          \"dataavailable\",\n          dataRecordFnRef.current,\n        )\n\n        currentRecorder.addEventListener(\"stop\", stopRecordFnRef.current)\n\n        currentRecorder.start()\n        recorder.current = currentRecorder\n        setIsRecording(true)\n      } catch (error) {\n        console.log(error)\n      }\n    }\n  }, [handleOnChange, handleUpdateStatus, isRecording, recordingTime])\n\n  const clearData = () => {\n    chunks.current = []\n    url && URL.revokeObjectURL(url)\n    setUrl(\"\")\n    setRecordingTime(0)\n    handleUpdateStatus({ recordTime: 0 })\n    handleOnChange && handleOnChange(\"\")\n  }\n\n  useEffect(() => {\n    return () => {\n      cancelTimer.current && cancelTimer.current()\n      if (recorder.current && recorder.current.state !== \"inactive\") {\n        recorder.current.stop()\n      }\n      if (stream.current) {\n        stream.current.getTracks()?.forEach((track) => track.stop())\n      }\n    }\n  }, [stream, recorder])\n\n  return {\n    isRecording,\n    url,\n    recordingTime,\n    handleButtonClick,\n    clearData,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/utils.ts",
    "content": "type TimerId = ReturnType<typeof setTimeout>\nexport const setInternalByTimeout = (\n  callback: () => void,\n  interval: number,\n) => {\n  let startTime = Date.now()\n  let timerId: TimerId\n  const deviation = 50\n  function run() {\n    const expected = startTime + interval\n    const drift = Date.now() - expected\n    if (drift > deviation) {\n      startTime = Date.now() + drift\n    } else {\n      startTime += interval\n    }\n    callback()\n    timerId = setTimeout(run, Math.max(0, interval - drift))\n  }\n  timerId = setTimeout(run, interval)\n  return () => {\n    clearTimeout(timerId)\n  }\n}\n\nexport const getsSafeNodeValue = (val: unknown) => {\n  return typeof val === \"string\" ? val : \"\"\n}\n\nexport const getDataFromVal = (val: unknown) => {\n  const rep = /^data:audio[^,]+base64,/\n  if (typeof val !== \"string\" || !val || !rep.test(val)) {\n    return \"\"\n  } else {\n    return val.replace(rep, \"\")\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RecordingWidget/widgetConfig.tsx",
    "content": "import RecordingWidgetIcon from \"@/assets/widgetCover/recording.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport {\n  DefaultClearText,\n  DefaultStartText,\n  DefaultStopText,\n} from \"@/widgetLibrary/RecordingWidget/constants\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const RECORDING_WIDGET_CONFIG: WidgetConfig = {\n  type: \"RECORDING_WIDGET\",\n  displayName: \"recording\",\n  widgetName: i18n.t(\"widget.recording.name\"),\n  icon: <RecordingWidgetIcon />,\n  keywords: [\"Recording\", \"录音\"],\n  sessionType: \"INPUTS\",\n  w: 10,\n  h: 7,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    value: \"\",\n    dataURI: \"\",\n    isRecording: false,\n    recordTime: 0,\n    maxDuration: \"{{10000}}\",\n    minDuration: \"{{0}}\",\n    formDataKey: \"recording\",\n    startText: DefaultStartText,\n    stopText: DefaultStopText,\n    clearText: DefaultClearText,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RichTextWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const RICH_TEXT_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"focus\", \"renderEditor\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RichTextWidget/index.ts",
    "content": "export { RICH_TEXT_PANEL_CONFIG } from \"./panelConfig\"\nexport { RICH_TEXT_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { RICH_TEXT_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RichTextWidget/interface.ts",
    "content": "import { OutputData } from \"@editorjs/editorjs\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface BaseRichTextProps extends BaseWidgetProps {\n  defaultText?: string\n  handleOnChange: (value: unknown) => void\n  handleMdValue: (value: unknown) => void\n}\n\nexport interface RichTextWidgetProps\n  extends BaseRichTextProps,\n    Pick<TooltipWrapperProps, \"tooltipText\"> {}\n\nexport interface ICustomRef {\n  focus: () => void\n  render: (value: OutputData) => void\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RichTextWidget/panelConfig.tsx",
    "content": "import RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { RICH_TEXT_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/RichTextWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"richText\"\nexport const RICH_TEXT_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-default-text`,\n        labelName: i18n.t(\"editor.inspect.setter_label.rich_text.default_text\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_hover.rich_text.default_text\"),\n        attrName: \"defaultText\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          RICH_TEXT_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-styles`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"border\",\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-shadow`,\n            labelName: i18n.t(\"editor.inspect.setter_label.shadow.shadow\"),\n            attrName: \"shadow\",\n            setterType: \"SHADOW_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"small\",\n          },\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            attrName: \"radius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RichTextWidget/richText.tsx",
    "content": "import { OutputData } from \"@editorjs/editorjs\"\nimport { FC, forwardRef, useCallback, useEffect, useRef } from \"react\"\nimport { v4 } from \"uuid\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  BaseRichTextProps,\n  ICustomRef,\n  RichTextWidgetProps,\n} from \"@/widgetLibrary/RichTextWidget/interface\"\nimport {\n  containerStyle,\n  editorContainerStyle,\n  editorStyle,\n} from \"@/widgetLibrary/RichTextWidget/style\"\nimport { useInitConfig } from \"@/widgetLibrary/RichTextWidget/useInitConfig\"\n\nconst WrappedRichText = forwardRef<ICustomRef, BaseRichTextProps>(\n  (props, ref) => {\n    const { defaultText, handleOnChange, handleMdValue } = props\n    const uniqueId = useRef(v4())\n    useInitConfig(\n      defaultText ?? \"\",\n      handleOnChange,\n      handleMdValue,\n      ref,\n      uniqueId.current,\n    )\n    return (\n      <div css={editorContainerStyle}>\n        <div\n          id={uniqueId.current}\n          onMouseMoveCapture={(e) => e.stopPropagation()}\n          css={editorStyle}\n        />\n      </div>\n    )\n  },\n)\n\nWrappedRichText.displayName = \"WrappedRichText\"\n\nexport const RichTextWidget: FC<RichTextWidgetProps> = (props) => {\n  const {\n    displayName,\n    tooltipText,\n    deleteComponentRuntimeProps,\n    updateComponentRuntimeProps,\n    triggerEventHandler,\n    handleUpdateMultiExecutionResult,\n  } = props\n\n  const editorRef = useRef<ICustomRef>(null)\n  const containerRef = useRef<HTMLDivElement>(null)\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      focus: () => {\n        editorRef.current?.focus()\n      },\n      renderEditor: (block: string) => {\n        try {\n          const blockValue: OutputData = JSON.parse(block || \"{}\")\n          editorRef.current?.render(blockValue)\n        } catch (e) {}\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  ])\n\n  const handleOnChange = useCallback(\n    (value: unknown) => {\n      if (!Array.isArray(value)) return\n      const [htmlValue, blockValue] = value\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: htmlValue,\n              blockValue: JSON.stringify(blockValue),\n            },\n          },\n        ])\n        resolve(value)\n      }).then(() => {\n        triggerEventHandler(\"change\")\n      })\n    },\n    [displayName, handleUpdateMultiExecutionResult, triggerEventHandler],\n  )\n\n  const handleMdValue = useCallback(\n    (value: unknown) => {\n      if (typeof value !== \"string\") return\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            markdownValue: value,\n          },\n        },\n      ])\n    },\n    [displayName, handleUpdateMultiExecutionResult],\n  )\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div ref={containerRef} css={containerStyle}>\n        <WrappedRichText\n          {...props}\n          ref={editorRef}\n          handleOnChange={handleOnChange}\n          handleMdValue={handleMdValue}\n        />\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nRichTextWidget.displayName = \"RichTextWidget\"\nexport default RichTextWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RichTextWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const containerStyle = css`\n  height: 100%;\n  width: 100%;\n  overflow: hidden;\n`\nexport const editorContainerStyle = css`\n  height: 100%;\n  width: 100%;\n  padding: 24px 60px;\n  overflow: auto;\n`\nexport const editorStyle = css`\n  width: 100%;\n  .codex-editor__redactor {\n    padding-bottom: 0 !important;\n  }\n  .ce-block__content {\n    width: 100%;\n    margin: 0;\n    max-width: 100%;\n    & * {\n      cursor: text;\n    }\n  }\n  .ce-toolbar__content {\n    width: 100%;\n    max-width: 100%;\n  }\n  .tc-add-column,\n  .tc-add-row {\n    display: none;\n  }\n  .tc-row:after {\n    height: 0px;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RichTextWidget/useInitConfig.ts",
    "content": "import CheckList from \"@editorjs/checklist\"\nimport Code from \"@editorjs/code\"\nimport EditorJS, { OutputData } from \"@editorjs/editorjs\"\nimport Embed from \"@editorjs/embed\"\nimport Header from \"@editorjs/header\"\nimport Image from \"@editorjs/image\"\nimport InlineCode from \"@editorjs/inline-code\"\nimport List from \"@editorjs/list\"\nimport Marker from \"@editorjs/marker\"\nimport parser from \"editorjs-html\"\nimport { MDfromBlocks } from \"editorjs-md-parser\"\nimport { ForwardedRef, useEffect, useImperativeHandle, useRef } from \"react\"\nimport { ICustomRef } from \"@/widgetLibrary/RichTextWidget/interface\"\nimport { handleImageUpload, parseCheckList } from \"./utils\"\n\nexport const useInitConfig = (\n  defaultText: string,\n  handleOnChange: (value: unknown) => void,\n  handleMdValue: (value: unknown) => void,\n  ref: ForwardedRef<ICustomRef>,\n  id: string,\n) => {\n  const editorRef = useRef<EditorJS | null>(null)\n\n  useImperativeHandle(ref, () => ({\n    focus: () => {\n      editorRef.current?.focus(true)\n    },\n    render: (value: OutputData) => {\n      editorRef.current?.render(value)\n    },\n  }))\n\n  useEffect(() => {\n    if (!editorRef.current) {\n      const editorInstance = new EditorJS({\n        holder: id,\n        placeholder: defaultText,\n        tools: {\n          header: {\n            class: Header,\n            inlineToolbar: true,\n          },\n          code: Code,\n          list: {\n            class: List,\n            inlineToolbar: true,\n          },\n          checklist: {\n            class: CheckList,\n            inlineToolbar: true,\n          },\n          image: {\n            class: Image,\n            config: {\n              uploader: {\n                uploadByFile(file: Blob) {\n                  return handleImageUpload(file).then((data) => {\n                    return {\n                      success: 1,\n                      file: {\n                        url: data,\n                      },\n                    }\n                  })\n                },\n              },\n            },\n          },\n          marker: {\n            class: Marker,\n            inlineToolbar: true,\n          },\n          inlineCode: {\n            class: InlineCode,\n            inlineToolbar: true,\n          },\n          embed: Embed,\n        },\n        onChange: async (_) => {\n          const blocks = await _.saver.save()\n          const htmlParser = parser({\n            checklist: parseCheckList,\n          })\n          try {\n            const html = htmlParser.parse(blocks).join(\"\\n\")\n            editorRef.current?.emit(\"change\", [html, blocks])\n            MDfromBlocks(blocks.blocks).then((md) => {\n              editorRef.current?.emit(\"mdValue\", md)\n            })\n          } catch (e) {}\n        },\n      })\n      editorRef.current = editorInstance\n    }\n\n    return () => {\n      if (editorRef.current && editorRef.current.destroy) {\n        editorRef.current.destroy()\n        editorRef.current = null\n      }\n    }\n  }, [defaultText, id])\n\n  useEffect(() => {\n    if (editorRef.current) {\n      editorRef.current.isReady.then(() => {\n        editorRef.current?.on(\"change\", handleOnChange)\n        editorRef.current?.on(\"mdValue\", handleMdValue)\n      })\n    }\n    return () => {\n      if (editorRef.current) {\n        editorRef.current.isReady.then(() => {\n          editorRef.current?.off(\"change\", handleOnChange)\n          editorRef.current?.off(\"mdValue\", handleMdValue)\n        })\n      }\n    }\n  }, [handleMdValue, handleOnChange])\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RichTextWidget/utils.ts",
    "content": "import { OutputBlockData } from \"@editorjs/editorjs\"\n\nexport const parseCheckList = (block: OutputBlockData) => {\n  const items = block.data.items\n  if (Array.isArray(items) && items.length) {\n    const checkListHtml: string[] = []\n    items.forEach((item: { checked: boolean; text: string }, index) => {\n      const { checked, text } = item\n      checkListHtml.push(`\n          <div class=\"ejs-form-check\">\n            <input\n              type=\"checkbox\"\n              ${checked ? \"checked\" : \"\"}\n              id=\"ejsRadios${index}\"\n            />\n            <label for=\"ejsRadios${index}\">${text}</label>\n          </div>`)\n    })\n    return checkListHtml.join(\"\\n\")\n  }\n}\n\nexport const handleImageUpload = (file: Blob) => {\n  return new Promise(function (resolve, reject) {\n    var reader = new FileReader()\n    reader.onload = function () {\n      return resolve(reader.result)\n    }\n    reader.onerror = reject\n    reader.readAsDataURL(file)\n  })\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/RichTextWidget/widgetConfig.tsx",
    "content": "import RichTextWidgetIcon from \"@/assets/widgetCover/richText.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const RICH_TEXT_WIDGET_CONFIG: WidgetConfig = {\n  version: 0,\n  type: \"RICH_TEXT_WIDGET\",\n  displayName: \"richText\",\n  widgetName: i18n.t(\"widget.rich_text_editor.name\"),\n  icon: <RichTextWidgetIcon />,\n  resizeDirection: RESIZE_DIRECTION.ALL,\n  keywords: [\"Rich Text\", \"富文本\"],\n  sessionType: \"INPUTS\",\n  w: 20,\n  h: 55,\n  defaults: {\n    defaultText: i18n.t(\n      \"editor.inspect.setter_default_value.rich_text.default_text\",\n    ),\n    hidden: false,\n    radius: \"4px\",\n    shadow: \"small\",\n    markdownValue: \"\",\n    blockValue: undefined,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SelectWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const SELECT_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.focus\",\n      ),\n      value: \"focus\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.blur\",\n      ),\n      value: \"blur\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SelectWidget/index.tsx",
    "content": "export { SELECT_PANEL_CONFIG } from \"./panelConfig\"\nexport { SELECT_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { SELECT_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SelectWidget/interface.ts",
    "content": "import { SelectProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedSelectProps\n  extends Omit<ValidateMessageOldProps, \"value\">,\n    Pick<\n      SelectProps,\n      | \"options\"\n      | \"value\"\n      | \"placeholder\"\n      | \"disabled\"\n      | \"loading\"\n      | \"readOnly\"\n      | \"showSearch\"\n      | \"colorScheme\"\n    > {\n  showClear?: SelectProps[\"allowClear\"]\n  invalid?: boolean\n  prefixIcon?: string // TODO: not support yet\n  suffixIcon?: string // TODO: not support yet\n  prefixText?: string // TODO: not support yet\n  suffixText?: string // TODO: not support yet\n  displayName: string\n  handleUpdateDsl: (value: any) => void\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n  handleOnBlur?: () => void\n  handleOnFocus?: () => void\n}\n\nexport interface SelectWidgetProps\n  extends WrappedSelectProps,\n    BaseWidgetProps,\n    LabelProps,\n    Omit<TooltipWrapperProps, \"children\"> {\n  optionConfigureMode?: \"dynamic\" | \"static\"\n  manualOptions?: {\n    label: string\n    value: string | number\n    disabled?: boolean\n    extra?: any\n  }[]\n  mappedOption?: {\n    labels: string[]\n    values: any[]\n    disables: boolean[]\n  }\n  validateMessage: string\n  dataSources: unknown[]\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SelectWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { SELECT_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/SelectWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"select\"\nexport const SELECT_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-options`,\n    groupName: i18n.t(\"editor.inspect.setter_group.options\"),\n    children: [\n      {\n        id: `${baseWidgetName}-options-mode`,\n        attrName: \"optionConfigureMode\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: i18n.t(\"widget.public.select_options.manual\"),\n            value: \"static\",\n          },\n          {\n            label: i18n.t(\"widget.public.select_options.mapped\"),\n            value: \"dynamic\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-options`,\n        useCustomLayout: true,\n        attrName: \"manualOptions\",\n        setterType: \"OPTION_LIST_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => !value || value === \"static\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-options-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"value\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-option-data-sources`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_sources\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        expectedType: VALIDATION_TYPES.ARRAY,\n        shown: (value) => value === \"dynamic\",\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-option-mapped`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.map_data_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedOption\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => value === \"dynamic\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-mappedOption-labels`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"labels\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-values`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"values\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-disables`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disables\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"placeholder\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          SELECT_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readOnly\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        attrName: \"showClear\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      //  [TODO] Not need it for now\n      // {\n      //   id: `${baseWidgetName}-adornments-prefixText`,\n      //   labelName: i18n.t(\"editor.inspect.setter_label.prefix_text\"),\n      //   attrName: \"prefixText\",\n      //   setterType: \"INPUT_SETTER\",\n      //   expectedType: VALIDATION_TYPES.STRING,\n      // },\n      // {\n      //   id: `${baseWidgetName}-adornments-suffixText`,\n      //   labelName: i18n.t(\"editor.inspect.setter_label.suffix_text\"),\n      //   attrName: \"suffixText\",\n      //   setterType: \"INPUT_SETTER\",\n      //   expectedType: VALIDATION_TYPES.STRING,\n      // },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"false\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-colors-theme-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SelectWidget/select.tsx",
    "content": "import { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { Select } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage/\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { formatSelectOptions } from \"@/widgetLibrary/PublicSector/utils/formatSelectOptions\"\nimport { SelectWidgetProps, WrappedSelectProps } from \"./interface\"\n\nexport const WrappedSelect: FC<WrappedSelectProps> = (props) => {\n  const {\n    showClear,\n    value,\n    options,\n    placeholder,\n    disabled,\n    loading,\n    readOnly,\n    colorScheme,\n    handleUpdateMultiExecutionResult,\n    handleOnChange,\n    getValidateMessage,\n    displayName,\n  } = props\n\n  const onChangeSelectValue = useCallback(\n    (value: unknown) => {\n      new Promise((resolve) => {\n        const message = getValidateMessage(value)\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: value || \"\",\n              validateMessage: message,\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        handleOnChange?.()\n      })\n    },\n    [\n      displayName,\n      getValidateMessage,\n      handleOnChange,\n      handleUpdateMultiExecutionResult,\n    ],\n  )\n\n  return (\n    <Select\n      allowClear={showClear}\n      options={options}\n      value={typeof value === \"object\" ? JSON.stringify(value) : value}\n      placeholder={placeholder}\n      disabled={disabled}\n      loading={loading}\n      readOnly={readOnly}\n      showSearch\n      colorScheme={colorScheme}\n      onChange={onChangeSelectValue}\n    />\n  )\n}\n\nWrappedSelect.displayName = \"WrappedSelect\"\n\nexport const SelectWidget: FC<SelectWidgetProps> = (props) => {\n  const {\n    value,\n    optionConfigureMode,\n    mappedOption,\n    manualOptions,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    customRule,\n    hideValidationMessage,\n    validateMessage,\n    updateComponentHeight,\n    triggerEventHandler,\n  } = props\n\n  const finalOptions = useMemo(() => {\n    return formatSelectOptions(optionConfigureMode, manualOptions, mappedOption)\n  }, [optionConfigureMode, manualOptions, mappedOption])\n\n  const getValidateMessage = useCallback(\n    (value: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required],\n  )\n\n  const handleValidate = useCallback(\n    (value: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [getValidateMessage, handleUpdateDsl],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: any) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: undefined })\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {},\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    handleUpdateDsl,\n    deleteComponentRuntimeProps,\n    handleValidate,\n    value,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  const handleOnFocus = useCallback(() => {\n    triggerEventHandler(\"focus\")\n  }, [triggerEventHandler])\n\n  const handleOnBlur = useCallback(() => {\n    triggerEventHandler(\"blur\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedSelect\n            {...props}\n            options={finalOptions}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n            handleOnBlur={handleOnBlur}\n            handleOnFocus={handleOnFocus}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\n\nSelectWidget.displayName = \"SelectWidget\"\nexport default SelectWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SelectWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport SelectWidgetIcon from \"@/assets/widgetCover/select.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const SELECT_WIDGET_CONFIG: WidgetConfig = {\n  type: \"SELECT_WIDGET\",\n  displayName: \"select\",\n  widgetName: i18n.t(\"widget.select.name\"),\n  icon: <SelectWidgetIcon />,\n  keywords: [\"Select\", \"选择器\"],\n  sessionType: \"SELECT\",\n  w: 6,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    optionConfigureMode: \"static\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    manualOptions: [\n      { id: `option-${v4()}`, label: \"Option 1\", value: \"Option 1\" },\n      { id: `option-${v4()}`, label: \"Option 2\", value: \"Option 2\" },\n      { id: `option-${v4()}`, label: \"Option 3\", value: \"Option 3\" },\n    ],\n    dataSources: \"{{[]}}\",\n    colorScheme: \"blue\",\n    hidden: false,\n    formDataKey: \"select\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SignatureWidget/constants.ts",
    "content": "export const DPR = window.devicePixelRatio\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SignatureWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const SIGNATURE_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"clearValue\", \"validate\", \"clearValidation\", \"setDisabled\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SignatureWidget/index.tsx",
    "content": "export { SIGNATURE_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { SIGNATURE_PANEL_CONFIG } from \"./panelConfig\"\nexport { SIGNATURE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SignatureWidget/interface.tsx",
    "content": "import { PADDING_MODE } from \"@illa-public/public-types\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedSignatureProps {\n  penColor?: string\n  guideColor?: string\n  text?: string\n  disabled?: boolean\n  value?: string\n  handleUpdateSignature: (value?: string, dataURI?: string) => void\n}\n\nexport interface SignatureWidgetProps\n  extends WrappedSignatureProps,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  validateMessage: string\n  padding?: {\n    size: string\n    mode: PADDING_MODE\n  }\n  backgroundColor?: string\n}\n\nexport interface ICustomRef {\n  clear: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SignatureWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport RadioIcon from \"@/assets/radius-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { SIGNATURE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n\nconst baseWidgetName = \"signature\"\nexport const SIGNATURE_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-Text`,\n        labelName: i18n.t(\"editor.inspect.setter_label.text\"),\n        attrName: \"text\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\", \"labelPosition\"],\n        shown: (hidden, position) => !hidden && position !== \"top\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          SIGNATURE_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        placeholder: \"{{false}}\",\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"submit\"],\n        shown: (value) => !value,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        useCustomLayout: true,\n        attrName: \"hidden\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-styles-border`,\n        setterType: \"BORDER_SETTER\",\n        useCustomLayout: true,\n        attrName: \"border\",\n      },\n      {\n        id: `${baseWidgetName}-styles-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.style\"),\n        attrName: \"style\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.radius\"),\n            attrName: \"radius\",\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            icon: <RadioIcon />,\n            defaultValue: \"4px\",\n          },\n          {\n            id: `${baseWidgetName}-style-shadow`,\n            labelName: i18n.t(\"editor.inspect.setter_label.shadow.shadow\"),\n            attrName: \"shadow\",\n            setterType: \"SHADOW_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"small\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-background`,\n            labelName: i18n.t(\"editor.inspect.setter_label.background\"),\n            attrName: \"backgroundColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"#ffffffff\",\n          },\n          {\n            id: `${baseWidgetName}-style-penColor`,\n            labelName: i18n.t(\"editor.inspect.setter_label.signature.penColor\"),\n            attrName: \"penColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"grayBlue\",\n          },\n          {\n            id: `${baseWidgetName}-style-contentColor`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.signature.contentColor\",\n            ),\n            attrName: \"guideColor\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"grayBlue\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-styles-padding`,\n        setterType: \"PADDING_INPUT_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_group.padding\"),\n        attrName: \"padding\",\n        useCustomLayout: true,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SignatureWidget/signature.tsx",
    "content": "import { FC, useCallback, useEffect, useRef } from \"react\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { ICustomRef, SignatureWidgetProps } from \"./interface\"\nimport SignatureCanvas from \"./signatureCanvas\"\nimport {\n  containerStyle,\n  labelWrapperStyle,\n  validateMessageStyle,\n} from \"./style\"\n\nexport const SignatureWidget: FC<SignatureWidgetProps> = (props) => {\n  const {\n    value,\n    tooltipText,\n    labelWidth = 33,\n    labelAlign,\n    validateMessage,\n    labelHidden,\n    labelPosition,\n    label,\n    hideValidationMessage,\n    labelCaption,\n    required,\n    labelFull,\n    labelWidthUnit,\n    displayName,\n    customRule,\n    padding,\n    backgroundColor,\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n  } = props\n\n  const customRef = useRef<ICustomRef>(null)\n\n  const getValidateMessage = useCallback(\n    (value: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required],\n  )\n\n  const handleValidate = useCallback(\n    (value: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            validateMessage: message,\n          },\n        },\n      ])\n      return message\n    },\n    [displayName, getValidateMessage, handleUpdateMultiExecutionResult],\n  )\n\n  const handleUpdateSignature = (value?: string, dataURI?: string) => {\n    new Promise((resolve) => {\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value,\n            dataURI,\n          },\n        },\n      ])\n      resolve(true)\n    }).then(() => {\n      triggerEventHandler(\"change\")\n    })\n  }\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      clearValue: () => {\n        customRef.current?.clear()\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: undefined,\n              dataURI: undefined,\n            },\n          },\n        ])\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              validateMessage: undefined,\n            },\n          },\n        ])\n      },\n      setDisabled: (disabled?: boolean) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              disabled: disabled,\n            },\n          },\n        ])\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    displayName,\n    handleUpdateMultiExecutionResult,\n    handleValidate,\n    updateComponentRuntimeProps,\n    value,\n  ])\n\n  return (\n    <div css={containerStyle(padding?.size, backgroundColor)}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={labelWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <SignatureCanvas\n            {...props}\n            ref={customRef}\n            handleUpdateSignature={handleUpdateSignature}\n          />\n          {!hideValidationMessage && (\n            <div\n              css={validateMessageStyle(\n                labelWidth,\n                labelPosition,\n                labelHidden || !label,\n              )}\n            >\n              <InvalidMessage validateMessage={validateMessage} />\n            </div>\n          )}\n        </div>\n      </TooltipWrapper>\n    </div>\n  )\n}\n\nSignatureWidget.displayName = \"SignatureWidget\"\nexport default SignatureWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SignatureWidget/signatureCanvas.tsx",
    "content": "import {\n  MouseEvent,\n  TouchEvent,\n  forwardRef,\n  useEffect,\n  useImperativeHandle,\n  useRef,\n  useState,\n} from \"react\"\nimport useMeasure from \"react-use-measure\"\nimport { RefreshIcon, getSpecialThemeColor } from \"@illa-design/react\"\nimport { DPR } from \"./constants\"\nimport { ICustomRef, WrappedSignatureProps } from \"./interface\"\nimport {\n  canvasContainerStyle,\n  canvasStyle,\n  lineStyle,\n  resetIconStyle,\n  signTextStyle,\n} from \"./style\"\n\ninterface SignatureCanvasProps\n  extends Pick<\n    WrappedSignatureProps,\n    | \"disabled\"\n    | \"guideColor\"\n    | \"penColor\"\n    | \"text\"\n    | \"value\"\n    | \"handleUpdateSignature\"\n  > {}\n\nconst SignatureCanvas = forwardRef<ICustomRef, SignatureCanvasProps>(\n  (\n    {\n      value,\n      guideColor = \"grayBlue\",\n      penColor = \"grayBlue\",\n      text,\n      disabled,\n      handleUpdateSignature,\n    },\n    ref,\n  ) => {\n    const [isDrawing, setIsDrawing] = useState(false)\n    const canvasRef = useRef<HTMLCanvasElement>(null)\n    const [boundsRef, bound] = useMeasure()\n    const ctx = useRef<CanvasRenderingContext2D | null>()\n    const startX = useRef(0)\n    const startY = useRef(0)\n\n    useImperativeHandle(ref, () => ({\n      clear: () => handleReset(),\n    }))\n\n    const handleStartDraw = (\n      e: MouseEvent<HTMLCanvasElement> | TouchEvent<HTMLCanvasElement>,\n    ) => {\n      e.stopPropagation()\n      setIsDrawing(true)\n      if (!ctx.current) {\n        ctx.current = canvasRef.current?.getContext(\"2d\")\n      }\n      if (!canvasRef.current || !ctx.current) return\n      if (\"offsetX\" in e.nativeEvent && \"offsetY\" in e.nativeEvent) {\n        startX.current = e.nativeEvent.offsetX\n        startY.current = e.nativeEvent.offsetY\n      } else {\n        const touch = (e as TouchEvent).touches[0]\n        const touchTarget = touch.target as HTMLCanvasElement\n        startX.current =\n          touch.clientX - touchTarget.getBoundingClientRect().left\n        startY.current = touch.clientY - touchTarget.getBoundingClientRect().top\n      }\n      ctx.current.lineWidth = 2 * DPR\n      ctx.current.lineCap = \"round\"\n      ctx.current.strokeStyle = getSpecialThemeColor(penColor)\n      ctx.current.beginPath()\n    }\n\n    const handleDraw = (\n      e: MouseEvent<HTMLCanvasElement> | TouchEvent<HTMLCanvasElement>,\n    ) => {\n      e.stopPropagation()\n      const currentCtx = ctx.current\n      if (!isDrawing || !currentCtx) return\n      let offsetX, offsetY\n      if (\"offsetX\" in e.nativeEvent && \"offsetY\" in e.nativeEvent) {\n        offsetX = e.nativeEvent.offsetX\n        offsetY = e.nativeEvent.offsetY\n      } else {\n        const touch = (e as TouchEvent).touches[0]\n        const touchTarget = touch.target as HTMLCanvasElement\n        offsetX = touch.clientX - touchTarget.getBoundingClientRect().left\n        offsetY = touch.clientY - touchTarget.getBoundingClientRect().top\n      }\n      currentCtx.moveTo(startX.current * DPR, startY.current * DPR)\n      currentCtx.lineTo(offsetX * DPR, offsetY * DPR)\n      startX.current = offsetX\n      startY.current = offsetY\n      currentCtx.stroke()\n    }\n\n    const handleEndDraw = (\n      e: MouseEvent<HTMLCanvasElement> | TouchEvent<HTMLCanvasElement>,\n    ) => {\n      e.stopPropagation()\n      if (!isDrawing) return\n      setIsDrawing(false)\n      ctx.current?.closePath()\n      const data = canvasRef.current?.toDataURL(\"image/png\")\n      const rep = /^data:image\\/png[^,]+base64,/\n      handleUpdateSignature(data, data?.replace(rep, \"\"))\n    }\n\n    const handleReset = () => {\n      if (!ctx.current) return\n      ctx.current.clearRect(\n        0,\n        0,\n        canvasRef.current?.width || 0,\n        canvasRef.current?.height || 0,\n      )\n      handleUpdateSignature()\n    }\n\n    useEffect(() => {\n      const el = canvasRef.current\n      const preventDefault = (e: Event) => {\n        e.preventDefault()\n      }\n      el?.addEventListener(\"touchstart\", preventDefault, { passive: false })\n      return () => {\n        el?.removeEventListener(\"touchstart\", preventDefault)\n      }\n    }, [])\n\n    return (\n      <div css={canvasContainerStyle(disabled)} ref={boundsRef}>\n        {!value && !isDrawing && (\n          <span css={signTextStyle(guideColor)}>{text}</span>\n        )}\n        <RefreshIcon\n          css={resetIconStyle(guideColor)}\n          onClick={handleReset}\n          size=\"16px\"\n        />\n        <canvas\n          ref={canvasRef}\n          css={canvasStyle}\n          width={DPR * bound.width}\n          height={DPR * bound.height}\n          onMouseDownCapture={handleStartDraw}\n          onMouseMoveCapture={handleDraw}\n          onMouseUp={handleEndDraw}\n          onMouseOut={handleEndDraw}\n          onTouchStart={handleStartDraw}\n          onTouchMove={handleDraw}\n          onTouchEnd={handleEndDraw}\n        />\n        <div css={lineStyle(guideColor)} />\n      </div>\n    )\n  },\n)\n\nSignatureCanvas.displayName = \"SignatureCanvas\"\n\nexport default SignatureCanvas\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SignatureWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\nimport { getPaddingShape } from \"@/utils/styleUtils/padding\"\nimport { applyLabelAndComponentWrapperStyle } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\n\nexport const containerStyle = (padding?: string, backgroundColor?: string) => {\n  const paddings = getPaddingShape(padding)\n  return css`\n    width: 100%;\n    height: 100%;\n    overflow: hidden;\n    padding: ${paddings.paddingTop}px ${paddings.paddingRight}px\n      ${paddings.paddingBottom}px ${paddings.paddingLeft}px;\n    background-color: ${backgroundColor};\n  `\n}\n\nexport const labelWrapperStyle = (\n  labelPosition: \"left\" | \"right\" | \"top\" = \"left\",\n) => {\n  const layoutCss = applyLabelAndComponentWrapperStyle(labelPosition)\n  return css`\n    ${layoutCss};\n    display: flex;\n    width: 100%;\n    height: 100%;\n    flex-direction: ${labelPosition === \"top\" ? \"column\" : \"row\"};\n    & label {\n      flex: none;\n    }\n    position: relative;\n  `\n}\n\nexport const canvasContainerStyle = (disabled?: boolean) => css`\n  width: 100%;\n  height: 100%;\n  position: relative;\n  display: flex;\n  flex: 1;\n  overflow: hidden;\n  pointer-events: ${disabled ? \"none\" : \"auto\"};\n  cursor: ${disabled ? \"not-allowed\" : \"auto\"};\n`\n\nexport const canvasStyle = css`\n  width: 100%;\n  height: 100%;\n  cursor: pointer;\n`\n\nexport const signTextStyle = (color: string) => css`\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  color: ${getSpecialThemeColor(color)};\n  font-size: 14px;\n  font-weight: 500;\n  transform: translate(-50%, -50%);\n`\n\nexport const resetIconStyle = (color: string) => css`\n  position: absolute;\n  top: 12px;\n  right: 12px;\n  color: ${getSpecialThemeColor(color)};\n  cursor: pointer;\n`\n\nexport const lineStyle = (color: string) => css`\n  position: absolute;\n  bottom: 32px;\n  width: 100%;\n  height: 2px;\n  background-color: ${getSpecialThemeColor(color)};\n`\n\nexport const validateMessageStyle = (\n  labelWidth: number,\n  labelPosition: \"left\" | \"right\" | \"top\" = \"left\",\n  labelHidden: boolean = false,\n) => {\n  return css`\n    width: 100%;\n    padding-left: ${labelPosition === \"top\" || labelHidden\n      ? 0\n      : `calc(${labelWidth}% + 8px)`};\n    position: absolute;\n    bottom: 0;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SignatureWidget/widgetConfig.tsx",
    "content": "import { PADDING_MODE } from \"@illa-public/public-types\"\nimport SignatureWidgetIcon from \"@/assets/widgetCover/signature.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const SIGNATURE_WIDGET_CONFIG: WidgetConfig = {\n  type: \"SIGNATURE_WIDGET\",\n  displayName: \"signature\",\n  widgetName: i18n.t(\"widget.signature.name\"),\n  keywords: [\"Signature\", \"签名\"],\n  icon: <SignatureWidgetIcon />,\n  sessionType: \"INPUTS\",\n  w: 12,\n  h: 30,\n  version: 0,\n  defaults: {\n    text: \"Sign here\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"top\",\n    labelWidth: \"{{33}}\",\n    padding: {\n      mode: PADDING_MODE.ALL,\n      size: \"8\",\n    },\n    radius: \"4px\",\n    backgroundColor: \"#ffffffff\",\n    shadow: \"none\",\n    formDataKey: \"signature\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SliderWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const SLIDER_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\n    \"setValue\",\n    \"validate\",\n    \"clearValue\",\n    \"clearValidation\",\n    \"reset\",\n    \"focus\",\n  ],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SliderWidget/index.tsx",
    "content": "export { SLIDER_PANEL_CONFIG } from \"./panelConfig\"\nexport { SLIDER_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { SLIDER_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SliderWidget/interface.ts",
    "content": "import { SliderProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedSliderProps\n  extends Omit<ValidateMessageOldProps, \"value\">,\n    Pick<\n      SliderProps,\n      \"value\" | \"min\" | \"max\" | \"step\" | \"disabled\" | \"colorScheme\"\n    > {\n  hideOutput: boolean\n  displayName: string\n  validateMessage: string\n  labelWrapping?: boolean\n  prefixIcon?: string\n  suffixIcon?: string\n  required?: boolean\n  handleOnChange: (value: number | number[]) => void\n}\n\nexport interface SliderWidgetProps\n  extends WrappedSliderProps,\n    BaseWidgetProps,\n    LabelProps,\n    Omit<TooltipWrapperProps, \"children\"> {\n  validateMessage: string\n  value?: number\n  defaultValue?: number\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SliderWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { SLIDER_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/SliderWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"slider\"\nexport const SLIDER_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-default-value`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.default_value\"),\n        attrName: \"defaultValue\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-basic-mini-num`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.minimum\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.minimum\"),\n        attrName: \"min\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-maxi-num`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.maximum\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.maximum\"),\n        attrName: \"max\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-step-size`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.step_size\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.step_size\"),\n        attrName: \"step\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.hide_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-allow-wrapping`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.allow_wrapping\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.allow_wrapping\"),\n        attrName: \"labelWrapping\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          SLIDER_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-prefix-icon`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.prefix_icon\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.prefix_icon\"),\n        attrName: \"prefixIcon\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"ICON_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-adornments-suffix-icon`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.suffix_icon\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.suffix_icon\"),\n        attrName: \"suffixIcon\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"ICON_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-adornments-hide-output`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.hide_output\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.hide_output\"),\n        attrName: \"hideOutput\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"false\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-colors-theme-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SliderWidget/slider.tsx",
    "content": "import { debounce } from \"lodash-es\"\nimport { FC, forwardRef, useCallback, useEffect, useRef, useState } from \"react\"\nimport { Slider } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage/\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { applyValidateMessageWrapperStyle } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { AllData } from \"../IconWidget/utils\"\nimport { SliderWidgetProps, WrappedSliderProps } from \"./interface\"\nimport {\n  applyIcon,\n  applyLabelAndComponentWrapperStyle,\n  applyWrapperSlider,\n} from \"./style\"\nimport { getValidateMessageFunc } from \"./utils\"\n\nexport const WrappedSlider = forwardRef<HTMLDivElement, WrappedSliderProps>(\n  (props, ref) => {\n    const { prefixIcon, suffixIcon, hideOutput, handleOnChange } = props\n\n    const getIcon = (iconName: string) =>\n      (iconName && AllData[iconName]) || null\n    const currentPrefixIcon = getIcon(prefixIcon ?? \"\")\n    const currentSuffixIcon = getIcon(suffixIcon ?? \"\")\n    return (\n      <div css={applyWrapperSlider}>\n        {currentPrefixIcon && (\n          <span css={applyIcon}>\n            {currentPrefixIcon && currentPrefixIcon({})}\n          </span>\n        )}\n        <Slider\n          tooltipVisible={!hideOutput}\n          isRange={false}\n          ref={ref}\n          {...props}\n          onChange={handleOnChange}\n        />\n        {currentSuffixIcon && (\n          <span css={applyIcon}>\n            {currentSuffixIcon && currentSuffixIcon({})}\n          </span>\n        )}\n      </div>\n    )\n  },\n)\n\nWrappedSlider.displayName = \"WrappedSlider\"\n\nexport const SliderWidget: FC<SliderWidgetProps> = (props) => {\n  const {\n    value,\n    min,\n    displayName,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    labelWrapping,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    customRule,\n    hideValidationMessage,\n    validateMessage,\n    defaultValue,\n    updateComponentHeight,\n    triggerEventHandler,\n  } = props\n\n  const sliderRef = useRef<HTMLDivElement>(null)\n  const [sliderValue, setSliderValue] = useState<number | undefined>(\n    defaultValue as number,\n  )\n\n  useEffect(() => {\n    setSliderValue(defaultValue)\n\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          value: defaultValue || \"\",\n        },\n      },\n    ])\n  }, [defaultValue, displayName, handleUpdateMultiExecutionResult])\n\n  const handleValidate = useCallback(\n    (value: number | number[] | undefined) => {\n      const message = getValidateMessageFunc(value, {\n        hideValidationMessage: hideValidationMessage,\n        required: required,\n        customRule: customRule,\n      })\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            validateMessage: message,\n          },\n        },\n      ])\n      return message\n    },\n    [\n      customRule,\n      displayName,\n      handleUpdateMultiExecutionResult,\n      hideValidationMessage,\n      required,\n    ],\n  )\n\n  const debounceOnChange = useRef(\n    debounce(\n      (\n        value: number | undefined,\n        triggerEventHandler: SliderWidgetProps[\"triggerEventHandler\"],\n        options?: {\n          hideValidationMessage?: SliderWidgetProps[\"hideValidationMessage\"]\n          pattern?: SliderWidgetProps[\"pattern\"]\n          regex?: SliderWidgetProps[\"regex\"]\n          required?: SliderWidgetProps[\"required\"]\n          customRule?: SliderWidgetProps[\"customRule\"]\n        },\n      ) => {\n        new Promise((resolve) => {\n          const message = getValidateMessageFunc(value, options)\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                value: value || \"\",\n                validateMessage: message,\n              },\n            },\n          ])\n          resolve(true)\n        }).then(() => {\n          triggerEventHandler(\"change\")\n        })\n      },\n      180,\n    ),\n  )\n\n  const handleOnChange = useCallback(\n    (value: number | number[]) => {\n      setSliderValue(value as number)\n      debounceOnChange.current(value as number, triggerEventHandler, {\n        hideValidationMessage: hideValidationMessage,\n\n        required: required,\n        customRule: customRule,\n      })\n    },\n    [customRule, hideValidationMessage, required, triggerEventHandler],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: number) => {\n        if (typeof value === \"number\") {\n          handleOnChange(value)\n        }\n      },\n      clearValue: () => {\n        handleOnChange(min ?? 0)\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              validateMessage: \"\",\n            },\n          },\n        ])\n      },\n      reset: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { value: defaultValue, validateMessage: \"\" },\n          },\n        ])\n      },\n      focus: () => {\n        sliderRef.current?.focus()\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    defaultValue,\n    deleteComponentRuntimeProps,\n    displayName,\n    handleOnChange,\n    handleUpdateMultiExecutionResult,\n    handleValidate,\n    min,\n    updateComponentRuntimeProps,\n    value,\n  ])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div\n          css={applyLabelAndComponentWrapperStyle(\n            labelWrapping ? \"top\" : labelPosition,\n          )}\n        >\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedSlider\n            {...props}\n            value={sliderValue}\n            ref={sliderRef}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nSliderWidget.displayName = \"SliderWidget\"\nexport default SliderWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SliderWidget/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\n\nexport const applyLabelAndComponentWrapperStyle = (\n  labelPosition: \"left\" | \"right\" | \"top\" = \"left\",\n): SerializedStyles => {\n  if (labelPosition === \"left\") {\n    return css`\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n    `\n  }\n  if (labelPosition === \"right\") {\n    return css`\n      display: flex;\n      flex-direction: row-reverse;\n      align-items: center;\n      justify-content: space-between;\n    `\n  }\n  return css``\n}\n\nexport const applyWrapperSlider = css`\n  width: 100%;\n  display: flex;\n  flex-direction: row;\n  padding: 0 8px;\n  gap: 8px;\n  align-items: center;\n`\n\nexport const applyIcon = css`\n  height: 16px;\n  width: 16px;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SliderWidget/utils.ts",
    "content": "import {\n  getValidateVFromString,\n  handleValidateCheck,\n} from \"../PublicSector/InvalidMessage/utils\"\nimport { SliderWidgetProps } from \"./interface\"\n\nexport const getValidateMessageFunc = (\n  value: number | number[] | undefined,\n  options: {\n    hideValidationMessage?: SliderWidgetProps[\"hideValidationMessage\"]\n    required?: SliderWidgetProps[\"required\"]\n    customRule?: SliderWidgetProps[\"customRule\"]\n  } = {},\n) => {\n  const { hideValidationMessage, required, customRule } = options\n  if (!hideValidationMessage) {\n    const message = handleValidateCheck({\n      value: getValidateVFromString(value),\n      required,\n      customRule,\n    })\n    const showMessage = message && message.length > 0\n    return showMessage ? message : \"\"\n  }\n  return \"\"\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SliderWidget/widgetConfig.tsx",
    "content": "import SliderWidgetIcon from \"@/assets/widgetCover/slider.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const SLIDER_WIDGET_CONFIG: WidgetConfig = {\n  type: \"SLIDER_WIDGET\",\n  displayName: \"slider\",\n  widgetName: i18n.t(\"widget.slider.name\"),\n  icon: <SliderWidgetIcon />,\n  keywords: [\"Slider\", \"滑动输入条\"],\n  sessionType: \"INPUTS\",\n  w: 10,\n  h: 10,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    value: undefined,\n    defaultValue: \"{{2}}\",\n    min: \"{{0}}\",\n    max: \"{{10}}\",\n    step: \"{{1}}\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    hideOutput: false,\n    disabled: false,\n    colorScheme: \"blue\",\n    hidden: false,\n    formDataKey: \"slider\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StatisticsWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const STATISTICS_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.click\",\n      ),\n      value: \"click\",\n    },\n  ],\n  methods: [\"setPrimaryValue\", \"resetPrimaryValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StatisticsWidget/index.tsx",
    "content": "export { STATISTICS_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\nexport { STATISTICS_PANEL_CONFIG } from \"./panelConfig\"\nexport { STATISTICS_WIDGET_CONFIG } from \"./widgetConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StatisticsWidget/interface.ts",
    "content": "import { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedStatisticProps extends BaseWidgetProps {\n  prefixText?: string\n  suffixText?: string\n  primaryValue?: number\n  secondaryValue?: number\n  decimalPlace?: number\n  showTrendSign?: boolean\n  positiveSign?: string\n  negativeSign?: string\n  showSeparator?: boolean\n  enableTrendColor?: boolean\n  secondaryPrefixText?: string\n  secondarySuffixText?: string\n  secondaryDecimalPlace?: number\n  secondaryShowTrendSign?: boolean\n  secondaryPositiveSign?: string\n  secondaryNegativeSign?: string\n  secondaryShowSeparator?: boolean\n  secondaryEnableTrendColor?: boolean\n  textAlign?: \"start\" | \"center\" | \"end\"\n  colorScheme?: string\n  negativeColorScheme?: string\n  label?: string\n  positiveColorScheme?: string\n  handleOnClick?: () => void\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  getValidateMessage: (value: string) => string\n}\n\nexport interface StatisticWidgetProps\n  extends WrappedStatisticProps,\n    BaseWidgetProps,\n    TooltipWrapperProps {\n  label?: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StatisticsWidget/panelConfig.tsx",
    "content": "import {\n  HorizontalCenterIcon,\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n} from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { STATISTICS_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/StatisticsWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"statistic\"\nexport const STATISTICS_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-primaryValue`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.statistics.primary_value\",\n        ),\n        attrName: \"primaryValue\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        isSetterSingleRow: true,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-secondaryValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.secValue\"),\n        attrName: \"secondaryValue\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-primaryValue`,\n    groupName: i18n.t(\"editor.inspect.setter_group.primary_value\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-decimalPlace`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.decimal\"),\n        attrName: \"decimalPlace\",\n        setterType: \"INPUT_SETTER\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.NUMBER,\n        placeholder: i18n.t(\n          \"editor.inspect.setter_placeholder.statistics.decimal\",\n        ),\n      },\n      {\n        id: `${baseWidgetName}-label-showTrendSign`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.trend_sign\"),\n        attrName: \"showTrendSign\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-label-positiveSign`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.statistics.positive_sign\",\n        ),\n        attrName: \"positiveSign\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"ICON_SETTER\",\n        bindAttrName: [\"showTrendSign\"],\n        shown: (value) => value,\n      },\n      {\n        id: `${baseWidgetName}-label-negativeSign`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.statistics.negative_sign\",\n        ),\n        attrName: \"negativeSign\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"ICON_SETTER\",\n        bindAttrName: [\"showTrendSign\"],\n        shown: (value) => value,\n      },\n      {\n        id: `${baseWidgetName}-label-showSeparator`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.statistics.thousand_separator\",\n        ),\n        attrName: \"showSeparator\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-label-enableTrendColor`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.trend_color\"),\n        attrName: \"enableTrendColor\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-label-prefixText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.prefix_text\"),\n        attrName: \"prefixText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        placeholder: i18n.t(\n          \"editor.inspect.setter_placeholder.statistics.prefix_text\",\n        ),\n      },\n      {\n        id: `${baseWidgetName}-label-suffixText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.suffix_text\"),\n        attrName: \"suffixText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        placeholder: i18n.t(\n          \"editor.inspect.setter_placeholder.statistics.suffix_text\",\n        ),\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-secondaryValue`,\n    groupName: i18n.t(\"editor.inspect.setter_group.secondary_value\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-secondaryDecimalPlace`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.decimal\"),\n        attrName: \"secondaryDecimalPlace\",\n        setterType: \"INPUT_SETTER\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.NUMBER,\n        placeholder: i18n.t(\n          \"editor.inspect.setter_placeholder.statistics.decimal\",\n        ),\n      },\n      {\n        id: `${baseWidgetName}-label-secondaryShowTrendSign`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.trend_sign\"),\n        attrName: \"secondaryShowTrendSign\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-label-secondaryPositiveSign`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.statistics.positive_sign\",\n        ),\n        attrName: \"secondaryPositiveSign\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"ICON_SETTER\",\n        bindAttrName: [\"secondaryShowTrendSign\"],\n        shown: (value) => value,\n      },\n      {\n        id: `${baseWidgetName}-label-secondaryNegativeSign`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.statistics.negative_sign\",\n        ),\n        attrName: \"secondaryNegativeSign\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"ICON_SETTER\",\n        bindAttrName: [\"secondaryShowTrendSign\"],\n        shown: (value) => value,\n      },\n      {\n        id: `${baseWidgetName}-label-secondaryShowSeparator`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.statistics.thousand_separator\",\n        ),\n        attrName: \"secondaryShowSeparator\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-label-secondaryEnableTrendColor`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.trend_color\"),\n        attrName: \"secondaryEnableTrendColor\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-label-secondaryPrefixText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.prefix_text\"),\n        attrName: \"secondaryPrefixText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        placeholder: \"US$\",\n      },\n      {\n        id: `${baseWidgetName}-label-secondarySuffixText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.statistics.suffix_text\"),\n        attrName: \"secondarySuffixText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        placeholder: \"%\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          STATISTICS_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-text-align`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"textAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        defaultValue: \"start\",\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"start\",\n          },\n          {\n            label: <HorizontalCenterIcon />,\n            value: \"center\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"end\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        isSetterSingleRow: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-colorScheme`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"grayBlue\",\n          },\n          {\n            id: `${baseWidgetName}-style-positiveColorScheme`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_placeholder.statistics.positive_color\",\n            ),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"positiveColorScheme\",\n            defaultValue: \"green\",\n          },\n          {\n            id: `${baseWidgetName}-style-negativeColorScheme`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_placeholder.statistics.negative_color\",\n            ),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"negativeColorScheme\",\n            defaultValue: \"red\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StatisticsWidget/statistics.tsx",
    "content": "import { FC, useCallback, useEffect, useMemo, useRef } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Statistic } from \"@illa-design/react\"\nimport { getBuilderInfo } from \"@/redux/builderInfo/builderInfoSelector\"\nimport { AllData } from \"@/widgetLibrary/IconWidget/utils\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  StatisticWidgetProps,\n  WrappedStatisticProps,\n} from \"@/widgetLibrary/StatisticsWidget/interface\"\nimport {\n  getPrefixIconStyle,\n  getSecondaryStatisticContainerStyle,\n  getSecondaryStatisticStyle,\n  getStatisticLabelStyle,\n  getStatisticStyle,\n  getStatisticWrapperStyle,\n  getStatisticsContainerStyle,\n  primaryStatisticContainerStyle,\n} from \"@/widgetLibrary/StatisticsWidget/style\"\n\nconst getNumberGroupSeparator = (value: number | undefined, lang: string) => {\n  if (value === undefined) {\n    return \"\"\n  }\n  const numberFormat = new Intl.NumberFormat(lang, {\n    style: \"decimal\",\n  })\n  const parts = numberFormat\n    .formatToParts(value)\n    .filter((part) => part.type === \"group\")\n  return parts[0]?.value ?? \"\"\n}\n\nconst getIcon = (iconName: string) => (iconName && AllData[iconName]) || null\n\nconst getTrendSignAndIcon = (\n  show: boolean,\n  value?: number,\n  positiveSign?: string,\n  negativeSign?: string,\n  color?: string,\n  secondary?: boolean,\n) => {\n  const positiveSignIcon = getIcon(positiveSign ?? \"\")\n  const negativeSignIcon = getIcon(negativeSign ?? \"\")\n  const icon = (value ?? 0) >= 0 ? positiveSignIcon : negativeSignIcon\n\n  return (\n    show &&\n    icon && (\n      <span css={getPrefixIconStyle(color, secondary)}>{icon && icon({})}</span>\n    )\n  )\n}\n\nexport const WrappedStatistic: FC<WrappedStatisticProps> = (props) => {\n  const builderInfo = useSelector(getBuilderInfo)\n  const {\n    label,\n    primaryValue,\n    secondaryValue,\n    decimalPlace,\n    prefixText,\n    suffixText,\n    secondaryPrefixText,\n    secondarySuffixText,\n    showTrendSign,\n    positiveSign,\n    negativeSign,\n    showSeparator,\n    enableTrendColor,\n    secondaryDecimalPlace,\n    secondaryShowTrendSign,\n    secondaryPositiveSign,\n    secondaryNegativeSign,\n    secondaryShowSeparator,\n    secondaryEnableTrendColor,\n    textAlign,\n    handleOnClick,\n    colorScheme,\n    negativeColorScheme,\n    positiveColorScheme,\n  } = props\n\n  const groupSeparator = showSeparator\n    ? getNumberGroupSeparator(primaryValue, builderInfo.language)\n    : \"\"\n  const secondaryGroupSeparator = secondaryShowSeparator\n    ? getNumberGroupSeparator(secondaryValue, builderInfo.language)\n    : \"\"\n\n  const getColor = useCallback(\n    (value?: number, enableTrendColor?: boolean) => {\n      return enableTrendColor\n        ? value !== undefined && value >= 0\n          ? positiveColorScheme\n          : negativeColorScheme\n        : colorScheme\n    },\n    [colorScheme, negativeColorScheme, positiveColorScheme],\n  )\n\n  const color = getColor(primaryValue, enableTrendColor)\n  const secondaryColor = getColor(secondaryValue, secondaryEnableTrendColor)\n\n  const icon = getTrendSignAndIcon(\n    !!showTrendSign,\n    primaryValue,\n    positiveSign,\n    negativeSign,\n    color,\n  )\n\n  const secondaryIcon = getTrendSignAndIcon(\n    !!secondaryShowTrendSign,\n    secondaryValue,\n    secondaryPositiveSign,\n    secondaryNegativeSign,\n    secondaryColor,\n    true,\n  )\n\n  const suffixNode = useMemo(\n    () => (\n      <>\n        {secondaryValue !== undefined && (\n          <div css={getSecondaryStatisticContainerStyle(secondaryColor)}>\n            {secondaryIcon}\n            <Statistic\n              _css={getSecondaryStatisticStyle}\n              groupSeparator={secondaryGroupSeparator}\n              value={secondaryValue}\n              precision={secondaryDecimalPlace}\n              prefix={secondaryPrefixText}\n              suffix={secondarySuffixText}\n              colorScheme={secondaryColor}\n            />\n          </div>\n        )}\n      </>\n    ),\n    [\n      secondaryColor,\n      secondaryDecimalPlace,\n      secondaryGroupSeparator,\n      secondaryIcon,\n      secondaryPrefixText,\n      secondarySuffixText,\n      secondaryValue,\n    ],\n  )\n\n  return (\n    <div css={getStatisticWrapperStyle(textAlign)} onClick={handleOnClick}>\n      <div css={getStatisticLabelStyle(textAlign)}>{label}</div>\n      <div css={getStatisticsContainerStyle(textAlign)}>\n        <div css={primaryStatisticContainerStyle}>\n          {icon}\n          <Statistic\n            _css={getStatisticStyle}\n            value={primaryValue}\n            precision={decimalPlace}\n            prefix={prefixText}\n            suffix={suffixText}\n            colorScheme={color}\n            groupSeparator={groupSeparator}\n          />\n        </div>\n        {suffixNode}\n      </div>\n    </div>\n  )\n}\nWrappedStatistic.displayName = \"WrappedStatistic\"\n\nexport const StatisticWidget: FC<StatisticWidgetProps> = (props) => {\n  const {\n    primaryValue,\n    triggerEventHandler,\n    handleUpdateDsl,\n    tooltipText,\n    updateComponentHeight,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n  } = props\n\n  const previousValueRef = useRef<number | undefined>(primaryValue)\n  const signalRef = useRef<boolean>(false)\n\n  useEffect(() => {\n    if (signalRef.current) {\n      signalRef.current = false\n      return\n    }\n    previousValueRef.current = primaryValue\n  }, [primaryValue])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setPrimaryValue: (value: number) => {\n        signalRef.current = true\n        handleUpdateDsl({ primaryValue: value })\n      },\n      resetPrimaryValue: () => {\n        handleUpdateDsl({\n          primaryValue: previousValueRef.current,\n        })\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n  ])\n\n  const handleOnClick = useCallback(() => {\n    triggerEventHandler(\"click\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer\n      updateComponentHeight={updateComponentHeight}\n      enable={true}\n    >\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div>\n          <WrappedStatistic {...props} handleOnClick={handleOnClick} />\n        </div>\n      </TooltipWrapper>\n    </AutoHeightContainer>\n  )\n}\nStatisticWidget.displayName = \"StatisticWidget\"\nexport default StatisticWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StatisticsWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport {\n  getColor,\n  getSpecialThemeColor,\n  globalColor,\n  illaPrefix,\n} from \"@illa-design/react\"\n\nconst overflowStyle = css`\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n`\n\nconst getAlignItems = (textAlign?: string) => {\n  let alignItemsStyle = css``\n  if (!textAlign || textAlign === \"start\") {\n    alignItemsStyle = css`\n      align-items: flex-start;\n    `\n  }\n  if (textAlign === \"center\") {\n    alignItemsStyle = css`\n      align-items: center;\n    `\n  }\n  if (textAlign === \"end\") {\n    alignItemsStyle = css`\n      align-items: flex-end;\n    `\n  }\n  return alignItemsStyle\n}\n\nexport const getStatisticWrapperStyle = (textAlign?: string) => {\n  const alignItemsStyle = getAlignItems(textAlign)\n  return css`\n    display: flex;\n    gap: 4px;\n    flex-direction: column;\n    align-items: center;\n    ${alignItemsStyle};\n  `\n}\nexport const getSecondaryStatisticStyle = css`\n  max-width: 100%;\n  overflow: hidden;\n  & span {\n    font-size: 12px;\n    font-weight: 500;\n    line-height: 18px;\n  }\n`\n\nexport const getStatisticStyle = css`\n  max-width: 100%;\n  overflow: hidden;\n  white-space: nowrap;\n  line-height: 36px;\n`\n\nexport const getPrefixIconStyle = (color?: string, secondary?: boolean) => {\n  const size = secondary ? 12 : 24\n  return css`\n    color: ${getSpecialThemeColor(color || \"\")};\n    display: inline-flex;\n    height: 100%;\n    align-items: center;\n    & > svg {\n      width: ${size}px;\n      height: ${size}px;\n    }\n  `\n}\n\nexport const primaryStatisticContainerStyle = css`\n  display: flex;\n  flex-wrap: nowrap;\n  gap: 8px;\n  align-items: center;\n`\n\nexport const getStatisticsContainerStyle = (textAlign?: string) => {\n  let justifyContentStyle = css``\n  if (textAlign === \"end\") {\n    justifyContentStyle = css`\n      justify-content: flex-end;\n    `\n  }\n  if (textAlign === \"center\") {\n    justifyContentStyle = css`\n      justify-content: center;\n    `\n  }\n\n  return css`\n    ${justifyContentStyle};\n    display: flex;\n    flex-wrap: wrap;\n    overflow: hidden;\n    align-items: center;\n    gap: 8px;\n  `\n}\n\nexport const getSecondaryStatisticContainerStyle = (color?: string) => {\n  return css`\n    display: flex;\n    gap: 2px;\n    align-items: center;\n    height: 18px;\n    padding: 0 4px;\n    border-radius: 2px;\n    background: ${getColor(color || \"\", \"08\")};\n  `\n}\n\nexport const getStatisticLabelStyle = (textAlign?: string) => {\n  let textAlignStyle = css``\n  if (textAlign === \"end\") {\n    textAlignStyle = css`\n      text-align: right;\n    `\n  }\n  if (textAlign === \"center\") {\n    textAlignStyle = css`\n      text-align: center;\n    `\n  }\n\n  return css`\n    ${textAlignStyle};\n    max-width: 100%;\n    color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n    ${overflowStyle};\n    font-size: 12px;\n    line-height: 16px;\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StatisticsWidget/widgetConfig.tsx",
    "content": "import StatisticWidgetIcon from \"@/assets/widgetCover/statistic.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const STATISTICS_WIDGET_CONFIG: WidgetConfig = {\n  type: \"STATISTIC_WIDGET\",\n  displayName: \"statistic\",\n  widgetName: i18n.t(\"widget.statistics.name\"),\n  icon: <StatisticWidgetIcon />,\n  keywords: [\"Statistic\", \"数值\"],\n  sessionType: \"PRESENTATION\",\n  w: 6,\n  h: 7,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    label: \"Label\",\n    colorScheme: \"grayBlue\",\n    positiveColorScheme: \"green\",\n    negativeColorScheme: \"red\",\n    hidden: false,\n    positiveSign: \"TbTrendingUp\",\n    negativeSign: \"TbTrendingDown\",\n    secondaryPositiveSign: \"TbTrendingUp\",\n    secondaryNegativeSign: \"TbTrendingDown\",\n    textAlign: \"start\",\n    primaryValue: \"{{0}}\",\n    decimalPlace: \"{{2}}\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StepsWidget/eventHandlerConfig.ts",
    "content": "import { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const STEPS_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [],\n  methods: [\"setValue\", \"resetValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StepsWidget/index.tsx",
    "content": "export { STEPS_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\nexport { STEPS_PANEL_CONFIG } from \"./panelConfig\"\nexport { STEPS_WIDGET_CONFIG } from \"./widgetConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StepsWidget/interface.ts",
    "content": "import { StepsProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedStepsProps\n  extends Omit<ValidateMessageOldProps, \"value\">,\n    Pick<StepsProps, \"direction\" | \"items\" | \"current\"> {\n  handleUpdateDsl: (value: any) => void\n  getValidateMessage: (value?: unknown) => string\n  linkContainer: boolean\n  linkWidgetDisplayName?: string\n  viewList?: any[]\n  currentKey?: any\n  current?: number\n  currentIndex?: number\n  defaultStep?: string\n  disabled?: boolean\n  handleStepsChange?: (current: number) => void\n}\n\nexport interface StepsWidgetProps extends WrappedStepsProps, BaseWidgetProps {\n  optionConfigureMode: \"dynamic\" | \"static\"\n  manualOptions?: StepsOptionsType[]\n  mappedOption?: StepsMappedOptionType\n}\n\nexport interface StepsMappedOptionType {\n  labels: string[]\n  values: any[]\n  hiddens: boolean[]\n  captions: string[]\n  tooltips: string[]\n}\nexport interface StepsOptionsType {\n  id: string\n  key?: string\n  label?: string\n  value?: any\n  caption?: string\n  tooltip?: string\n  hidden?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StepsWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst baseWidgetName = \"steps\"\nexport const STEPS_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-linkContainer`,\n        labelName: \"Link to a container\",\n        attrName: \"linkContainer\",\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-column-decimalPlaces`,\n        labelName: i18n.t(\"editor.inspect.setter_label.container\"),\n        attrName: \"linkWidgetDisplayName\",\n        bindAttrName: [\"linkContainer\"],\n        shown: (value) => value,\n        setterType: \"TABS_CONTAINER_SELECT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-views-list`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        useCustomLayout: true,\n        attrName: \"viewList\",\n        setterType: \"CONTAINER_VIEW_SETTER\",\n        bindAttrName: [\"linkContainer\", \"linkWidgetDisplayName\"],\n        shown: (isLink, id) => isLink && id,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-options-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"key\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-caption`,\n            labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n            attrName: \"caption\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-tooltip`,\n            labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n            attrName: \"tooltip\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-hidden`,\n            labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n            setterType: \"DYNAMIC_SWITCH_SETTER\",\n            attrName: \"hidden\",\n            useCustomLayout: true,\n            openDynamic: true,\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-options-mode`,\n        attrName: \"optionConfigureMode\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"linkContainer\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: i18n.t(\"widget.public.select_options.manual\"),\n            value: \"static\",\n          },\n          {\n            label: i18n.t(\"widget.public.select_options.mapped\"),\n            value: \"dynamic\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-options`,\n        useCustomLayout: true,\n        attrName: \"manualOptions\",\n        setterType: \"STEPS_LIST_SETTER\",\n        bindAttrName: [\"optionConfigureMode\", \"linkContainer\"],\n        shown: (value, link) => !link && (!value || value === \"static\"),\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-options-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"value\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-caption`,\n            labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n            attrName: \"caption\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-tooltip`,\n            labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n            attrName: \"tooltip\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-hidden`,\n            labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n            setterType: \"DYNAMIC_SWITCH_SETTER\",\n            attrName: \"hidden\",\n            useCustomLayout: true,\n            openDynamic: true,\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-option-data-source`,\n        labelName: \"Data source\",\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"optionConfigureMode\", \"linkContainer\"],\n        expectedType: VALIDATION_TYPES.ARRAY,\n        shown: (value, link) => !link && value === \"dynamic\",\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-option-mapped`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.map_data_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedOption\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        bindAttrName: [\"optionConfigureMode\", \"linkContainer\"],\n        shown: (value, link) => !link && value === \"dynamic\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-mappedOption-labels`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"labels\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item.label}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-values`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"values\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item.value}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-captions`,\n            labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n            attrName: \"captions\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item.caption}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-tooltips`,\n            labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n            attrName: \"tooltips\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item.tooltip}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-hiddens`,\n            labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n            attrName: \"hiddens\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item.hidden}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-option-default-manual-step`,\n        labelName: \"Default step\",\n        attrName: \"defaultStep\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"linkContainer\"],\n        expectedType: VALIDATION_TYPES.STRING,\n        shown: (value) => !value,\n        isSetterSingleRow: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        placeholder: \"{{false}}\",\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"submit\"],\n        shown: (value) => !value,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-direction`,\n        labelName: i18n.t(\"editor.inspect.setter_label.direction\"),\n        setterType: \"RADIO_GROUP_SETTER\",\n        attrName: \"direction\",\n        options: [\n          {\n            label: \"Horizontal\",\n            value: \"horizontal\",\n          },\n          {\n            label: \"Vertical\",\n            value: \"vertical\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"false\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StepsWidget/steps.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useMemo, useRef } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Steps } from \"@illa-design/react\"\nimport { getExecutionResult } from \"@/redux/currentApp/executionTree/executionSelector\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport {\n  StepsWidgetProps,\n  WrappedStepsProps,\n} from \"@/widgetLibrary/StepsWidget/interface\"\nimport {\n  formatStepsData,\n  getFormatOptionConfigData,\n  getStepItemTitle,\n} from \"@/widgetLibrary/StepsWidget/util\"\n\nexport const WrappedSteps: FC<WrappedStepsProps> = (props) => {\n  const { direction, items, current, handleStepsChange } = props\n\n  return (\n    <Steps\n      direction={direction}\n      items={items}\n      type=\"line\"\n      current={current}\n      onChange={handleStepsChange}\n    />\n  )\n}\n\nexport const StepsWidget: FC<StepsWidgetProps> = (props) => {\n  const {\n    manualOptions,\n    mappedOption,\n    displayName,\n    linkContainer,\n    viewList,\n    currentIndex,\n    linkWidgetDisplayName,\n    defaultStep,\n    disabled,\n    updateComponentHeight,\n    handleUpdateMultiExecutionResult,\n    handleUpdateOriginalDSLOtherMultiAttr,\n    optionConfigureMode,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n  } = props\n\n  const preLinkContainer = useRef<boolean>(false)\n  const executionResult = useSelector(getExecutionResult)\n\n  const isLinkedContainer = useMemo(\n    () => linkContainer && !!linkWidgetDisplayName,\n    [linkContainer, linkWidgetDisplayName],\n  )\n\n  const transformedContainerList = useMemo(() => {\n    return (viewList ?? [])\n      .map((item) => {\n        const { key: _key, ...others } = item\n        return {\n          value: item.key,\n          ...others,\n        }\n      })\n      .filter((item) => !item?.hidden)\n  }, [viewList])\n\n  const formatOptionConfigData = useMemo(() => {\n    return getFormatOptionConfigData(\n      optionConfigureMode,\n      optionConfigureMode === \"static\" ? manualOptions : mappedOption,\n    )\n  }, [manualOptions, mappedOption, optionConfigureMode])\n\n  /*\n   * items: StepItem[]\n   * uniqueOptions: array of value that with hidden option filtered\n   */\n  const { items, uniqueOptions } = useMemo(() => {\n    if (!isLinkedContainer) {\n      return formatStepsData(\n        optionConfigureMode,\n        formatOptionConfigData,\n        disabled,\n      )\n    }\n    const results = transformedContainerList.map((item, index) => {\n      const { label, value, caption, tooltip = \"\" } = item\n      const titleContent = label || value || index\n      return {\n        title: getStepItemTitle(titleContent, tooltip),\n        description: caption,\n        disabled,\n      }\n    })\n    return {\n      items: results,\n      uniqueOptions: transformedContainerList.map((item) => item.value),\n    }\n  }, [\n    isLinkedContainer,\n    transformedContainerList,\n    optionConfigureMode,\n    formatOptionConfigData,\n    disabled,\n  ])\n\n  const handleUpdateMultiExecutionResults = useCallback(\n    (updateSliceItem: Record<string, any>) => {\n      if (linkWidgetDisplayName) {\n        handleUpdateOriginalDSLOtherMultiAttr(\n          linkWidgetDisplayName,\n          updateSliceItem,\n          true,\n        )\n      }\n      handleUpdateOriginalDSLOtherMultiAttr(displayName, updateSliceItem, true)\n    },\n    [displayName, handleUpdateOriginalDSLOtherMultiAttr, linkWidgetDisplayName],\n  )\n\n  const handleStepsChange = useCallback(\n    (current: number) => {\n      const value = {\n        currentKey: uniqueOptions?.[current],\n        currentIndex: current,\n      }\n      if (isLinkedContainer) {\n        handleUpdateMultiExecutionResults(value)\n      } else {\n        handleUpdateDsl(value)\n      }\n    },\n    [\n      handleUpdateDsl,\n      handleUpdateMultiExecutionResults,\n      isLinkedContainer,\n      uniqueOptions,\n    ],\n  )\n\n  const handleSetStepsValue = useCallback(\n    (value: any) => {\n      const index = uniqueOptions?.findIndex((item) => item === value)\n      const updateValue = {\n        currentKey: uniqueOptions[index],\n        currentIndex: index,\n      }\n      if (isLinkedContainer) {\n        handleUpdateMultiExecutionResults(updateValue)\n      } else {\n        handleUpdateDsl(updateValue)\n      }\n    },\n    [\n      handleUpdateDsl,\n      handleUpdateMultiExecutionResults,\n      isLinkedContainer,\n      uniqueOptions,\n    ],\n  )\n\n  const handleResetStepsValue = useCallback(() => {\n    if (linkContainer) {\n      return\n    }\n    handleUpdateDsl({\n      currentIndex: uniqueOptions?.findIndex((item) => item === defaultStep),\n      currentKey: defaultStep,\n    })\n  }, [defaultStep, handleUpdateDsl, linkContainer, uniqueOptions])\n\n  useEffect(() => {\n    if (preLinkContainer.current !== linkContainer && linkWidgetDisplayName) {\n      preLinkContainer.current = linkContainer\n      if (linkContainer) {\n        const defaultIndex = get(\n          executionResult,\n          `${linkWidgetDisplayName}.currentIndex`,\n        )\n        const defaultKey = get(\n          executionResult,\n          `${linkWidgetDisplayName}.currentKey`,\n        )\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              currentIndex: defaultIndex,\n              currentKey: defaultKey,\n            },\n          },\n        ])\n      } else {\n        const defaultStepIndex = uniqueOptions?.findIndex(\n          (item) => item === defaultStep,\n        )\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              currentIndex: defaultStepIndex < 0 ? 0 : defaultStepIndex,\n              currentKey: defaultStep,\n            },\n          },\n        ])\n        if (linkWidgetDisplayName) {\n          handleUpdateOriginalDSLOtherMultiAttr(\n            linkWidgetDisplayName,\n            {\n              linkWidgetDisplayName: undefined,\n            },\n            true,\n          )\n        }\n        handleUpdateOriginalDSLOtherMultiAttr(\n          displayName,\n          {\n            linkWidgetDisplayName: undefined,\n          },\n          true,\n        )\n      }\n    }\n  }, [\n    defaultStep,\n    displayName,\n    executionResult,\n    handleUpdateMultiExecutionResult,\n    handleUpdateOriginalDSLOtherMultiAttr,\n    linkContainer,\n    linkWidgetDisplayName,\n    uniqueOptions,\n  ])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: any) => {\n        handleSetStepsValue(value)\n      },\n      resetValue: () => {\n        handleResetStepsValue()\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleResetStepsValue,\n    handleSetStepsValue,\n    updateComponentRuntimeProps,\n  ])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <WrappedSteps\n        {...props}\n        items={items}\n        current={currentIndex}\n        handleStepsChange={handleStepsChange}\n      />\n    </AutoHeightContainer>\n  )\n}\nexport default StepsWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StepsWidget/util.tsx",
    "content": "import { StepItem, Trigger, isArray, isObject } from \"@illa-design/react\"\nimport {\n  StepsMappedOptionType,\n  StepsOptionsType,\n} from \"@/widgetLibrary/StepsWidget/interface\"\n\nconst spliceArrayItem = (arr: any[], index: number) => {\n  arr.length >= index && arr.splice(index, 1)\n}\n\nexport const getFormatOptionConfigData = (\n  optionConfigureMode: \"dynamic\" | \"static\",\n  list?: StepsOptionsType[] | StepsMappedOptionType,\n) => {\n  const isMappedOption = optionConfigureMode === \"dynamic\"\n  if (!list) {\n    return isMappedOption\n      ? { labels: [], values: [], captions: [], tooltips: [], hiddens: [] }\n      : []\n  }\n  if (!isMappedOption && isArray(list)) {\n    const filteredManualOptions = list.filter((option: any) => !option?.hidden)\n    const filteredManualOptionsValueMap: StepsOptionsType[] = []\n    return filteredManualOptions.filter((option: any) => {\n      if (!filteredManualOptionsValueMap.includes(option?.value)) {\n        filteredManualOptionsValueMap.push(option?.value)\n        return true\n      }\n      return false\n    })\n  }\n  const {\n    labels = [],\n    values = [],\n    captions = [],\n    tooltips = [],\n    hiddens = [],\n  } = list as StepsMappedOptionType\n\n  let newHiddens = [...hiddens]\n  const newLabels = [...labels]\n  const newValues = [...values]\n  const newCaptions = [...captions]\n  const newTooltips = [...tooltips]\n\n  newHiddens = newHiddens.filter((item, index) => {\n    if (item) {\n      ;[newLabels, newValues, newCaptions, newTooltips].forEach((arr) =>\n        spliceArrayItem(arr, index),\n      )\n    }\n    return !item\n  })\n  const uniqueValues = newValues.filter((item, index) => {\n    const isUnique = newValues.indexOf(item) === index\n    if (!isUnique) {\n      ;[newLabels, newHiddens, newCaptions, newTooltips].forEach((arr) =>\n        spliceArrayItem(arr, index),\n      )\n    }\n    return isUnique\n  })\n  return {\n    labels: newLabels,\n    values: uniqueValues,\n    captions: newCaptions,\n    tooltips: newTooltips,\n    hiddens: newHiddens,\n  }\n}\n\nexport const getStepItemTitle = (title: any, tooltip?: any) => {\n  const titleContent = title\n  return !!tooltip ? (\n    <Trigger\n      trigger=\"hover\"\n      colorScheme=\"grayBlue\"\n      position=\"top-start\"\n      showArrow={false}\n      content={<>{tooltip}</>}\n    >\n      <div>{titleContent}</div>\n    </Trigger>\n  ) : (\n    titleContent\n  )\n}\n\nexport const formatStepsData = (\n  optionConfigureMode: \"dynamic\" | \"static\",\n  formatOptionConfigData: StepsOptionsType[] | StepsMappedOptionType,\n  disabled?: boolean,\n) => {\n  if (optionConfigureMode === \"static\") {\n    const uniqueManualOptions = formatOptionConfigData as StepsOptionsType[]\n    const results = uniqueManualOptions.map((option, index) => {\n      const { label, value, caption, tooltip = \"\" } = option\n      const titleContent = label || value || index\n      return {\n        title: getStepItemTitle(titleContent, tooltip),\n        description: caption,\n        disabled,\n      }\n    })\n    return {\n      items: results,\n      uniqueOptions: uniqueManualOptions.map((item) => item.value),\n    }\n  }\n  const mappedData = formatOptionConfigData as StepsMappedOptionType\n  const labels = mappedData?.labels || []\n  const values = mappedData?.values || []\n  const captions = mappedData?.captions || []\n  const tooltips = mappedData?.tooltips || []\n  const hiddens = mappedData?.hiddens || []\n  const maxLength = Math.max(\n    labels.length,\n    values.length,\n    captions.length,\n    tooltips.length,\n    hiddens.length,\n  )\n  const uniqueValues: any[] = []\n  const result: StepItem[] = []\n  for (let i = 0; i < maxLength; i++) {\n    let titleContent = labels[i] || values[i] || i\n    if (isObject(titleContent)) {\n      titleContent = i\n    }\n    const caption = isObject(captions[i]) ? \"\" : captions[i]\n    const tips = isObject(tooltips[i]) ? \"\" : tooltips[i]\n    result.push({\n      title: getStepItemTitle(titleContent, tips),\n      description: <>{caption}</>,\n    })\n    uniqueValues.push(values[i])\n  }\n  return { items: result, uniqueOptions: uniqueValues }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/StepsWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport StepsWidgetIcon from \"@/assets/widgetCover/steps.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nconst originData = [\n  { id: `Steps-${v4()}`, value: \"Step 1\", label: \"Step 1\", hidden: false },\n  { id: `Steps-${v4()}`, value: \"Step 2\", label: \"Step 2\", hidden: false },\n  { id: `Steps-${v4()}`, value: \"Step 3\", label: \"Step 3\", hidden: false },\n  { id: `Steps-${v4()}`, value: \"Step 4\", label: \"Step 4\", hidden: false },\n]\n\nexport const STEPS_WIDGET_CONFIG: WidgetConfig = {\n  type: \"STEPS_WIDGET\",\n  displayName: \"steps\",\n  widgetName: i18n.t(\"widget.step.name\"),\n  icon: <StepsWidgetIcon />,\n  keywords: [\"Steps\", \"步骤\"],\n  sessionType: \"NAVIGATION\",\n  w: 18,\n  h: 4,\n  version: 0,\n  defaults: {\n    direction: \"horizontal\",\n    alignment: \"start\",\n    linkContainer: false,\n    linkWidgetDisplayName: \"\",\n    optionConfigureMode: \"static\",\n    manualOptions: originData,\n    viewList: [],\n    defaultStep: \"Step 1\",\n    currentKey: \"Step 1\",\n    currentIndex: 0,\n    dataSources: `{{${JSON.stringify(originData, null, 2)}}}`,\n    resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n    disabled: false,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchGroupWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const SWITCH_GROUP_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"setValueInArray\", \"clearValue\", \"validate\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchGroupWidget/index.tsx",
    "content": "export { SWITCH_GROUP_PANEL_CONFIG } from \"./panelConfig\"\nexport { SWITCH_GROUP_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { SWITCH_GROUP_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchGroupWidget/interface.ts",
    "content": "import { SwitchProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport type Pluralize<T> = {\n  [K in keyof T as `${string & K}s`]: T[K][]\n}\n\nexport interface SwitchItem {\n  label: string | number\n  value: string | number\n  caption?: string\n  disabled?: boolean\n}\nexport interface WrappedSwitchGroupProps\n  extends Omit<ValidateMessageOldProps, \"value\">,\n    Pick<SwitchProps, \"colorScheme\"> {\n  options: SwitchItem[]\n  value: (string | number)[]\n  layoutPosition: \"left\" | \"right\"\n  invalid?: boolean\n  displayName: string\n  handleOnChange: (status: boolean, val: string | number | undefined) => void\n}\nexport interface SwitchGroupWidgetProps\n  extends WrappedSwitchGroupProps,\n    BaseWidgetProps,\n    LabelProps,\n    Omit<TooltipWrapperProps, \"children\"> {\n  optionConfigureMode?: \"dynamic\" | \"static\"\n  manualOptions?: {\n    label: string\n    value: string | number\n    disabled?: boolean\n    extra?: any\n  }[]\n  mappedOption?: {\n    labels: string[]\n    values: any[]\n    disables: boolean[]\n  }\n  validateMessage: string\n  dataSources: unknown[]\n  atLeastNumber: number\n  upToNumber: number\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchGroupWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { SWITCH_GROUP_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/SwitchGroupWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"SwitchGroup\"\nexport const SWITCH_GROUP_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-options`,\n    groupName: i18n.t(\"editor.inspect.setter_group.options\"),\n    children: [\n      {\n        id: `${baseWidgetName}-options-mode`,\n        attrName: \"optionConfigureMode\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          {\n            label: i18n.t(\"widget.public.select_options.manual\"),\n            value: \"static\",\n          },\n          {\n            label: i18n.t(\"widget.public.select_options.mapped\"),\n            value: \"dynamic\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-options`,\n        useCustomLayout: true,\n        attrName: \"manualOptions\",\n        setterType: \"OPTION_LIST_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => !value || value === \"static\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-options-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.switch_group.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-options-value`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.switch_group.value\"),\n            attrName: \"value\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-caption`,\n            labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.switch_group.caption\",\n            ),\n            attrName: \"caption\",\n            setterType: \"INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-options-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            placeholder: \"{{false}}\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-option-data-sources`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_sources\"),\n        attrName: \"dataSources\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        expectedType: VALIDATION_TYPES.ARRAY,\n        shown: (value) => value === \"dynamic\",\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-option-mapped`,\n        labelName: i18n.t(\"editor.inspect.setter_label.mapped_option\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.map_data_option\"),\n        useCustomLayout: true,\n        attrName: \"mappedOption\",\n        setterType: \"OPTION_MAPPED_SETTER\",\n        bindAttrName: [\"optionConfigureMode\"],\n        shown: (value) => value === \"dynamic\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-mappedOption-labels`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"labels\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-values`,\n            labelName: i18n.t(\"editor.inspect.setter_label.value\"),\n            attrName: \"values\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{item}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-caption`,\n            labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.switch_group.caption\",\n            ),\n            attrName: \"captions\",\n            placeholder: \"{{item}}\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-mappedOption-disables`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disableds\",\n            setterType: \"OPTION_MAPPED_INPUT_SETTER\",\n            placeholder: \"{{false}}\",\n            expectedType: VALIDATION_TYPES.ARRAY,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.switch_group.default_value\",\n        ),\n        attrName: \"value\",\n        isSetterSingleRow: true,\n        placeholder: `{{ [\"value1\", \"value2\"] }}`,\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          SWITCH_GROUP_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-leastNumber`,\n        labelName: i18n.t(\"editor.inspect.setter_label.choose_at_least\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.switch_group.choose_at_least\",\n        ),\n        isSetterSingleRow: true,\n        attrName: \"atLeastNumber\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{2}}\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-upNumber`,\n        labelName: i18n.t(\"editor.inspect.setter_label.choose_up_to\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.switch_group.choose_up_to\",\n        ),\n        isSetterSingleRow: true,\n        attrName: \"upToNumber\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{5}}\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-position`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.switch_group.option_label_alignment\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.switch_group.option_label_alignment\",\n        ),\n        attrName: \"layoutPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        isSetterSingleRow: true,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.right\"), value: \"right\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        placeholder: \"false\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-colors-theme-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchGroupWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nconst baseLabelCss = css`\n  display: block;\n  font-size: 14px;\n  text-overflow: ellipsis;\n`\n\nexport const applyLabel = css`\n  ${baseLabelCss};\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\nexport const applyCaptions = css`\n  ${baseLabelCss};\n  color: ${getColor(\"grey\", \"04\")};\n`\n\nexport const applySwitchContainer = (layoutPosition: \"left\" | \"right\") => {\n  return css`\n    display: inline-flex;\n    word-wrap: break-word;\n    flex-direction: ${layoutPosition === \"left\" ? \"row\" : \"row-reverse\"};\n    gap: 8px;\n    cursor: pointer;\n    align-items: center;\n  `\n}\n\nexport const applyContainer = css`\n  display: inline-flex;\n  align-items: center;\n  margin-right: 24px;\n  gap: 6px 24px;\n  flex-wrap: wrap;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchGroupWidget/switchGroup.tsx",
    "content": "import { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { Switch } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage/\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport {\n  SwitchGroupWidgetProps,\n  WrappedSwitchGroupProps,\n} from \"@/widgetLibrary/SwitchGroupWidget/interface\"\nimport {\n  applyCaptions,\n  applyContainer,\n  applyLabel,\n  applySwitchContainer,\n} from \"@/widgetLibrary/SwitchGroupWidget/style\"\nimport { formatSwitchOptions } from \"@/widgetLibrary/SwitchGroupWidget/utils\"\n\nexport const WrappedSwitchGroup: FC<WrappedSwitchGroupProps> = (props) => {\n  const {\n    options,\n    layoutPosition,\n    value: finalValue,\n    colorScheme,\n    handleOnChange,\n  } = props\n\n  return (\n    <div css={applyContainer}>\n      {options &&\n        options.map(({ value, caption, label, disabled }, index) => (\n          <label\n            css={applySwitchContainer(layoutPosition)}\n            key={`${index}-${value}`}\n          >\n            <Switch\n              colorScheme={colorScheme}\n              disabled={disabled}\n              data-value={value}\n              checked={Array.isArray(finalValue) && finalValue.includes(value)}\n              onChange={(status, event) =>\n                handleOnChange(\n                  status,\n                  (event.currentTarget as HTMLElement).dataset?.value,\n                )\n              }\n            />\n            <div>\n              <span css={applyLabel}>{label}</span>\n              {caption && <span css={applyCaptions}>{caption}</span>}\n            </div>\n          </label>\n        ))}\n    </div>\n  )\n}\n\nWrappedSwitchGroup.displayName = \"WrappedSwitchGroup\"\n\nexport const SwitchGroupWidget: FC<SwitchGroupWidgetProps> = (props) => {\n  const {\n    value: finalValue = [],\n    optionConfigureMode,\n    mappedOption,\n    manualOptions,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    customRule,\n    hideValidationMessage,\n    validateMessage,\n    displayName,\n    upToNumber,\n    atLeastNumber,\n    updateComponentHeight,\n    triggerEventHandler,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n  } = props\n\n  const finalOptions = useMemo(() => {\n    return formatSwitchOptions(optionConfigureMode, manualOptions, mappedOption)\n  }, [optionConfigureMode, manualOptions, mappedOption])\n\n  const getValidateMessage = useCallback(\n    (value: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          atLeastNumber,\n          upToNumber,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [atLeastNumber, customRule, hideValidationMessage, required, upToNumber],\n  )\n\n  const handleValidate = useCallback(\n    (value: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            validateMessage: message,\n          },\n        },\n      ])\n      return message\n    },\n    [displayName, getValidateMessage, handleUpdateMultiExecutionResult],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValueInArray: (value: unknown) => {\n        if (!value || !Array.isArray(value)) {\n          return\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value,\n            },\n          },\n        ])\n      },\n      clearValue: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: [],\n            },\n          },\n        ])\n      },\n      validate: () => {\n        return handleValidate(finalValue)\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    deleteComponentRuntimeProps,\n    handleValidate,\n    finalValue,\n    displayName,\n  ])\n\n  const handleOnChange = useCallback(\n    (status: boolean, val: string | number | undefined) => {\n      if (val === undefined) {\n        return\n      }\n      let safeValue: (string | number)[]\n      if (!Array.isArray(finalValue)) {\n        safeValue = []\n      } else {\n        safeValue = finalValue\n      }\n      let handleValue: (string | number)[] | undefined\n      if (!status) {\n        handleValue = safeValue.filter((item) => item !== val)\n      } else {\n        handleValue = [...safeValue, val]\n      }\n      handleValidate(handleValue)\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: handleValue,\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"change\")\n      })\n    },\n    [\n      finalValue,\n      handleValidate,\n      handleUpdateMultiExecutionResult,\n      displayName,\n      triggerEventHandler,\n    ],\n  )\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedSwitchGroup\n            {...props}\n            value={finalValue}\n            options={finalOptions}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nSwitchGroupWidget.displayName = \"SwitchGroupWidget\"\nexport default SwitchGroupWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchGroupWidget/utils.ts",
    "content": "import {\n  Pluralize,\n  SwitchItem,\n} from \"@/widgetLibrary/SwitchGroupWidget/interface\"\n\nexport const formatSwitchOptions = (\n  optionConfigureMode: \"dynamic\" | \"static\" = \"static\",\n  manualOptions: SwitchItem[] = [],\n  mappedOption: Pluralize<SwitchItem> = {\n    labels: [],\n    captions: [],\n    values: [],\n    disableds: [],\n  },\n) => {\n  if (optionConfigureMode === \"dynamic\") {\n    const label = mappedOption.labels ?? []\n    const value = mappedOption.values ?? []\n    const caption = mappedOption.captions ?? []\n    const disabled = mappedOption.disableds ?? []\n    const maxLength = Math.max(\n      label.length,\n      value.length,\n      disabled.length,\n      caption.length,\n    )\n    const options: SwitchItem[] = []\n    for (let i = 0; i < maxLength; i++) {\n      let labelItem = label[i] || value[i] || i\n      const valueItem = value[i] || label[i] || i\n      const captionItem = caption[i]\n      const disabledItem = disabled[i]\n      if (typeof labelItem === \"object\") {\n        labelItem = i\n      }\n      if (!options.find((item) => item.value === valueItem)) {\n        options.push({\n          label: labelItem,\n          caption: safeNodeValue(captionItem),\n          value: valueItem,\n          disabled: disabledItem,\n        })\n      }\n    }\n    return options\n  } else {\n    if (!Array.isArray(manualOptions)) {\n      return []\n    }\n    const options: SwitchItem[] = []\n    manualOptions.forEach((option, index) => {\n      let labelItem = option.label || option.value || index\n      const captionItem = option.caption\n      const valueItem = option.value || labelItem || index\n      const disabledItem = option.disabled\n      if (typeof labelItem === \"object\") {\n        labelItem = index\n      }\n      if (!options.find((item) => item.value === valueItem)) {\n        options.push({\n          label: labelItem,\n          caption: safeNodeValue(captionItem),\n          value: valueItem,\n          disabled: disabledItem,\n        })\n      }\n    })\n    return options\n  }\n}\n\nconst safeNodeValue = (value: unknown) => {\n  return typeof value === \"string\" ? value : undefined\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchGroupWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport SwitchGroupWidgetIcon from \"@/assets/widgetCover/switchGroup.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const SWITCH_GROUP_WIDGET_CONFIG: WidgetConfig = {\n  type: \"SWITCH_GROUP_WIDGET\",\n  displayName: \"switchGroup\",\n  widgetName: i18n.t(\"widget.switch_group.name\"),\n  icon: <SwitchGroupWidgetIcon />,\n  keywords: [\"switchGroup\", \"开关组\"],\n  sessionType: \"SELECT\",\n  w: 10,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    optionConfigureMode: \"static\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    manualOptions: [\n      { id: `option-${v4()}`, label: \"Option 1\", value: \"Option 1\" },\n      { id: `option-${v4()}`, label: \"Option 2\", value: \"Option 2\" },\n      { id: `option-${v4()}`, label: \"Option 3\", value: \"Option 3\" },\n    ],\n    dataSources: \"{{[]}}\",\n    colorScheme: \"blue\",\n    hidden: false,\n    formDataKey: \"switchGroup\",\n    layoutPosition: \"left\",\n    value: undefined,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const SWITCH_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"toggle\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchWidget/index.tsx",
    "content": "export { SWITCH_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { SWITCH_PANEL_CONFIG } from \"./panelConfig\"\nexport { SWITCH_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchWidget/interface.ts",
    "content": "import { SwitchProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedSwitchProps\n  extends Pick<SwitchProps, \"disabled\" | \"colorScheme\">,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  value?: SwitchProps[\"checked\"]\n  handleOnChange: () => void\n  handleUpdateDsl: (value: Record<string, boolean | undefined>) => void\n}\n\nexport interface SwitchWidgetProps\n  extends WrappedSwitchProps,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps {\n  handleUpdateDsl: (value: Record<string, boolean | undefined>) => void\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { SWITCH_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/SwitchWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"switch\"\nexport const SWITCH_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.component_default_value\",\n        ),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        placeholder: \"{{false}}\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: \"select-label-hidden\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.right\"), value: \"right\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          SWITCH_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-color`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-radius`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchWidget/switch.tsx",
    "content": "import { FC, useCallback, useEffect } from \"react\"\nimport { Switch } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { applyCenterLabelAndComponentWrapperStyle } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { SwitchWidgetProps, WrappedSwitchProps } from \"./interface\"\n\nexport const WrappedSwitch: FC<WrappedSwitchProps> = (props) => {\n  const { value, disabled, colorScheme, handleUpdateDsl, handleOnChange } =\n    props\n\n  return (\n    <Switch\n      checked={value}\n      alignSelf=\"center\"\n      disabled={disabled}\n      colorScheme={colorScheme}\n      onChange={(value) => {\n        handleUpdateDsl({ value })\n        handleOnChange()\n      }}\n    />\n  )\n}\n\nWrappedSwitch.displayName = \"WrappedSwitch\"\n\nexport const SwitchWidget: FC<SwitchWidgetProps> = (props) => {\n  const {\n    value,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    updateComponentHeight,\n    triggerEventHandler,\n  } = props\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: boolean) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: false })\n      },\n      toggle: () => {\n        handleUpdateDsl({ value: !value })\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    handleUpdateDsl,\n    deleteComponentRuntimeProps,\n    value,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyCenterLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedSwitch {...props} handleOnChange={handleOnChange} />\n        </div>\n      </TooltipWrapper>\n    </AutoHeightContainer>\n  )\n}\nSwitchWidget.displayName = \"SwitchWidget\"\nexport default SwitchWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/SwitchWidget/widgetConfig.tsx",
    "content": "import SwitchWidgetIcon from \"@/assets/widgetCover/switch.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const SWITCH_WIDGET_CONFIG: WidgetConfig = {\n  displayName: \"switch\",\n  widgetName: i18n.t(\"widget.switch.name\"),\n  h: 3,\n  w: 5,\n  type: \"SWITCH_WIDGET\",\n  icon: <SwitchWidgetIcon />,\n  keywords: [\"Switch\", \"开关\"],\n  sessionType: \"SELECT\",\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    labelFull: \"{{true}}\",\n    colorScheme: \"blue\",\n    hidden: \"{{false}}\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TableWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const TABLE_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.sortingChange\",\n      ),\n      value: \"sortingChange\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.paginationChange\",\n      ),\n      value: \"paginationChange\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.filtersChange\",\n      ),\n      value: \"filtersChange\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.rowSelectChange\",\n      ),\n      value: \"rowSelectChange\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.rowClick\",\n      ),\n      value: \"rowClick\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.refresh\",\n      ),\n      value: \"refresh\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.onCellSelect\",\n      ),\n      value: \"onCellSelect\",\n    },\n  ],\n  methods: [\n    \"selectPage\",\n    \"selectRow\",\n    \"clearSelection\",\n    \"setFilters\",\n    \"clearFilters\",\n    \"setSort\",\n  ],\n}\n\nexport const TABLE_BUTTON_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.clickMenuItem\",\n      ),\n      value: \"clickMenuItem\",\n    },\n  ],\n  methods: [],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TableWidget/index.ts",
    "content": "export { TABLE_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { TABLE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\nexport { TABLE_PANEL_CONFIG } from \"./panelConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TableWidget/interface.ts",
    "content": "import { ColumnDef } from \"@tanstack/react-table\"\nimport { HTMLAttributes } from \"react\"\nimport {\n  ButtonColorScheme,\n  ButtonProps,\n  ImageProps,\n  TableProps,\n} from \"@illa-design/react\"\nimport { CellItemProps } from \"@/page/App/components/InspectPanel/PanelSetters/TableSetter/CellSetter/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport enum Columns {\n  Auto = \"auto\",\n  Text = \"text\",\n  Date = \"date\",\n  Tag = \"tag\",\n  Time = \"time\",\n  DateTime = \"datetime\",\n  Number = \"number\",\n  Percent = \"percent\",\n  Link = \"link\",\n  Button = \"button\",\n  ButtonGroup = \"buttongroup\",\n  Boolean = \"boolean\",\n  Image = \"image\",\n  IconGroup = \"icongroup\",\n  Rating = \"rating\",\n  Markdown = \"markdown\",\n  // HTML = \"html\",\n  Currency = \"currency\",\n}\n\nexport type ColumnType = Lowercase<keyof typeof Columns>\n\nexport const ColumnTypeOption = Object.entries(Columns).map(([key, value]) => {\n  return {\n    label: key,\n    value: value as ColumnType,\n  }\n})\n\nexport const defaultColumnItem: Partial<ColumnItemShape> = {\n  enableSorting: true,\n  type: \"auto\",\n  visible: true,\n  format: \"YYYY-MM-DD\",\n  colorScheme: \"blue\",\n  objectFit: \"scale-down\",\n  tagColor: \"auto\",\n  alignment: \"left\",\n}\n\nexport interface ColumnItemShape\n  extends Pick<ColumnDef<object>, \"cell\" | \"id\" | \"meta\"> {\n  accessorKey: string\n  header: string\n  value?: string\n  label?: string\n  type?: ColumnType\n  disabled?: boolean\n  colorScheme?: ButtonColorScheme\n  objectFit?: ImageProps[\"objectFit\"]\n  enableSorting?: boolean\n  visible?: boolean\n  decimalPlaces?: number\n  showThousandsSeparator?: boolean\n  format?: string\n  mappedValue?: string\n  custom?: boolean\n  fromCurrentRow?: Record<string, boolean>\n  events?: any[]\n  columnIndex?: number\n  alignment?: TableCellAlign\n  backgroundColor?: string\n  // button type\n  variant?: ButtonProps[\"variant\"]\n  // icon type\n  iconName?: string\n  iconGroupContent?: TableCellIconGroupItemProps[]\n  // currency type\n  currencyCode?: string\n  // tag type\n  tagLabel?: string\n  tagColor?: string | \"auto\"\n  tagColorJs?: string | \"auto\"\n  tagColorMode?: \"select\" | \"dynamic\"\n  // button group type\n  buttonGroupContent?: TableCellButtonGroupItemProps[]\n}\n\nexport type TableCellAlign = \"left\" | \"center\" | \"right\"\n\nexport interface TableCellButtonGroupItemProps extends CellItemProps {\n  colorScheme?: ButtonColorScheme\n  disabled?: boolean\n  variant?: ButtonProps[\"variant\"]\n  fromCurrentRow?: Record<string, boolean>\n}\n\nexport interface TableCellIconGroupItemProps extends CellItemProps {\n  colorScheme?: string\n  disabled?: boolean\n  fromCurrentRow?: Record<string, boolean>\n}\n\nexport const tagColorSchemeOptions = [\n  \"auto\",\n  \"blackAlpha\",\n  \"gray\",\n  \"grayBlue\",\n  \"red\",\n  \"orange\",\n  \"yellow\",\n  \"green\",\n  \"blue\",\n  \"cyan\",\n  \"purple\",\n  \"techPurple\",\n  \"techPink\",\n]\n\nexport interface TableCommonProps\n  extends HTMLAttributes<HTMLDivElement>,\n    Pick<\n      TableProps<any, any>,\n      | \"loading\"\n      | \"columns\"\n      | \"filter\"\n      | \"refresh\"\n      | \"download\"\n      | \"downloadRawData\"\n      | \"overFlow\"\n      | \"pagination\"\n      | \"defaultSort\"\n      | \"rowSelection\"\n      | \"columnVisibility\"\n      | \"multiRowSelection\"\n      | \"enableSingleCellSelection\"\n      | \"columnSizing\"\n      | \"data\"\n    > {\n  emptyState?: string\n  pageSize?: number\n  pageIndex?: number\n  defaultSortKey?: string\n  defaultSortOrder?: \"ascend\" | \"descend\"\n  selectedRow?: any[]\n  enableServerSidePagination?: boolean\n  paginationType?:\n    | \"limitOffsetBased\"\n    | \"cursorBased\"\n    | \"graphqlRelayCursorBased\"\n  totalRowCount?: number\n  nextBeforeCursor?: number\n  nextAfterCursor?: number\n  hasNextPage?: boolean\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n}\n\nexport interface WrappedTableProps\n  extends TableCommonProps,\n    Omit<BaseWidgetProps, \"triggerEventHandler\"> {\n  customColumns?: Record<number, string>\n  clickOutsideToResetSelection?: boolean\n  handleOnClickMenuItem?: (path: string) => void\n  handleOnCellSelect: () => void\n  handleOnSortingChange: () => void\n  handleOnPaginationChange: () => void\n  handleOnFiltersChange: () => void\n  handleOnRowSelectChange: () => void\n  handleOnRowClick: () => void\n  handleOnRefresh: () => void\n}\n\n// todo: @echoxyc error extends\nexport interface TableWidgetProps extends TableCommonProps, BaseWidgetProps {\n  columns: ColumnItemShape[]\n  dataSource: any[]\n  dataSourceJS: any[]\n  dataSourceMode: \"select\" | \"dynamic\"\n}\n\nexport interface WrappedTableContextProps {\n  handleOnClick?: () => void\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TableWidget/panelConfig.tsx",
    "content": "import {\n  HorizontalCenterIcon,\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n} from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { generatorTableEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorTableEventHandlerConfig\"\nimport {\n  TABLE_BUTTON_EVENT_HANDLER_CONFIG,\n  TABLE_EVENT_HANDLER_CONFIG,\n} from \"@/widgetLibrary/TableWidget/eventHandlerConfig\"\nimport { Columns } from \"@/widgetLibrary/TableWidget/interface\"\n\nconst baseWidgetName = \"table\"\n\nexport const TABLE_PAGENATION_OPTIONS = [\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.limit_offset_based\"),\n    value: \"limitOffsetBased\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.cursor_based\"),\n    value: \"cursorBased\",\n  },\n  {\n    label: i18n.t(\"editor.inspect.setter_option.table.graphql_relay_cursor\"),\n    value: \"graphqlRelayCursorBased\",\n  },\n]\n\nexport const TABLE_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-data`,\n    groupName: i18n.t(\"editor.inspect.setter_group.data\"),\n    children: [\n      {\n        id: `${baseWidgetName}-data-source`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        useCustomLayout: true,\n        attrName: \"dataSource\",\n        setterType: \"TABLE_DATASOURCE_SELECT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-emptyState`,\n        labelName: i18n.t(\"editor.inspect.setter_label.empty_state\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"emptyState\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-loading`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n        attrName: \"loading\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-column`,\n    groupName: i18n.t(\"editor.inspect.setter_group.column\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-columns`,\n        useCustomLayout: true,\n        attrName: \"columns\",\n        setterType: \"COLUMN_SETTER\",\n        openDynamic: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-column-header`,\n            labelName: i18n.t(\"editor.inspect.setter_label.column_title\"),\n            attrName: \"header\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-column-type`,\n            labelName: i18n.t(\"editor.inspect.setter_label.column_type\"),\n            attrName: \"type\",\n            setterType: \"COLUMN_TYPE_SELECT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-column-decimalPlaces`,\n            labelName: i18n.t(\"editor.inspect.setter_label.decimal_places\"),\n            attrName: \"decimalPlaces\",\n            bindAttrName: [\"type\"],\n            shown: (value) =>\n              value === Columns.Number ||\n              value === Columns.Percent ||\n              value === Columns.Currency,\n            placeholder: \"{{ 0 }}\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.NUMBER,\n          },\n          {\n            id: `${baseWidgetName}-column-format`,\n            labelName: i18n.t(\"editor.inspect.setter_label.format\"),\n            attrName: \"format\",\n            bindAttrName: [\"type\"],\n            shown: (value) =>\n              value === Columns.Date ||\n              value === Columns.DateTime ||\n              value === Columns.Time,\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-column-mappedValue`,\n            labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n            attrName: \"mappedValue\",\n            setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n            placeholder: \"{{currentRow.col}}\",\n            bindAttrName: [\"type\"],\n            shown: (value) =>\n              value !== Columns.ButtonGroup &&\n              value !== Columns.IconGroup &&\n              value !== Columns.Tag,\n          },\n          {\n            id: `${baseWidgetName}-column-buttonGroupContent`,\n            useCustomLayout: true,\n            attrName: \"buttonGroupContent\",\n            setterType: \"CELL_SETTER\",\n            openDynamic: true,\n            bindAttrName: [\"type\"],\n            shown: (value) => value === Columns.ButtonGroup,\n            childrenSetter: [\n              {\n                id: `${baseWidgetName}-column-buttonGroupContent-cellValue`,\n                labelName: i18n.t(\"editor.inspect.setter_label.mapped_value\"),\n                attrName: \"cellValue\",\n                setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n              },\n              {\n                id: `${baseWidgetName}-column-buttonGroupContent-variant`,\n                setterType: \"RADIO_GROUP_SETTER\",\n                labelName: i18n.t(\"editor.inspect.setter_label.variant\"),\n                attrName: \"variant\",\n                options: [\n                  {\n                    label: i18n.t(\"editor.inspect.setter_default_value.fill\"),\n                    value: \"fill\",\n                  },\n                  {\n                    label: i18n.t(\n                      \"editor.inspect.setter_default_value.outline\",\n                    ),\n                    value: \"outline\",\n                  },\n                ],\n              },\n              {\n                ...generatorTableEventHandlerConfig(\n                  baseWidgetName,\n                  TABLE_BUTTON_EVENT_HANDLER_CONFIG.events,\n                ),\n              },\n              {\n                id: `${baseWidgetName}-column-buttonGroupContent-disabled`,\n                labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n                placeholder: \"{{false}}\",\n                attrName: \"disabled\",\n                setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n              },\n              {\n                id: `${baseWidgetName}-column-buttonGroupContent-colorScheme`,\n                labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n                setterType: \"COLOR_PICKER_SETTER\",\n                attrName: \"colorScheme\",\n                labelSize: \"medium\",\n              },\n            ],\n          },\n          {\n            id: `${baseWidgetName}-column-iconGroupContent`,\n            useCustomLayout: true,\n            attrName: \"iconGroupContent\",\n            setterType: \"CELL_SETTER\",\n            openDynamic: true,\n            bindAttrName: [\"type\"],\n            shown: (value) => value === Columns.IconGroup,\n            childrenSetter: [\n              {\n                id: `${baseWidgetName}-column-iconGroupContent-cellValue`,\n                labelName: i18n.t(\"editor.inspect.setter_label.icon\"),\n                attrName: \"cellValue\",\n                expectedType: VALIDATION_TYPES.STRING,\n                setterType: \"ICON_SETTER\",\n              },\n              {\n                id: `${baseWidgetName}-column-buttonGroupContent-colorScheme`,\n                labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n                setterType: \"COLOR_PICKER_SETTER\",\n                attrName: \"colorScheme\",\n                labelSize: \"medium\",\n              },\n              {\n                ...generatorTableEventHandlerConfig(\n                  baseWidgetName,\n                  TABLE_BUTTON_EVENT_HANDLER_CONFIG.events,\n                ),\n              },\n              {\n                id: `${baseWidgetName}-column-buttonGroupContent-disabled`,\n                labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n                placeholder: \"{{false}}\",\n                attrName: \"disabled\",\n                setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n              },\n            ],\n          },\n          {\n            id: `${baseWidgetName}-column-tagLabel`,\n            labelName: i18n.t(\"editor.inspect.setter_label.table.tag_label\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.mapped_value\"),\n            attrName: \"tagLabel\",\n            setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n            placeholder: \"{{currentRow.col}}\",\n            bindAttrName: [\"type\"],\n            shown: (value) => value === Columns.Tag,\n          },\n          {\n            id: `${baseWidgetName}-column-tagColor`,\n            labelName: i18n.t(\"editor.inspect.setter_label.table.tag_color\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.table.tag_color\"),\n            setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n            attrName: \"tagColor\",\n            bindAttrName: [\"type\"],\n            shown: (value) => value === Columns.Tag,\n          },\n          {\n            id: `${baseWidgetName}-column-currencyCode`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.table.currency_code\",\n            ),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.table.currency_code\"),\n            placeholder: i18n.t(\n              \"editor.inspect.setter_placeholder.table.currency_code\",\n            ),\n            attrName: \"currencyCode\",\n            setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n            bindAttrName: [\"type\"],\n            shown: (value) => value === Columns.Currency,\n          },\n          {\n            id: `${baseWidgetName}-column-showThousandsSeparator`,\n            labelName: i18n.t(\n              \"editor.inspect.setter_label.table.show_thousands_separ\",\n            ),\n            labelDesc: i18n.t(\n              \"editor.inspect.setter_tips.table.show_thousands_separ\",\n            ),\n            attrName: \"showThousandsSeparator\",\n            setterType: \"DYNAMIC_SWITCH_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n            openDynamic: true,\n            useCustomLayout: true,\n            bindAttrName: [\"type\"],\n            shown: (value) =>\n              value === Columns.Number ||\n              value === Columns.Percent ||\n              value === Columns.Currency,\n          },\n          {\n            id: `${baseWidgetName}-column-enableSorting`,\n            labelName: i18n.t(\"editor.inspect.setter_label.enable_sorting\"),\n            attrName: \"enableSorting\",\n            setterType: \"DYNAMIC_SWITCH_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n            openDynamic: true,\n            useCustomLayout: true,\n          },\n          {\n            bindAttrName: [\"type\"],\n            shown: (value) => value === Columns.Button,\n            ...generatorTableEventHandlerConfig(\n              baseWidgetName,\n              TABLE_BUTTON_EVENT_HANDLER_CONFIG.events,\n            ),\n          },\n          {\n            id: `${baseWidgetName}-column-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n            placeholder: \"{{false}}\",\n            attrName: \"disabled\",\n            setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n            bindAttrName: [\"type\"],\n            shown: (value) => value === Columns.Button,\n          },\n          {\n            id: `${baseWidgetName}-column-colorScheme`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            labelSize: \"medium\",\n            attrName: \"colorScheme\",\n            defaultValue: \"blue\",\n            bindAttrName: [\"type\"],\n            shown: (value) => value === Columns.Button,\n          },\n          {\n            id: `${baseWidgetName}-column-scale-type`,\n            labelName: i18n.t(\"editor.inspect.setter_label.scale_type\"),\n            attrName: \"objectFit\",\n            setterType: \"SEARCH_SELECT_SETTER\",\n            options: [\"container\", \"cover\", \"fill\", \"none\", \"scale-down\"],\n            bindAttrName: [\"type\"],\n            shown: (value) => value === Columns.Image,\n          },\n          {\n            id: `${baseWidgetName}-column-background-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.table.background\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.table.background\"),\n            attrName: \"backgroundColor\",\n            setterType: \"TABLE_MAPPED_VALUE_INPUT_SETTER\",\n          },\n          {\n            id: `${baseWidgetName}-column-column-variant`,\n            setterType: \"RADIO_GROUP_SETTER\",\n            labelName: i18n.t(\"editor.inspect.setter_label.variant\"),\n            attrName: \"variant\",\n            options: [\n              {\n                label: i18n.t(\"editor.inspect.setter_default_value.fill\"),\n                value: \"fill\",\n              },\n              {\n                label: i18n.t(\"editor.inspect.setter_default_value.outline\"),\n                value: \"outline\",\n              },\n            ],\n            bindAttrName: [\"type\"],\n            shown: (value) => value === Columns.Button,\n          },\n          {\n            id: `${baseWidgetName}-column-alignment`,\n            setterType: \"RADIO_GROUP_SETTER\",\n            labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n            attrName: \"alignment\",\n            options: [\n              {\n                label: <HorizontalStartIcon />,\n                value: \"left\",\n              },\n              {\n                label: <HorizontalCenterIcon />,\n                value: \"center\",\n              },\n              {\n                label: <HorizontalEndIcon />,\n                value: \"right\",\n              },\n            ],\n          },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-sort`,\n    groupName: i18n.t(\"editor.inspect.setter_group.sort\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-defaultSortKey`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_sort_key\"),\n        attrName: \"defaultSortKey\",\n        setterType: \"COLUMNS_SELECT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        openDynamic: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-defaultSortOrder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_sort_order\"),\n        attrName: \"defaultSortOrder\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"defaultSortKey\"],\n        shown: (value) => value !== \"default\",\n        options: [\n          { label: i18n.t(\"widget.table.ascend\"), value: \"ascend\" },\n          { label: i18n.t(\"widget.table.descend\"), value: \"descend\" },\n        ],\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-rowSelection`,\n    groupName: i18n.t(\"editor.inspect.setter_group.row_selection\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-multiRowSelection`,\n        labelName: i18n.t(\"editor.inspect.setter_label.multi_row_selection\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.multi_row_selection\"),\n        attrName: \"multiRowSelection\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-enableSingleCellSelection`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.cell_selection\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.table.whether_allow_users_\",\n        ),\n        attrName: \"enableSingleCellSelection\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-clickOutsideToResetSelection`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.table.click_outside_to_des\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.table.supported_in_the_row\",\n        ),\n        attrName: \"clickOutsideToResetSelection\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n        bindAttrName: [\"multiRowSelection\"],\n        shown: (value) => !value,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-PAGINATION`,\n    groupName: i18n.t(\"editor.inspect.setter_group.pagination\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-overFlow`,\n        labelName: i18n.t(\"editor.inspect.setter_label.overFlow\"),\n        attrName: \"overFlow\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          { label: i18n.t(\"widget.table.pagination\"), value: \"pagination\" },\n          { label: i18n.t(\"widget.table.scroll\"), value: \"scroll\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-enableServerSidePagination`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.table.enable_server_side_p\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.table.enable_server_side_p\",\n        ),\n        attrName: \"enableServerSidePagination\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-column-paginationType`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.pagination_type\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.pagination_type\"),\n        attrName: \"paginationType\",\n        setterType: \"SEARCH_SELECT_SETTER\",\n        isSetterSingleRow: true,\n        bindAttrName: [\"enableServerSidePagination\"],\n        shown: (value) => value,\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.table.limit_offset_based\",\n            ),\n            value: \"limitOffsetBased\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.table.cursor_based\"),\n            value: \"cursorBased\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_option.table.graphql_relay_cursor\",\n            ),\n            value: \"graphqlRelayCursorBased\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-totalRowCount`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.total_row_count\"),\n        attrName: \"totalRowCount\",\n        setterType: \"INPUT_SETTER\",\n        isSetterSingleRow: true,\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\"enableServerSidePagination\"],\n        shown: (value) => value,\n      },\n      {\n        id: `${baseWidgetName}-basic-previousCursor`,\n        labelName: i18n.t(\"editor.inspect.setter_label.previous_cursor\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_label.previous_cursor\"),\n        attrName: \"nextBeforeCursor\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        bindAttrName: [\"enableServerSidePagination\", \"paginationType\"],\n        shown: (enable, paginationType) =>\n          enable && paginationType === \"graphqlRelayCursorBased\",\n      },\n      {\n        id: `${baseWidgetName}-basic-nextCursor`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.next_cursor\"),\n        attrName: \"nextAfterCursor\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        bindAttrName: [\"enableServerSidePagination\", \"paginationType\"],\n        shown: (enable, paginationType) =>\n          enable &&\n          (paginationType === \"cursorBased\" ||\n            paginationType === \"graphqlRelayCursorBased\"),\n      },\n      {\n        id: `${baseWidgetName}-basic-hasNextPage`,\n        labelName: i18n.t(\"editor.inspect.setter_label.table.has_next_page\"),\n        attrName: \"hasNextPage\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"enableServerSidePagination\", \"paginationType\"],\n        shown: (enable, paginationType) =>\n          enable &&\n          (paginationType === \"cursorBased\" ||\n            paginationType === \"graphqlRelayCursorBased\"),\n      },\n      {\n        id: `${baseWidgetName}-basic-pageSize`,\n        labelName: i18n.t(\"editor.inspect.setter_label.pageSize\"),\n        attrName: \"pageSize\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-toolbar`,\n    groupName: i18n.t(\"editor.inspect.setter_group.toolbar\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-refresh`,\n        labelName: i18n.t(\"editor.inspect.setter_content.refresh\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.refresh\"),\n        attrName: \"refresh\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-download`,\n        labelName: i18n.t(\"editor.inspect.setter_label.download\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.download\"),\n        attrName: \"download\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-downloadRawData`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.table.download_row_data\",\n        ),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.table.download_row_data\"),\n        attrName: \"downloadRawData\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-basic-filter`,\n        labelName: i18n.t(\"editor.inspect.setter_label.filter\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.filter\"),\n        attrName: \"filter\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        openDynamic: true,\n        useCustomLayout: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          TABLE_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TableWidget/react-table.d.ts",
    "content": "import { SerializedStyles } from \"@emotion/react\"\nimport type { CellContext, RowData } from \"@tanstack/react-table\"\nimport \"@tanstack/react-table\"\n\ndeclare module \"@tanstack/react-table\" {\n  interface ColumnMeta<TData extends RowData, TValue> {\n    custom?: boolean\n    haveMappedValue?: boolean\n    style?: SerializedStyles\n    getBackgroundColor?: (\n      props: CellContext<TData, TValue>,\n    ) => string | undefined\n    getRenderedValueAsString?: (props: CellContext<TData, TValue>) => string\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TableWidget/renderTableCell.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { CellContext } from \"@tanstack/table-core\"\nimport { FC, SyntheticEvent } from \"react\"\nimport {\n  Button,\n  ButtonGroup,\n  Image,\n  Link,\n  Rate,\n  Tag,\n  getColor,\n  getSpecialThemeColor,\n} from \"@illa-design/react\"\nimport { ILLAMarkdown } from \"@/components/ILLAMarkdown\"\nimport { getIcon } from \"@/widgetLibrary/IconWidget/utils\"\nimport {\n  ColumnItemShape,\n  TableCellAlign,\n  TableCellButtonGroupItemProps,\n  TableCellIconGroupItemProps,\n  tagColorSchemeOptions,\n} from \"@/widgetLibrary/TableWidget/interface\"\nimport {\n  applyAlignmentStyle,\n  applyFlexAlignmentStyle,\n  applyIconContainerStyle,\n  applyTableButtonGroupStyle,\n  applyTableCellBackgroundStyle,\n  overFlowStyle,\n} from \"@/widgetLibrary/TableWidget/style\"\nimport {\n  getConfigFromColumnShapeData,\n  getMappedValue,\n} from \"@/widgetLibrary/TableWidget/utils\"\n\nexport const RenderTableStringCell: FC<{\n  value?: string\n  alignment?: TableCellAlign\n  bgColor?: string\n}> = (props) => {\n  const { value, alignment, bgColor } = props\n  return (\n    <span\n      css={[\n        applyAlignmentStyle(alignment),\n        applyTableCellBackgroundStyle(bgColor),\n      ]}\n    >\n      {value ? value : \"-\"}\n    </span>\n  )\n}\n\nexport const RenderTableLink: FC<{\n  cell: CellContext<any, any>\n  value?: string\n  alignment?: TableCellAlign\n}> = (props) => {\n  const { cell, value, alignment } = props\n  const cellValue = value ?? cell.getValue()\n\n  return (\n    <div css={applyAlignmentStyle(alignment)}>\n      {cellValue ? (\n        <Link href={cellValue} target=\"_blank\">{`${cellValue}`}</Link>\n      ) : (\n        \"-\"\n      )}\n    </div>\n  )\n}\n\nexport const RenderTableImage: FC<{\n  cell: CellContext<any, any>\n  value?: string\n  data: ColumnItemShape\n}> = (props) => {\n  const { cell, value, data } = props\n  const { fromCurrentRow } = data\n  const objectFit = getConfigFromColumnShapeData(\n    \"objectFit\",\n    data,\n    cell.row.index,\n    fromCurrentRow,\n  )\n  return (\n    <Image\n      w=\"100%\"\n      width=\"100%\"\n      height=\"42px\"\n      src={value}\n      objectFit={objectFit}\n      draggable={false}\n    />\n  )\n}\n\nconst getTagColor = (color: string, rowIndex: number, index: number) => {\n  const tagDefaultColor = [\n    \"techPink\",\n    \"purple\",\n    \"red\",\n    \"green\",\n    \"orange\",\n    \"cyan\",\n  ]\n\n  return color === \"auto\"\n    ? tagDefaultColor[(rowIndex + index) % tagDefaultColor.length]\n    : tagColorSchemeOptions.includes(color)\n      ? color\n      : getSpecialThemeColor(color)\n}\n\nexport const RenderTableTag: FC<{\n  cell: CellContext<any, any>\n  value?: Array<unknown>\n  color: string | \"auto\"\n  alignment?: TableCellAlign\n}> = (props) => {\n  const { cell, value, color, alignment } = props\n  const rowIndex = cell.row.index\n\n  return (\n    <div css={applyFlexAlignmentStyle(alignment)}>\n      {value?.length ? (\n        value?.map((itemValue, index) => {\n          const colorScheme = getTagColor(color, rowIndex, index)\n          return (\n            <Tag key={index} colorScheme={colorScheme}>\n              {`${itemValue}`}\n            </Tag>\n          )\n        })\n      ) : (\n        <Tag colorScheme={getTagColor(color, rowIndex, 0)}>{\"-\"}</Tag>\n      )}\n    </div>\n  )\n}\n\nexport const RenderTableButton: FC<{\n  cell: CellContext<any, any>\n  value?: string\n  data: ColumnItemShape\n  eventPath: string\n  handleOnClickMenuItem?: (path: string) => void\n}> = (props) => {\n  const { value, data, cell, eventPath, handleOnClickMenuItem } = props\n  const rowIndex = cell.row.index\n  const paths = [eventPath, `${cell.row.index}`]\n  const { fromCurrentRow, variant, colorScheme } = data\n  const disabled = getConfigFromColumnShapeData(\n    \"disabled\",\n    data,\n    rowIndex,\n    fromCurrentRow,\n  )\n  const clickEvent = (e: SyntheticEvent) => {\n    cell.row.getIsSelected() && e.stopPropagation()\n    handleOnClickMenuItem?.(convertPathToString(paths))\n  }\n\n  return (\n    <Button\n      css={overFlowStyle}\n      fullWidth\n      variant={variant}\n      disabled={disabled}\n      colorScheme={colorScheme}\n      onClick={clickEvent}\n    >\n      {`${value ?? \"-\"}`}\n    </Button>\n  )\n}\n\nexport const RenderTableButtonGroup: FC<{\n  cell: CellContext<any, any>\n  value?: TableCellButtonGroupItemProps[]\n  alignment?: TableCellAlign\n  eventPath: string\n  handleOnClick?: (path: string, index?: number) => void\n}> = (props) => {\n  const { cell, value, alignment, eventPath, handleOnClick } = props\n  const rowIndex = cell.row.index\n\n  const handleOnClickButtonItem = (e: SyntheticEvent, index: number) => {\n    cell.row.getIsSelected() && e.stopPropagation()\n    const paths = [`${eventPath}`, \"buttonGroupContent\", `${index}`, \"events\"]\n    handleOnClick?.(convertPathToString(paths), rowIndex)\n  }\n\n  return value ? (\n    <ButtonGroup css={applyTableButtonGroupStyle(alignment)} spacing=\"8px\">\n      {value.map((item, index) => {\n        const { cellValue, colorScheme, disabled, variant, fromCurrentRow } =\n          item\n        const _disabled = getMappedValue(\n          rowIndex,\n          disabled,\n          fromCurrentRow,\n          \"disabled\",\n          false,\n        )\n\n        return (\n          <Button\n            key={index}\n            colorScheme={colorScheme}\n            disabled={_disabled}\n            variant={variant}\n            onClick={(e) => handleOnClickButtonItem(e, index)}\n          >\n            {cellValue ? cellValue : \"-\"}\n          </Button>\n        )\n      })}\n    </ButtonGroup>\n  ) : (\n    <span>{\"-\"}</span>\n  )\n}\n\nexport const RenderTableIconGroup: FC<{\n  cell: CellContext<any, any>\n  value?: TableCellIconGroupItemProps[]\n  alignment?: TableCellAlign\n  eventPath: string\n  handleOnClick?: (path: string, index?: number) => void\n}> = (props) => {\n  const { cell, value, alignment, eventPath, handleOnClick } = props\n  const rowIndex = cell.row.index\n  const handleOnClickIconItem = (e: SyntheticEvent, index: number) => {\n    cell.row.getIsSelected() && e.stopPropagation()\n    const paths = [`${eventPath}`, \"iconGroupContent\", `${index}`, \"events\"]\n    handleOnClick?.(convertPathToString(paths), rowIndex)\n  }\n\n  return (\n    <div css={applyAlignmentStyle(alignment)}>\n      {value ? (\n        value.map((item, index) => {\n          const { cellValue, colorScheme, disabled, fromCurrentRow } = item\n          const Icon = getIcon(cellValue)\n          const _disabled = getMappedValue(\n            rowIndex,\n            disabled,\n            fromCurrentRow,\n            \"disabled\",\n            false,\n          )\n          return Icon ? (\n            <Icon\n              css={applyIconContainerStyle(colorScheme, _disabled)}\n              key={index}\n              onClick={(e) => !_disabled && handleOnClickIconItem(e, index)}\n            />\n          ) : (\n            <span>{\"-\"}</span>\n          )\n        })\n      ) : (\n        <span>{\"-\"}</span>\n      )}\n    </div>\n  )\n}\n\nexport const RenderTableMarkdown: FC<{\n  value?: string\n  alignment?: TableCellAlign\n}> = (props) => {\n  const { value, alignment } = props\n\n  return (\n    <div css={applyAlignmentStyle(alignment)}>\n      {value ? (\n        <ILLAMarkdown\n          textString={value}\n          textColor={getColor(\"grayBlue\", \"02\")}\n          urlColor=\"grayBlue\"\n        />\n      ) : (\n        <span>-</span>\n      )}\n    </div>\n  )\n}\n\nexport const RenderTableRating: FC<{\n  value?: unknown\n  alignment?: TableCellAlign\n}> = (props) => {\n  const { value, alignment } = props\n  const maxCount = 5\n\n  return (\n    <div css={applyAlignmentStyle(alignment)}>\n      <Rate count={maxCount} readonly value={Number(value) || 0} />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TableWidget/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\nimport { TableCellAlign } from \"@/widgetLibrary/TableWidget/interface\"\n\nexport const overFlowStyle = css`\n  & > span {\n    overflow: hidden;\n    text-overflow: ellipsis;\n  }\n`\n\nexport const applyIconContainerStyle = (\n  colorScheme?: string,\n  disabled?: boolean,\n): SerializedStyles => {\n  const svgColor = colorScheme\n    ? css`\n        color: ${colorScheme};\n      `\n    : css``\n  return css`\n    width: 16px;\n    ${svgColor};\n    cursor: ${disabled ? \"not-allowed\" : \"pointer\"};\n\n    &:not(:last-of-type) {\n      margin-right: 4px;\n    }\n  }\n  `\n}\n\nexport const applyAlignmentStyle = (\n  align?: TableCellAlign,\n): SerializedStyles => {\n  switch (align) {\n    case \"left\":\n      return css`\n        text-align: left;\n      `\n    case \"center\":\n      return css`\n        text-align: center;\n      `\n    case \"right\":\n      return css`\n        text-align: right;\n      `\n  }\n  return css``\n}\nexport const applyFlexAlignmentStyle = (\n  align?: TableCellAlign,\n): SerializedStyles => {\n  return css`\n    display: flex;\n    flex-direction: row;\n    gap: 8px;\n    justify-content: ${align};\n  `\n}\n\nexport const applyTableButtonGroupStyle = (\n  align?: TableCellAlign,\n): SerializedStyles => {\n  let alignmentStyle\n  switch (align) {\n    case \"left\":\n      alignmentStyle = css`\n        justify-content: left;\n      `\n      break\n    case \"center\":\n      alignmentStyle = css`\n        justify-content: center;\n      `\n      break\n    case \"right\":\n      alignmentStyle = css`\n        justify-content: right;\n      `\n      break\n  }\n  return css`\n    width: 100%;\n    ${alignmentStyle};\n  `\n}\n\nexport const applyTableCellBackgroundStyle = (\n  color?: string,\n): SerializedStyles => {\n  if (color) {\n    return css`\n      background-color: ${getSpecialThemeColor(color)};\n    `\n  }\n  return css``\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TableWidget/table.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { PaginationState } from \"@tanstack/react-table\"\nimport {\n  CellContext,\n  Table as ReactTable,\n  RowSelectionState,\n} from \"@tanstack/table-core\"\nimport { klona } from \"klona/json\"\nimport { debounce, isEqual, toPath } from \"lodash-es\"\nimport {\n  FC,\n  forwardRef,\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport { useSelector } from \"react-redux\"\nimport {\n  FilterOperator,\n  FilterOptions,\n  Table,\n  TableHandler,\n  isFilterOption,\n  isNumber,\n  isObject,\n} from \"@illa-design/react\"\nimport { getIllaMode } from \"@/redux/config/configSelector\"\nimport { applyAlignmentStyle } from \"@/widgetLibrary/TableWidget/style\"\nimport {\n  ColumnItemShape,\n  TableWidgetProps,\n  WrappedTableProps,\n} from \"./interface\"\nimport {\n  getCellForType,\n  getMappedValueFromCellContext,\n  getStringPropertyValue,\n  transTableColumnEvent,\n} from \"./utils\"\n\nexport const WrappedTable = forwardRef<TableHandler<any>, WrappedTableProps>(\n  (props, ref) => {\n    const {\n      displayName,\n      data,\n      loading,\n      emptyState,\n      columns,\n      columnSizing,\n      filter,\n      refresh,\n      download,\n      downloadRawData,\n      overFlow,\n      pageSize,\n      pageIndex = 0,\n      rowSelection,\n      defaultSort,\n      columnVisibility,\n      multiRowSelection,\n      enableSingleCellSelection,\n      clickOutsideToResetSelection,\n      enableServerSidePagination,\n      totalRowCount,\n      paginationType,\n      nextBeforeCursor,\n      nextAfterCursor,\n      handleOnRefresh,\n      handleOnRowClick,\n      handleOnSortingChange,\n      handleOnPaginationChange,\n      handleOnFiltersChange,\n      handleOnRowSelectChange,\n      handleOnCellSelect,\n      handleUpdateMultiExecutionResult,\n      handleUpdateOriginalDSLMultiAttr,\n    } = props\n\n    const mode = useSelector(getIllaMode)\n    const [cachedData, setCachedData] = useState<any[]>([])\n\n    const formatData = useMemo(() => {\n      if (Array.isArray(data)) {\n        return data\n      }\n      return []\n    }, [data])\n\n    const isCursorPaginationEnabled = useMemo(() => {\n      return (\n        (paginationType === \"cursorBased\" ||\n          paginationType === \"graphqlRelayCursorBased\") &&\n        enableServerSidePagination\n      )\n    }, [paginationType, enableServerSidePagination])\n\n    const cursorBasedData = useMemo(() => {\n      const _pageSize = pageSize ? pageSize : data?.length ?? 10\n      const paginationOffset = pageIndex * _pageSize\n\n      return cachedData.slice(paginationOffset, paginationOffset + _pageSize)\n    }, [cachedData, pageIndex, pageSize, data?.length])\n\n    const updateCachedData = useCallback(\n      (data: Array<unknown>) => {\n        if (paginationType === \"cursorBased\") {\n          setCachedData((prevData = []) => {\n            if (isEqual(prevData, data)) {\n              return prevData\n            }\n            return [...prevData, ...data]\n          })\n        }\n      },\n      [paginationType],\n    )\n\n    useEffect(() => {\n      updateCachedData(formatData)\n    }, [formatData, updateCachedData])\n\n    const handleUpdateMulti = useCallback(\n      (value: Record<string, any>) => {\n        if (mode === \"edit\") {\n          handleUpdateOriginalDSLMultiAttr(value, true)\n        } else {\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value,\n            },\n          ])\n        }\n      },\n      [\n        mode,\n        handleUpdateMultiExecutionResult,\n        handleUpdateOriginalDSLMultiAttr,\n        displayName,\n      ],\n    )\n\n    const onRowSelectionChange = useCallback(\n      (value?: RowSelectionState) => {\n        let selectedRow: unknown[] = []\n        let selectedRowIndex: unknown[] = []\n        if (isObject(value)) {\n          Object.keys(value)?.map((key) => {\n            const index = Number(key)\n            if (formatData[index]) {\n              selectedRow.push(formatData[index])\n              selectedRowIndex.push(index)\n            }\n          })\n        }\n        const updateValue = {\n          selectedRowIndex,\n          selectedRow,\n          rowSelection: value,\n        }\n        handleUpdateMulti(updateValue)\n        handleOnRowSelectChange?.()\n      },\n      [formatData, handleUpdateMulti, handleOnRowSelectChange],\n    )\n\n    const onPaginationChange = useCallback(\n      (paginationState: PaginationState, table: ReactTable<any>) => {\n        const data = table.getSortedRowModel().rows\n        const displayedData = data?.map((item) => {\n          const dataRecord: Record<string, unknown> = {}\n          item.getVisibleCells().forEach((cell) => {\n            dataRecord[cell.column.id] = cell.getValue()\n          })\n          return dataRecord\n        })\n        const displayedDataIndices = data?.map((item) => {\n          return item.index\n        })\n        const { pageIndex: _pageIndex, pageSize } = paginationState\n        const paginationOffset = _pageIndex > 0 ? _pageIndex * pageSize : 0\n        const updateValue: Record<string, unknown> = {\n          pageIndex: _pageIndex,\n          paginationOffset,\n          displayedData,\n          displayedDataIndices,\n        }\n        if (enableServerSidePagination) {\n          if (paginationType === \"cursorBased\") {\n            if (pageIndex > _pageIndex) {\n              // updateValue[\"beforeCursor\"] = nextAfterCursor\n            } else {\n              updateValue[\"afterCursor\"] = nextAfterCursor\n            }\n          } else if (paginationType === \"graphqlRelayCursorBased\") {\n            if (pageIndex > _pageIndex) {\n              updateValue[\"beforeCursor\"] = nextBeforeCursor\n              updateValue[\"afterCursor\"] = null\n            } else {\n              updateValue[\"beforeCursor\"] = null\n              updateValue[\"afterCursor\"] = nextAfterCursor\n            }\n          }\n        }\n        // only update execution result\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: updateValue,\n          },\n        ])\n        handleOnPaginationChange?.()\n      },\n      [\n        displayName,\n        handleUpdateMultiExecutionResult,\n        handleOnPaginationChange,\n        enableServerSidePagination,\n        nextBeforeCursor,\n        nextAfterCursor,\n        paginationType,\n        pageIndex,\n      ],\n    )\n\n    const onFiltersChange = useCallback(\n      (filters: FilterOptions[], operator: FilterOperator) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              filters,\n              filterOperator: operator,\n            },\n          },\n        ])\n        handleOnFiltersChange?.()\n      },\n      [displayName, handleUpdateMultiExecutionResult, handleOnFiltersChange],\n    )\n\n    return (\n      <Table\n        bordered\n        striped\n        borderedCell\n        pinedHeader\n        w=\"100%\"\n        h=\"100%\"\n        tableRef={ref}\n        enableColumnResizing={mode === \"edit\"}\n        enableSingleCellSelection={enableSingleCellSelection}\n        serverSidePagination={enableServerSidePagination}\n        total={totalRowCount}\n        colorScheme={\"techPurple\"}\n        rowSelection={rowSelection}\n        data={paginationType === \"cursorBased\" ? cursorBasedData : formatData}\n        columns={columns}\n        columnSizing={columnSizing}\n        filter={filter}\n        loading={loading}\n        refresh={refresh}\n        download={download}\n        downloadRawData={downloadRawData}\n        overFlow={overFlow}\n        pagination={{\n          pageSize: enableServerSidePagination\n            ? pageSize\n              ? pageSize\n              : data?.length\n            : pageSize,\n          disableSimplePageJump: isCursorPaginationEnabled,\n        }}\n        emptyProps={{ description: emptyState }}\n        defaultSort={defaultSort}\n        columnVisibility={columnVisibility}\n        multiRowSelection={multiRowSelection}\n        clickOutsideToResetRowSelect={clickOutsideToResetSelection}\n        onRefresh={handleOnRefresh}\n        onRowClick={handleOnRowClick}\n        onPaginationChange={onPaginationChange}\n        onGlobalFiltersChange={onFiltersChange}\n        onColumnFiltersChange={handleOnFiltersChange}\n        onColumnSizingChange={debounce((columnSizing) => {\n          handleUpdateMulti({ columnSizing })\n        }, 100)}\n        onRowSelectionChange={onRowSelectionChange}\n        onSortingChange={(sortState) => {\n          let sort\n          if (sortState?.length) {\n            sort = {\n              sortKey: sortState[0].id,\n              sortOrder: sortState[0].desc ? \"descend\" : \"ascend\",\n            }\n          }\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: { sort },\n            },\n          ])\n          handleOnSortingChange?.()\n        }}\n        onCellSelectionChange={(cell) => {\n          const selectedCell: Record<string, unknown> = cell\n            ? {\n                index: cell.row.index,\n                columnName: cell.column.id,\n                value: cell.getValue(),\n              }\n            : {}\n          if (cell?.column.columnDef.meta?.haveMappedValue) {\n            selectedCell[\"mappedValue\"] =\n              cell.column.columnDef.meta?.getRenderedValueAsString?.(\n                cell.getContext(),\n              )\n          }\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: { selectedCell },\n            },\n          ])\n          handleOnCellSelect()\n        }}\n      />\n    )\n  },\n)\n\nexport const TableWidget: FC<TableWidgetProps> = (props) => {\n  const {\n    emptyState,\n    selectedRow,\n    loading,\n    columns,\n    filter,\n    download,\n    overFlow,\n    pageSize,\n    dataSource,\n    dataSourceJS,\n    dataSourceMode,\n    displayName,\n    defaultSortKey,\n    defaultSortOrder,\n    multiRowSelection,\n    columnSizing,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateOriginalDSLMultiAttr,\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n    triggerMappedEventHandler,\n    ...otherProps\n  } = props\n\n  const tableRef = useRef<TableHandler<any>>(null)\n\n  const handleOnRefresh = useCallback(() => {\n    triggerEventHandler(\"refresh\")\n  }, [triggerEventHandler])\n\n  const handleOnCellSelect = useCallback(() => {\n    triggerEventHandler(\"onCellSelect\")\n  }, [triggerEventHandler])\n\n  const handleOnRowClick = useCallback(() => {\n    triggerEventHandler(\"rowClick\")\n  }, [triggerEventHandler])\n\n  const handleOnRowSelectChange = useCallback(() => {\n    triggerEventHandler(\"rowSelectChange\")\n  }, [triggerEventHandler])\n\n  const handleOnSortingChange = useCallback(() => {\n    triggerEventHandler(\"sortingChange\")\n  }, [triggerEventHandler])\n\n  const handleOnPaginationChange = useCallback(() => {\n    triggerEventHandler(\"paginationChange\")\n  }, [triggerEventHandler])\n\n  const handleOnFiltersChange = useCallback(() => {\n    triggerEventHandler(\"filtersChange\")\n  }, [triggerEventHandler])\n\n  const handleOnClickMenuItem = useCallback(\n    (path: string, index?: number) => {\n      if (isNumber(index)) {\n        triggerMappedEventHandler(\n          \"clickMenuItem\",\n          path,\n          index,\n          (path) => {\n            return convertPathToString(toPath(path).slice(-2))\n          },\n          (dynamicString) => {\n            // if dynamicString contain currentRow return true\n            return dynamicString.includes(\"currentRow\")\n          },\n        )\n      } else {\n        triggerEventHandler(\"clickMenuItem\", path)\n      }\n    },\n    [triggerEventHandler, triggerMappedEventHandler],\n  )\n\n  const isColumnsKey = useCallback(\n    (key: string) => {\n      const columnsKeys = columns.map((item: ColumnItemShape) => {\n        return item.accessorKey\n      })\n      return columnsKeys.includes(key)\n    },\n    [columns],\n  )\n\n  const defaultSort = useMemo(() => {\n    if (!defaultSortKey || defaultSortKey === \"default\") return []\n    if (!isColumnsKey(defaultSortKey)) return []\n\n    return [\n      {\n        id: defaultSortKey,\n        desc: defaultSortOrder === \"descend\",\n      },\n    ]\n  }, [defaultSortOrder, defaultSortKey, isColumnsKey])\n\n  const columnVisibility = useMemo(() => {\n    const res: Record<string, boolean> = {}\n    columns?.forEach((item) => {\n      const { visible, accessorKey } = item as ColumnItemShape\n      if (!visible) {\n        res[accessorKey] = false\n      }\n    })\n    return res\n  }, [columns])\n\n  const columnsDef = useMemo(() => {\n    const res: ColumnItemShape[] = []\n    columns?.forEach((item, index) => {\n      const eventPath = `rowEvents.${index}`\n      const transItem = klona(item) as ColumnItemShape\n      transItem[\"meta\"] = {\n        haveMappedValue: \"mappedValue\" in transItem,\n        getBackgroundColor: (props: CellContext<any, unknown>) => {\n          return getMappedValueFromCellContext(\n            props,\n            transItem.backgroundColor,\n            transItem.fromCurrentRow,\n            \"backgroundColor\",\n            \"\",\n          )\n        },\n        getRenderedValueAsString: (props: CellContext<any, unknown>) => {\n          return getStringPropertyValue(\n            props,\n            transItem.mappedValue,\n            transItem.fromCurrentRow,\n          )\n        },\n        style: applyAlignmentStyle(item.alignment),\n        custom: item.custom,\n      }\n      transItem[\"cell\"] = getCellForType(\n        transItem,\n        eventPath,\n        handleOnClickMenuItem,\n        index,\n      )\n      res.push(transItem)\n    })\n    return res\n  }, [columns, handleOnClickMenuItem])\n\n  const realDataSourceArray = useMemo(() => {\n    if (dataSourceMode === \"dynamic\") {\n      return dataSourceJS ? dataSourceJS : []\n    }\n    return dataSource ? dataSource : []\n  }, [dataSource, dataSourceJS, dataSourceMode])\n\n  const rowEvents = useMemo(() => {\n    const res: Record<string, any> = {}\n    columns?.forEach((item, index) => {\n      const { events } = item as ColumnItemShape\n      if (events) {\n        res[index] = transTableColumnEvent(events, realDataSourceArray.length)\n      }\n    })\n    return res\n  }, [columns, realDataSourceArray?.length])\n\n  useEffect(() => {\n    handleUpdateOriginalDSLMultiAttr(\n      {\n        rowEvents,\n      },\n      true,\n    )\n  }, [handleUpdateOriginalDSLMultiAttr, rowEvents])\n\n  useEffect(() => {\n    // use accessorKey as origin column name\n    const customColumnIndices = columns.reduce<Record<number, string>>(\n      (acc, column, index) => {\n        if (column.custom) {\n          acc[index] = column.header\n        }\n        return acc\n      },\n      {},\n    )\n    const columnNameIndices = columns.reduce<Record<number, string>>(\n      (acc, column, index) => {\n        if (column.custom) {\n          acc[index] = column.header\n        } else {\n          acc[index] = column.accessorKey\n        }\n        return acc\n      },\n      {},\n    )\n    const renamedColumnNames = columns.reduce<Record<string, string>>(\n      (acc, column) => {\n        if (column.header !== column.accessorKey && !column.custom) {\n          acc[column.accessorKey] = column.header\n        }\n        return acc\n      },\n      {},\n    )\n    const columnVisibility = columns.reduce<Record<string, boolean>>(\n      (acc, column) => {\n        if (column.custom) {\n          acc[column.header] = !!column.visible\n        } else {\n          acc[column.accessorKey] = !!column.visible\n        }\n        return acc\n      },\n      {},\n    )\n    const columnMapper = columns.reduce<Record<string, unknown>>(\n      (acc, column) => {\n        if (column.custom) {\n          acc[column.header] = column\n        } else {\n          // use accessorKey as origin column name\n          acc[column.accessorKey] = column\n        }\n        return acc\n      },\n      {},\n    )\n\n    handleUpdateOriginalDSLMultiAttr(\n      {\n        customColumnIndices,\n        columnNameIndices,\n        renamedColumnNames,\n        columnVisibility,\n        columnMapper,\n      },\n      true,\n    )\n  }, [handleUpdateOriginalDSLMultiAttr, columns])\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      clearSelection: () => {\n        tableRef.current?.clearSelection()\n      },\n      clearFilters: () => {\n        tableRef.current?.setGlobalFilters([], \"and\")\n      },\n      setFilters: (filters: unknown, operator: string) => {\n        const filterOperator =\n          operator === \"and\" || operator === \"or\" ? operator : \"and\"\n        if (Array.isArray(filters)) {\n          const filterOptions = filters.filter((value) => {\n            return isFilterOption(value)\n          })\n          tableRef.current?.setGlobalFilters(filterOptions, filterOperator)\n        }\n      },\n      setSort: (sortKey: string, order: string) => {\n        if (isColumnsKey(sortKey)) {\n          tableRef.current?.table.setSorting([\n            {\n              id: sortKey,\n              desc: order !== \"ascend\",\n            },\n          ])\n        }\n      },\n      selectPage: (pageIndex: number) => {\n        if (!isNumber(pageIndex)) {\n          console.error(\"TypeError: value is not a number\")\n          return\n        }\n        tableRef.current?.selectPage(pageIndex)\n      },\n      selectRow: (indexOrIndices: unknown) => {\n        if (isNumber(indexOrIndices)) {\n          tableRef.current?.selectRow({ [indexOrIndices]: true })\n        } else if (Array.isArray(indexOrIndices)) {\n          const rowSelection = indexOrIndices\n            .slice(0, multiRowSelection ? undefined : 1)\n            .reduce((acc, value) => {\n              if (isNumber(value)) {\n                acc[value] = true\n              }\n              console.error(`TypeError: ${value} is not a number`)\n              return acc\n            }, {})\n          tableRef.current?.selectRow(rowSelection)\n        } else {\n          console.error(\"TypeError: value is not a number or array\")\n        }\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    displayName,\n    multiRowSelection,\n    isColumnsKey,\n  ])\n\n  return (\n    <WrappedTable\n      {...otherProps}\n      ref={tableRef}\n      selectedRow={selectedRow}\n      displayName={displayName}\n      data={realDataSourceArray}\n      emptyState={emptyState}\n      loading={loading}\n      filter={filter}\n      columns={columnsDef}\n      columnSizing={columnSizing}\n      download={download}\n      overFlow={overFlow}\n      pageSize={pageSize}\n      columnVisibility={columnVisibility}\n      defaultSort={defaultSort}\n      multiRowSelection={multiRowSelection}\n      triggerMappedEventHandler={triggerMappedEventHandler}\n      updateComponentRuntimeProps={updateComponentRuntimeProps}\n      deleteComponentRuntimeProps={deleteComponentRuntimeProps}\n      handleUpdateOriginalDSLMultiAttr={handleUpdateOriginalDSLMultiAttr}\n      handleUpdateMultiExecutionResult={handleUpdateMultiExecutionResult}\n      handleUpdateDsl={handleUpdateDsl}\n      handleOnCellSelect={handleOnCellSelect}\n      handleOnSortingChange={handleOnSortingChange}\n      handleOnPaginationChange={handleOnPaginationChange}\n      handleOnFiltersChange={handleOnFiltersChange}\n      handleOnRowSelectChange={handleOnRowSelectChange}\n      handleOnRowClick={handleOnRowClick}\n      handleOnRefresh={handleOnRefresh}\n    />\n  )\n}\n\nWrappedTable.displayName = \"WrappedTable\"\nexport default TableWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TableWidget/utils.tsx",
    "content": "import { convertPathToString } from \"@illa-public/dynamic-string\"\nimport { CellContext } from \"@tanstack/table-core\"\nimport { isBoolean } from \"lodash-es\"\nimport {\n  dayjsPro,\n  isArray,\n  isFunction,\n  isNumber,\n  isObject,\n  isString,\n} from \"@illa-design/react\"\nimport { isValidCurrencyCode } from \"@/constants/currency\"\nimport i18n from \"@/i18n/config\"\nimport {\n  ColumnItemShape,\n  Columns,\n  defaultColumnItem,\n} from \"@/widgetLibrary/TableWidget/interface\"\nimport {\n  RenderTableButton,\n  RenderTableButtonGroup,\n  RenderTableIconGroup,\n  RenderTableImage,\n  RenderTableLink,\n  RenderTableMarkdown,\n  RenderTableRating,\n  RenderTableStringCell,\n  RenderTableTag,\n} from \"@/widgetLibrary/TableWidget/renderTableCell\"\n\nconst getOldOrder = (cur: number, oldOrders?: Array<number>) => {\n  return oldOrders?.[cur] ?? -1\n}\n\nexport const tansDataFromOld = (\n  data: Record<any, any>[],\n  oldKeyMap: Record<string, ColumnItemShape>,\n  oldKeyOrder: string[],\n): ColumnItemShape[] => {\n  const reOrderColumns: ColumnItemShape[] = []\n  if (data?.length) {\n    if (isObject(data[0])) {\n      const newKeys = Object.keys(data[0])\n      const filteredOldKeys = oldKeyOrder.filter((key) => {\n        return newKeys.includes(key) || oldKeyMap[key].custom\n      })\n      const finalKeys = filteredOldKeys.concat(\n        newKeys.filter((key) => {\n          return !filteredOldKeys.includes(key)\n        }),\n      )\n      finalKeys.forEach((key, index) => {\n        const oldItem = oldKeyMap[key]\n        if (oldItem) {\n          reOrderColumns.push({\n            ...oldItem,\n            columnIndex: index,\n          })\n        } else {\n          reOrderColumns.push({\n            ...defaultColumnItem,\n            id: key,\n            header: key,\n            accessorKey: key,\n            columnIndex: index,\n          })\n        }\n      })\n    }\n  }\n  return reOrderColumns\n}\n\nexport const tansTableDataToColumns = (\n  data: Record<any, any>[],\n  oldOrders?: Array<number>,\n): ColumnItemShape[] => {\n  const columns: ColumnItemShape[] = []\n  let cur = 0\n  if (data && data.length > 0) {\n    if (isObject(data[0])) {\n      Object.keys(data[0]).forEach((key, index) => {\n        let columnIndex = index\n        if (index === getOldOrder(cur, oldOrders)) {\n          columnIndex += 1\n          cur += 1\n        }\n        columns.push({\n          ...defaultColumnItem,\n          id: key,\n          header: key,\n          accessorKey: key,\n          columnIndex,\n        } as ColumnItemShape)\n      })\n    }\n  }\n  return columns\n}\n\nexport const transTableColumnEvent = (events: any[], columnLength: number) => {\n  let res: Record<string, any> = {}\n  for (let i = 0; i < columnLength; i++) {\n    res[i] = []\n    events.forEach((event) => {\n      const rowEvent: Record<string, any> = { ...event }\n      if (event?.fromCurrentRow && isObject(event?.fromCurrentRow)) {\n        const keys = Object.keys(event?.fromCurrentRow)\n        keys.forEach((key) => {\n          // Determine whether the current key is taken from currentRow, if so, treat it as an array.\n          if (event?.fromCurrentRow?.[key]) {\n            rowEvent[key] = event?.[key]?.[i]\n          } else {\n            rowEvent[key] = event?.[key]\n          }\n        })\n      }\n      res[i].push(rowEvent)\n    })\n  }\n  return res\n}\n\nexport const getConfigFromColumnShapeData = <K extends keyof ColumnItemShape>(\n  itemKey: K,\n  data: ColumnItemShape,\n  rowIndex: number,\n  fromCurrentRow?: Record<K, boolean>,\n): ColumnItemShape[K] => {\n  const value = data[itemKey]\n  if (fromCurrentRow?.[itemKey] && Array.isArray(value)) {\n    return value[rowIndex]\n  }\n  return value\n}\n\nexport const getMappedValue = (\n  rowIndex: number,\n  mappedValue: unknown,\n  fromCurrentRow?: Record<string, boolean>,\n  mappedValuePrefix: string = \"mappedValue\",\n  defaultValue: unknown = \"-\",\n) => {\n  if (mappedValue != null && mappedValue !== \"\") {\n    if (\n      fromCurrentRow?.[`${mappedValuePrefix}`] &&\n      Array.isArray(mappedValue)\n    ) {\n      return mappedValue[rowIndex] ?? defaultValue\n    }\n    return mappedValue ?? defaultValue\n  }\n  return defaultValue\n}\n\nexport const getMappedValueFromCellContext = (\n  props: CellContext<unknown, unknown>,\n  mappedValue: unknown,\n  fromCurrentRow?: Record<string, boolean>,\n  mappedValuePrefix: string = \"mappedValue\",\n  defaultValue: string = \"-\",\n) => {\n  const rowIndex = props.row.index\n\n  return getMappedValue(\n    rowIndex,\n    mappedValue,\n    fromCurrentRow,\n    mappedValuePrefix,\n    defaultValue,\n  )\n}\n\nexport const getPropertyValue = (\n  props: CellContext<unknown, unknown>,\n  mappedValue: unknown,\n  fromCurrentRow?: Record<string, boolean>,\n  mappedValuePrefix: string = \"mappedValue\",\n) => {\n  const value = props.getValue()\n  const index = props.row.index\n\n  if (mappedValue != null && mappedValue !== \"\") {\n    if (\n      fromCurrentRow?.[`${mappedValuePrefix}`] &&\n      Array.isArray(mappedValue)\n    ) {\n      return mappedValue[index] ?? \"-\"\n    }\n    return mappedValue ?? \"-\"\n  }\n\n  return value ?? \"-\"\n}\n\nexport const getStringPropertyValue = (\n  props: CellContext<unknown, unknown>,\n  mappedValue?: unknown,\n  fromCurrentRow?: Record<string, boolean>,\n  mappedValuePrefix: string = \"mappedValue\",\n) => {\n  const value = props.getValue()\n  const index = props.row.index\n\n  if (mappedValue) {\n    if (\n      fromCurrentRow?.[`${mappedValuePrefix}`] &&\n      Array.isArray(mappedValue)\n    ) {\n      return `${mappedValue[index] ?? \"-\"}`\n    }\n    return `${mappedValue}`\n  }\n  if (isObject(value)) {\n    return `${JSON.stringify(value)}`\n  }\n  if (isFunction(value)) {\n    return \"-\"\n  }\n  return `${value ?? \"-\"}`\n}\n\nconst isImageUrl = (str: unknown) => {\n  if (!isString(str)) return false\n  return (\n    str.match(/(http(s?):)([/|.|\\w|\\s|-])*\\.(?:jpg|jpeg|gif|png)/g) !== null\n  )\n}\n\nconst isValidUrl = (str: unknown) => {\n  if (!isString(str)) return false\n  const pattern = new RegExp(\n    /^(((ht|f)tps?):\\/\\/)?(([^!@#$%^&*?.\\s-]([^!@#$%^&*?.\\s]{0,63}[^!@#$%^&*?.\\s])?\\.)+[a-z]{2,6}|(\\d{1,3}\\.){3}\\d{1,3})\\/?/,\n  )\n  return pattern.test(str)\n}\n\nexport const getCellForType = (\n  data: ColumnItemShape,\n  eventPath: string,\n  handleOnClickMenuItem: (path: string, index?: number) => void,\n  columnIndex: number,\n) => {\n  const {\n    type = \"text\",\n    decimalPlaces = 0,\n    format = \"YYYY-MM-DD\",\n    mappedValue,\n    fromCurrentRow,\n    currencyCode = \"XXX\",\n    showThousandsSeparator,\n    tagLabel,\n    tagColor = \"auto\",\n    buttonGroupContent,\n    iconGroupContent,\n    alignment,\n    backgroundColor,\n  } = data\n\n  const locale = i18n.language\n  const columnEventPath = convertPathToString([\"columns\", `${columnIndex}`])\n\n  switch (type) {\n    case Columns.Text:\n      return (props: CellContext<any, any>) => {\n        const value = getStringPropertyValue(props, mappedValue, fromCurrentRow)\n        const bgColor = getMappedValueFromCellContext(\n          props,\n          backgroundColor,\n          fromCurrentRow,\n          \"backgroundColor\",\n        )\n        return RenderTableStringCell({ value, alignment, bgColor })\n      }\n    case Columns.Boolean:\n      return (props: CellContext<any, any>) => {\n        const value = getPropertyValue(props, mappedValue, fromCurrentRow)\n        const currentVal = isBoolean(value) ? value.toString() : \"-\"\n        return RenderTableStringCell({ value: currentVal, alignment })\n      }\n    case Columns.Number:\n    case Columns.Percent:\n    case Columns.Currency:\n      return (props: CellContext<any, any>) => {\n        const value = getStringPropertyValue(props, mappedValue, fromCurrentRow)\n        const formatVal = Number(value)\n        const style = type === Columns.Number ? \"decimal\" : type\n        const numberFormatOptions: Intl.NumberFormatOptions = {\n          style,\n          minimumFractionDigits: decimalPlaces,\n          maximumFractionDigits: decimalPlaces,\n          useGrouping: !!showThousandsSeparator,\n        }\n        if (type === Columns.Currency) {\n          numberFormatOptions.currency = isValidCurrencyCode(currencyCode)\n            ? currencyCode\n            : \"XXX\"\n        }\n\n        const numberFormat = new Intl.NumberFormat(locale, numberFormatOptions)\n        const currentVal = isNumber(formatVal)\n          ? numberFormat.format(formatVal)\n          : \"-\"\n        return RenderTableStringCell({ value: currentVal, alignment })\n      }\n    case Columns.Date:\n    case Columns.Time:\n    case Columns.DateTime:\n      return (props: CellContext<any, any>) => {\n        const value = getStringPropertyValue(props, mappedValue, fromCurrentRow)\n        const currentVal = dayjsPro(value).format(format)\n        return RenderTableStringCell({ value: currentVal, alignment })\n      }\n    case Columns.Link:\n      return (props: CellContext<any, any>) => {\n        const value = getStringPropertyValue(props, mappedValue, fromCurrentRow)\n        return RenderTableLink({\n          cell: props,\n          value,\n          alignment,\n        })\n      }\n    case Columns.Tag:\n      return (props: CellContext<any, any>) => {\n        const value = getPropertyValue(\n          props,\n          tagLabel,\n          fromCurrentRow,\n          \"tagLabel\",\n        )\n        const color = getMappedValueFromCellContext(\n          props,\n          tagColor,\n          fromCurrentRow,\n          \"tagColor\",\n          \"auto\",\n        )\n        return RenderTableTag({\n          cell: props,\n          value: isArray(value) ? value : [`${value}`],\n          color,\n          alignment,\n        })\n      }\n    case Columns.Image:\n      return (props: CellContext<any, any>) => {\n        const value = getStringPropertyValue(props, mappedValue, fromCurrentRow)\n        return RenderTableImage({\n          cell: props,\n          value,\n          data,\n        })\n      }\n    case Columns.Markdown:\n      return (props: CellContext<any, any>) => {\n        const value = getStringPropertyValue(props, mappedValue, fromCurrentRow)\n        return RenderTableMarkdown({ value, alignment })\n      }\n    case Columns.Rating:\n      return (props: CellContext<any, any>) => {\n        const value = getPropertyValue(props, mappedValue, fromCurrentRow)\n        return RenderTableRating({ value, alignment })\n      }\n    case Columns.Button:\n      return (props: CellContext<any, any>) => {\n        const value = getStringPropertyValue(props, mappedValue, fromCurrentRow)\n\n        return RenderTableButton({\n          cell: props,\n          value,\n          data,\n          eventPath,\n          handleOnClickMenuItem,\n        })\n      }\n    case Columns.ButtonGroup:\n      return (props: CellContext<any, any>) => {\n        const rowIndex = props.row.index\n        const value = buttonGroupContent?.map((content) => {\n          const { cellValue, fromCurrentRow } = content\n          return {\n            ...content,\n            cellValue: `${getMappedValue(\n              rowIndex,\n              cellValue,\n              fromCurrentRow,\n              \"cellValue\",\n            )}`,\n          }\n        })\n\n        return RenderTableButtonGroup({\n          cell: props,\n          value,\n          alignment,\n          eventPath: columnEventPath,\n          handleOnClick: handleOnClickMenuItem,\n        })\n      }\n    case Columns.IconGroup:\n      return (props: CellContext<any, any>) => {\n        return RenderTableIconGroup({\n          cell: props,\n          alignment,\n          value: iconGroupContent,\n          eventPath: columnEventPath,\n          handleOnClick: handleOnClickMenuItem,\n        })\n      }\n    default:\n      return (props: CellContext<any, any>) => {\n        const value = getPropertyValue(props, mappedValue, fromCurrentRow)\n        const stringValue = getStringPropertyValue(\n          props,\n          mappedValue,\n          fromCurrentRow,\n        )\n        if (isBoolean(value)) {\n          return RenderTableStringCell({ value: value.toString(), alignment })\n        } else if (isNumber(value)) {\n          return RenderTableStringCell({\n            value: value.toFixed(decimalPlaces),\n            alignment,\n          })\n        } else if (!isNaN(Number(value))) {\n          return RenderTableStringCell({\n            value: Number(value).toFixed(decimalPlaces),\n            alignment,\n          })\n        } else if (isImageUrl(value)) {\n          return RenderTableImage({\n            cell: props,\n            value: stringValue,\n            data,\n          })\n        } else if (isValidUrl(value)) {\n          return RenderTableLink({\n            cell: props,\n            value: stringValue,\n            alignment,\n          })\n        } else {\n          return RenderTableStringCell({\n            value: stringValue,\n            alignment,\n          })\n        }\n      }\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TableWidget/widgetConfig.tsx",
    "content": "import TableWidgetIcon from \"@/assets/widgetCover/table.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { tansTableDataToColumns } from \"@/widgetLibrary/TableWidget/utils\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nconst originData = [\n  {\n    month: \"April\",\n    users: 3700,\n    incomes: 4000,\n  },\n  {\n    month: \"May\",\n    users: 5400,\n    incomes: 8700,\n  },\n  {\n    month: \"June\",\n    users: 6000,\n    incomes: 12000,\n  },\n  {\n    month: \"July\",\n    users: 8000,\n    incomes: 14000,\n  },\n]\n\nexport const TABLE_WIDGET_CONFIG: WidgetConfig = {\n  displayName: \"table\",\n  widgetName: i18n.t(\"widget.table.name\"),\n  h: 40,\n  w: 16,\n  type: \"TABLE_WIDGET\",\n  icon: <TableWidgetIcon />,\n  keywords: [\"Table\", \"表格\"],\n  sessionType: \"DATA\",\n  version: 0,\n  defaults: initTableWidgetDefaultProps(),\n}\n\nexport function initTableWidgetDefaultProps() {\n  return {\n    dataSourceMode: \"dynamic\",\n    dataSourceJS: `{{${JSON.stringify(originData, null, \"  \")}}}`,\n    columns: tansTableDataToColumns(originData),\n    defaultSortKey: \"default\",\n    defaultSortOrder: \"ascend\",\n    emptyState: \"No rows found\",\n    overFlow: \"pagination\",\n    download: false,\n    filter: false,\n    pageSize: `{{10}}`,\n    pageIndex: 0,\n    paginationOffset: 0,\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TabsWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const TABS_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TabsWidget/index.tsx",
    "content": "export { TABS_PANEL_CONFIG } from \"./panelConfig\"\nexport { TABS_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { TABS_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TabsWidget/interface.tsx",
    "content": "import { TabsProps } from \"@illa-design/react\"\nimport { viewListItemShaper } from \"@/widgetLibrary/ContainerWidget/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedTabsProps\n  extends Omit<TabsProps, \"w\" | \"h\">,\n    BaseWidgetProps {\n  value?: string\n  disabled?: boolean\n  viewList?: viewListItemShaper[]\n  tabList?: viewListItemShaper[]\n  linkWidgetDisplayName?: string\n  handleOnChange?: () => void\n  handleUpdateExecution?: (updateSliceItem: Record<string, any>) => void\n}\n\nexport interface TabsWidgetProps\n  extends WrappedTabsProps,\n    BaseWidgetProps,\n    TooltipWrapperProps {\n  navigateContainer?: boolean\n  linkWidgetDisplayName?: string\n  currentKey?: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TabsWidget/panelConfig.tsx",
    "content": "import {\n  HorizontalCenterIcon,\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n  VerticalEndIcon,\n  VerticalStartIcon,\n} from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { TABS_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/TabsWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"tabs\"\nexport const TABS_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-tabs`,\n    groupName: i18n.t(\"editor.inspect.setter_group.tabs\"),\n    children: [\n      {\n        id: `${baseWidgetName}-column-decimalPlaces`,\n        labelName: i18n.t(\"editor.inspect.setter_label.container\"),\n        attrName: \"linkWidgetDisplayName\",\n        bindAttrName: [\"navigateContainer\"],\n        setterType: \"TABS_CONTAINER_SELECT_SETTER\",\n        useCustomLayout: true,\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-tabList`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        useCustomLayout: true,\n        attrName: \"tabList\",\n        setterType: \"TABS_LIST_SETTER\",\n        bindAttrName: [\"navigateContainer\"],\n        shown: (value) => !value,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-tabList-key`,\n            labelName: i18n.t(\"editor.inspect.setter_label.key\"),\n            attrName: \"key\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-tabList-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-tabList-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n          {\n            id: `${baseWidgetName}-tabList-hidden`,\n            labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n            attrName: \"hidden\",\n            setterType: \"DYNAMIC_SWITCH_SETTER\",\n            useCustomLayout: true,\n            openDynamic: true,\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-views-list`,\n        labelName: i18n.t(\"editor.inspect.setter_label.data_source\"),\n        useCustomLayout: true,\n        attrName: \"viewList\",\n        setterType: \"CONTAINER_VIEW_SETTER\",\n        bindAttrName: [\"navigateContainer\", \"linkWidgetDisplayName\"],\n        shown: (isLink, id) => isLink && id,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-viewList-key`,\n            labelName: i18n.t(\"editor.inspect.setter_label.key\"),\n            attrName: \"key\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-viewList-label`,\n            labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n            attrName: \"label\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-viewList-disabled`,\n            labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n            attrName: \"disabled\",\n            setterType: \"INPUT_SETTER\",\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n          {\n            id: `${baseWidgetName}-viewList-hidden`,\n            labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n            attrName: \"hidden\",\n            setterType: \"DYNAMIC_SWITCH_SETTER\",\n            useCustomLayout: true,\n            openDynamic: true,\n            expectedType: VALIDATION_TYPES.BOOLEAN,\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-views-default`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_tab\"),\n        attrName: \"currentKey\",\n        bindAttrName: [\"navigateContainer\"],\n        shown: (value) => !value,\n        setterType: \"TABS_DEFAULT_KEY_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          TABS_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-startAdornment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-layout`,\n        labelName: i18n.t(\"editor.inspect.setter_label.layout\"),\n        setterType: \"RADIO_GROUP_SETTER\",\n        attrName: \"tabPosition\",\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <VerticalStartIcon />,\n            value: \"top\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n          {\n            label: <VerticalEndIcon />,\n            value: \"bottom\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-align`,\n        labelName: i18n.t(\"editor.inspect.setter_label.align\"),\n        attrName: \"align\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"tabPosition\"],\n        shown: (tabPosition) =>\n          tabPosition === \"top\" || tabPosition === \"bottom\",\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"flex-start\",\n          },\n          {\n            label: <HorizontalCenterIcon />,\n            value: \"center\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"flex-end\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-color`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.text\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TabsWidget/style.tsx",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { HorizontalAlign } from \"@/widgetLibrary/TextWidget/interface\"\n\nexport function applyAlignStyle(\n  horizontalAlign?: HorizontalAlign,\n): SerializedStyles {\n  return css`\n    width: 100%;\n    height: 100%;\n    display: flex;\n    justify-content: ${horizontalAlign};\n  `\n}\n\nexport const fullWidthAndFullHeightStyle = css`\n  width: 100%;\n  height: 100%;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TabsWidget/tabs.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { TabPane, Tabs } from \"@illa-design/react\"\nimport { getComponentMap } from \"@/redux/currentApp/components/componentsSelector\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { TabsWidgetProps, WrappedTabsProps } from \"./interface\"\nimport { fullWidthAndFullHeightStyle } from \"./style\"\n\nexport const WrappedTabs: FC<WrappedTabsProps> = (props) => {\n  const {\n    align,\n    activeKey,\n    disabled,\n    tabList = [],\n    colorScheme,\n    tabPosition,\n    handleOnChange,\n    handleUpdateExecution,\n  } = props\n\n  return (\n    <Tabs\n      w={\"100%\"}\n      align={align}\n      colorScheme={colorScheme}\n      tabPosition={tabPosition}\n      activeKey={activeKey}\n      onChange={(value) => {\n        new Promise((resolve) => {\n          const currentIndex = tabList?.findIndex((view) => view.key === value)\n          handleUpdateExecution?.({\n            currentKey: value,\n            currentIndex,\n          })\n          resolve(true)\n        }).then(() => {\n          handleOnChange?.()\n        })\n      }}\n    >\n      {Array.isArray(tabList) &&\n        tabList?.map((item) => {\n          if (item.hidden) return null\n          return (\n            <TabPane\n              key={item.key}\n              title={item.label}\n              disabled={disabled || item.disabled}\n            />\n          )\n        })}\n    </Tabs>\n  )\n}\n\nWrappedTabs.displayName = \"WrappedTabs\"\n\nexport const TabsWidget: FC<TabsWidgetProps> = (props) => {\n  const {\n    value,\n    align,\n    disabled,\n    navigateContainer,\n    currentKey,\n    tabList = [],\n    viewList,\n    displayName,\n    linkWidgetDisplayName,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    tooltipText,\n    colorScheme,\n    tabPosition,\n    triggerEventHandler,\n    updateComponentHeight,\n    handleUpdateMultiExecutionResult,\n  } = props\n\n  const components = useSelector(getComponentMap)\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: string) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: undefined })\n      },\n    })\n\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    displayName,\n    value,\n    updateComponentRuntimeProps,\n    handleUpdateDsl,\n    deleteComponentRuntimeProps,\n  ])\n\n  const list = useMemo(() => {\n    if (navigateContainer) return viewList\n    return tabList\n  }, [navigateContainer, tabList, viewList])\n\n  const handleUpdateExecution = useCallback(\n    (updateSliceItem: Record<string, any>) => {\n      if (navigateContainer && linkWidgetDisplayName) {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName: linkWidgetDisplayName,\n            value: updateSliceItem,\n          },\n        ])\n        const targetLinkedDisplayNames = get(\n          components,\n          `${linkWidgetDisplayName}.props.linkWidgetDisplayName`,\n          [],\n        )\n        if (Array.isArray(targetLinkedDisplayNames)) {\n          const curUpdateSliceItem = targetLinkedDisplayNames\n            .filter((name) => name !== displayName)\n            .map((name) => ({\n              displayName: name,\n              value: updateSliceItem,\n            }))\n          handleUpdateMultiExecutionResult(curUpdateSliceItem)\n        }\n        targetLinkedDisplayNames &&\n          Array.isArray(targetLinkedDisplayNames) &&\n          targetLinkedDisplayNames.forEach((targetLinkedDisplayName) => {\n            targetLinkedDisplayName !== displayName &&\n              handleUpdateMultiExecutionResult([\n                {\n                  displayName: targetLinkedDisplayName,\n                  value: updateSliceItem,\n                },\n              ])\n          })\n      }\n\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: updateSliceItem,\n        },\n      ])\n    },\n    [\n      components,\n      displayName,\n      handleUpdateMultiExecutionResult,\n      linkWidgetDisplayName,\n      navigateContainer,\n    ],\n  )\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={fullWidthAndFullHeightStyle}>\n          <WrappedTabs\n            {...props}\n            tabList={list}\n            value={value}\n            align={align}\n            activeKey={currentKey}\n            colorScheme={colorScheme}\n            tabPosition={tabPosition}\n            disabled={disabled}\n            linkWidgetDisplayName={linkWidgetDisplayName}\n            handleUpdateExecution={handleUpdateExecution}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n    </AutoHeightContainer>\n  )\n}\n\nTabsWidget.displayName = \"TabsWidget\"\nexport default TabsWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TabsWidget/widgetConfig.tsx",
    "content": "import { v4 } from \"uuid\"\nimport TabsWidgetIcon from \"@/assets/widgetCover/tabs.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nconst defaultTabList = [\n  { id: v4(), key: \"Tab 1\", label: \"Tab 1\" },\n  { id: v4(), key: \"Tab 2\", label: \"Tab 2\" },\n  { id: v4(), key: \"Tab 3\", label: \"Tab 3\" },\n]\n\nexport const TABS_WIDGET_CONFIG: WidgetConfig = {\n  displayName: \"tabs\",\n  widgetName: i18n.t(\"widget.tabs.name\"),\n  h: 6,\n  w: 6,\n  type: \"TABS_WIDGET\",\n  icon: <TabsWidgetIcon />,\n  keywords: [\"Tabs\", \"选项卡\"],\n  sessionType: \"NAVIGATION\",\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    tabList: defaultTabList,\n    viewList: [],\n    align: \"flex-start\",\n    colorScheme: \"blue\",\n    tabPosition: \"top\",\n    currentIndex: 0,\n    currentKey: \"Tab 1\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/components/MorePanel/index.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC } from \"react\"\nimport {\n  getHashCode,\n  getPreColor,\n} from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/utils\"\nimport { getSafeStringValue } from \"../../utils\"\nimport TagContainer from \"../TagContainer\"\nimport { MorePanelProps } from \"./interface\"\nimport { panelContainerStyle } from \"./style\"\n\nconst MorePanel: FC<MorePanelProps> = ({\n  values,\n  tagColorMap,\n  handleOnSelect,\n}) => {\n  return (\n    <div css={panelContainerStyle}>\n      {values.map((v, i) => {\n        const s = getSafeStringValue(v)\n        const c = get(tagColorMap, s) ?? getPreColor(getHashCode(s))\n        if (!s) return null\n        return (\n          <TagContainer\n            key={`${v}${i}`}\n            c={c}\n            v={s}\n            handleOnSelect={handleOnSelect}\n          />\n        )\n      })}\n    </div>\n  )\n}\n\nexport default MorePanel\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/components/MorePanel/interface.ts",
    "content": "export interface MorePanelProps {\n  values: string[]\n  tagColorMap: Record<string, string>\n  handleOnSelect?: (v: string) => void\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/components/MorePanel/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const panelContainerStyle = css`\n  max-width: 240px;\n  padding: 8px;\n  display: flex;\n  flex-wrap: wrap;\n  gap: 8px;\n  border-radius: 8px;\n  border: 1px solid ${getColor(\"gray\", \"08\")};\n  background: ${getColor(\"white\", \"01\")};\n  box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.16);\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/components/TagContainer/index.tsx",
    "content": "import { FC, useEffect, useRef } from \"react\"\nimport { Tag } from \"@illa-design/react\"\nimport { TagContainerProps } from \"./interface\"\n\nconst TagContainer: FC<TagContainerProps> = ({\n  v,\n  c,\n  allowWrap,\n  handleUpdateWith,\n  handleOnSelect,\n}) => {\n  const ref = useRef<HTMLDivElement | null>(null)\n\n  useEffect(() => {\n    if (!allowWrap) {\n      handleUpdateWith?.(ref.current?.clientWidth || 0)\n    }\n  }, [allowWrap, handleUpdateWith])\n  return (\n    <Tag\n      ref={ref}\n      colorScheme={c}\n      clickable\n      onClick={() => handleOnSelect?.(v)}\n    >\n      {v}\n    </Tag>\n  )\n}\n\nexport default TagContainer\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/components/TagContainer/interface.ts",
    "content": "export interface TagContainerProps {\n  v: string\n  c: string\n  allowWrap?: boolean\n  handleUpdateWith?: (v: number) => void\n  handleOnSelect?: (v: string) => void\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/constants.ts",
    "content": "export const GAP = 8\nexport const OVERFLOW_GAP = 32\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const TAGS_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.select\",\n      ),\n      value: \"select\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/index.tsx",
    "content": "export { TAGS_PANEL_CONFIG } from \"./panelConfig\"\nexport { TAGS_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { TAGS_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/interface.ts",
    "content": "import LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"../interface\"\n\nexport type Alignment = \"flex-start\" | \"center\" | \"flex-end\"\nexport interface WrappedTagsProps {\n  width: number\n  value?: string[]\n  allowWrap?: boolean\n  tagColor?: Record<string, string>\n  alignment?: Alignment\n  handleOnSelect?: (value: string) => void\n}\n\nexport interface TagsWidgetProps\n  extends WrappedTagsProps,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps {\n  disabled?: boolean\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/panelConfig.tsx",
    "content": "import {\n  HorizontalCenterIcon,\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n} from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { TAGS_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n\nconst baseWidgetName = \"tags\"\nexport const TAGS_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.input_default_value\"),\n        attrName: \"value\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          TAGS_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-allowWrap`,\n        labelName: i18n.t(\"editor.inspect.setter_label.slider.allow_wrapping\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.slider.allow_wrapping\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"allowWrap\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-layout-alignment`,\n        setterType: \"RADIO_GROUP_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"alignment\",\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"flex-start\",\n          },\n          {\n            label: <HorizontalCenterIcon />,\n            value: \"center\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"flex-end\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-styles`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.tag_color\"),\n            labelDesc: i18n.t(\"editor.inspect.setter_tips.tag_color\"),\n            attrName: \"tagColor\",\n            setterType: \"INPUT_SETTER\",\n            useCustomLayout: true,\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { GAP } from \"./constants\"\nimport { Alignment } from \"./interface\"\n\nexport const wrapperContainerStyle = (\n  minW: number,\n  alignment: Alignment = \"flex-start\",\n  allowWrap?: boolean,\n) => css`\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: ${alignment};\n  gap: ${GAP}px;\n  flex-wrap: ${allowWrap ? \"wrap\" : \"nowrap\"};\n  min-width: ${minW}px;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/tags.tsx",
    "content": "import { get } from \"lodash-es\"\nimport { FC, useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport useMeasure from \"react-use-measure\"\nimport { Trigger, isArray, isObject } from \"@illa-design/react\"\nimport {\n  getHashCode,\n  getPreColor,\n} from \"@/page/App/components/InspectPanel/PanelSetters/DataGridSetter/utils\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport MorePanel from \"./components/MorePanel\"\nimport TagContainer from \"./components/TagContainer\"\nimport { GAP, OVERFLOW_GAP } from \"./constants\"\nimport { TagsWidgetProps, WrappedTagsProps } from \"./interface\"\nimport { wrapperContainerStyle } from \"./style\"\nimport { getSafeStringValue } from \"./utils\"\n\nexport const WrappedTags: FC<WrappedTagsProps> = (props) => {\n  const { value = [], tagColor, allowWrap, alignment, handleOnSelect } = props\n\n  const [sliceIndex, setSliceIndex] = useState(value.length)\n  const tagColorMap = isObject(tagColor) ? tagColor : {}\n  const widthArray = useRef<number[]>(new Array(value.length).fill(0))\n  const overflowWidth = useRef<number>(OVERFLOW_GAP)\n\n  const [container, containerBounds] = useMeasure()\n  const containerWidth = containerBounds.width - 6\n\n  const handleUpdateWithArray = useCallback(\n    (width: number, index: number) => {\n      if (width !== 0) {\n        const array = widthArray.current\n        const w =\n          index === 0\n            ? width\n            : width + array[index - 1] + (index === value.length - 1 ? 0 : GAP)\n        array[index] = w\n        widthArray.current = array\n      }\n    },\n    [value.length],\n  )\n\n  const realValue = useMemo(() => {\n    if (allowWrap || sliceIndex === widthArray.current.length) {\n      return value\n    }\n    return value.slice(0, sliceIndex + 1)\n  }, [sliceIndex, value, allowWrap])\n\n  useEffect(() => {\n    if (allowWrap) return\n    const dfs = (index: number) => {\n      if (index < 0) return\n      if (index === widthArray.current.length - 1) {\n        if (widthArray.current[index] > containerWidth) {\n          dfs(index - 1)\n        } else {\n          setSliceIndex(widthArray.current.length)\n        }\n      } else {\n        if (\n          widthArray.current[index] + GAP + overflowWidth.current >\n          containerWidth\n        ) {\n          dfs(index - 1)\n        } else {\n          setSliceIndex(index)\n        }\n      }\n    }\n    dfs(widthArray.current.length - 1)\n  }, [allowWrap, value.length, containerWidth])\n\n  useEffect(() => {\n    widthArray.current = new Array(value.length).fill(0)\n    setSliceIndex(value.length)\n  }, [value.length])\n\n  return (\n    <div\n      css={wrapperContainerStyle(\n        widthArray.current[0] + overflowWidth.current,\n        alignment,\n        allowWrap,\n      )}\n      ref={container}\n    >\n      {realValue.map((v, i) => {\n        const s = getSafeStringValue(v)\n        const c = get(tagColorMap, s) ?? getPreColor(getHashCode(s))\n        if (!s) return null\n        return (\n          <TagContainer\n            key={`${v}${i}`}\n            c={c}\n            v={s}\n            allowWrap={allowWrap}\n            handleUpdateWith={(w) => handleUpdateWithArray(w, i)}\n            handleOnSelect={handleOnSelect}\n          />\n        )\n      })}\n      {!allowWrap && !!value.length && sliceIndex !== value.length && (\n        <Trigger\n          position=\"bottom\"\n          withoutPadding\n          withoutShadow\n          colorScheme=\"white\"\n          content={\n            <MorePanel\n              values={value.slice(sliceIndex + 1)}\n              tagColorMap={tagColorMap}\n              handleOnSelect={handleOnSelect}\n            />\n          }\n        >\n          <div>\n            <TagContainer\n              c={getPreColor(getHashCode(`${value.length - sliceIndex - 1}`))}\n              v={`+${value.length - sliceIndex - 1}`}\n              handleUpdateWith={(w) => (overflowWidth.current = w)}\n            />\n          </div>\n        </Trigger>\n      )}\n    </div>\n  )\n}\n\nWrappedTags.displayName = \"WrappedTags\"\n\nexport const TagsWidget: FC<TagsWidgetProps> = (props) => {\n  const {\n    displayName,\n    tooltipText,\n    disabled,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    triggerEventHandler,\n    updateComponentHeight,\n  } = props\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: unknown) => {\n        if (!isArray(value)) return\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: value || [],\n            },\n          },\n        ])\n      },\n      clearValue: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: undefined,\n            },\n          },\n        ])\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    displayName,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n  ])\n\n  const handleOnSelect = useCallback(\n    (value: string) => {\n      if (disabled) return\n      new Promise((resolve) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              selectedTag: value,\n            },\n          },\n        ])\n        resolve(true)\n      }).then(() => {\n        triggerEventHandler(\"select\")\n      })\n    },\n    [\n      disabled,\n      displayName,\n      handleUpdateMultiExecutionResult,\n      triggerEventHandler,\n    ],\n  )\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div>\n          <WrappedTags {...props} handleOnSelect={handleOnSelect} />\n        </div>\n      </TooltipWrapper>\n    </AutoHeightContainer>\n  )\n}\nTagsWidget.displayName = \"TagsWidget\"\nexport default TagsWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/utils.ts",
    "content": "import { isObject } from \"@illa-design/react\"\n\nexport const getSafeStringValue = (value: unknown) => {\n  if (isObject(value) || Array.isArray(value)) {\n    return JSON.stringify(value)\n  } else {\n    return `${value}`\n  }\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TagsWidget/widgetConfig.tsx",
    "content": "import TagsWidgetIcon from \"@/assets/widgetCover/tags.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const TAGS_WIDGET_CONFIG: WidgetConfig = {\n  displayName: \"tags\",\n  type: \"TAGS_WIDGET\",\n  widgetName: i18n.t(\"widget.tags.name\"),\n  icon: <TagsWidgetIcon />,\n  keywords: [\"tags\", \"标签\"],\n  sessionType: \"PRESENTATION\",\n  w: 8,\n  h: 3,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    value: '{{[\"Dog\", \"Cat\", \"Rabbit\"]}}',\n    alignment: \"flex-start\",\n    hidden: false,\n    selectedTag: undefined,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextAreaWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const TEXTAREA_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.focus\",\n      ),\n      value: \"focus\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.blur\",\n      ),\n      value: \"blur\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"focus\", \"validate\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextAreaWidget/index.tsx",
    "content": "export { TEXTAREA_PANEL_CONFIG } from \"./panelConfig\"\nexport { TEXTAREA_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { TEXTAREA_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextAreaWidget/interface.tsx",
    "content": "import { TextAreaProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedTextareaProps\n  extends Pick<\n      TextAreaProps,\n      \"placeholder\" | \"disabled\" | \"readOnly\" | \"maxLength\" | \"colorScheme\"\n    >,\n    BaseWidgetProps,\n    LabelProps {\n  showCharacterCount?: TextAreaProps[\"showWordLimit\"]\n  value?: string\n  allowClear?: TextAreaProps[\"allowClear\"]\n  handleOnChange: (value: string) => void\n  handleOnFocus?: () => void\n  handleOnBlur?: () => void\n  maxLength?: number\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  dynamicMinHeight?: number\n  dynamicMaxHeight?: number\n  getValidateMessage: (value: string) => string\n  showValidationMessage: boolean\n}\n\nexport interface TextareaWidgetProps\n  extends WrappedTextareaProps,\n    BaseWidgetProps,\n    TooltipWrapperProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  validateMessage: string\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  dynamicMinHeight?: number\n  dynamicMaxHeight?: number\n  defaultValue?: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextAreaWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { TEXTAREA_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/TextAreaWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"text-area\"\nexport const TEXTAREA_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-defaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.input_default_value\"),\n        attrName: \"defaultValue\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"placeholder\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\", \"labelPosition\"],\n        shown: (hidden, position) => !hidden && position !== \"top\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          TEXTAREA_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        placeholder: \"{{false}}\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-readonly`,\n        labelName: i18n.t(\"editor.inspect.setter_label.read_only\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.read_only\"),\n        attrName: \"readOnly\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-Adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        attrName: \"allowClear\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-showChartCount`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_character_count\"),\n        attrName: \"showCharacterCount\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-regex`,\n        labelName: i18n.t(\"editor.inspect.setter_label.regex\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"regex\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-max`,\n        labelName: i18n.t(\"editor.inspect.setter_label.max_length\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"maxLength\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-min`,\n        labelName: i18n.t(\"editor.inspect.setter_label.min_length\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"minLength\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-height`,\n        labelName: i18n.t(\"editor.inspect.setter_label.height\"),\n        attrName: \"dynamicHeight\",\n        setterType: \"HEIGHT_MODE_SELECT\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.fixed\"),\n            value: \"fixed\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_limited\"),\n            value: \"limited\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_height\"),\n            value: \"auto\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-colors`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-colors-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            attrName: \"colorScheme\",\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextAreaWidget/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { VALIDATE_MESSAGE_HEIGHT } from \"@/page/App/components/ScaleSquare/constant/widget\"\n\nexport const getTextareaContentContainerStyle = (\n  labelPosition: \"left\" | \"right\" | \"top\" = \"left\",\n  showValidationMessage: boolean,\n) => {\n  return css`\n    display: flex;\n    height: ${showValidationMessage\n      ? `calc(100% - ${VALIDATE_MESSAGE_HEIGHT})px`\n      : \"100%\"};\n    flex-direction: ${labelPosition === \"top\" ? \"column\" : \"row\"};\n    & textarea {\n      resize: none;\n    }\n  `\n}\n\nexport const textAreaStyle = css`\n  flex: 1;\n  width: 100%;\n  overflow-y: auto;\n  & > textarea:hover {\n    z-index: 0;\n  }\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextAreaWidget/textArea.tsx",
    "content": "import { debounce } from \"lodash-es\"\nimport {\n  FC,\n  forwardRef,\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport useMeasure from \"react-use-measure\"\nimport { TextArea } from \"@illa-design/react\"\nimport { UNIT_HEIGHT } from \"@/page/App/components/DotPanel/constant/canvas\"\nimport {\n  LABEL_TOP_UNIT_HEIGHT,\n  VALIDATE_MESSAGE_HEIGHT,\n} from \"@/page/App/components/ScaleSquare/constant/widget\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport {\n  TextareaWidgetProps,\n  WrappedTextareaProps,\n} from \"@/widgetLibrary/TextAreaWidget/interface\"\nimport {\n  getTextareaContentContainerStyle,\n  textAreaStyle,\n} from \"@/widgetLibrary/TextAreaWidget/style\"\nimport { getValidateMessageFunc } from \"./utils\"\n\nexport const WrappedTextarea = forwardRef<\n  HTMLTextAreaElement,\n  WrappedTextareaProps\n>((props, ref) => {\n  const {\n    value,\n    placeholder,\n    disabled,\n    readOnly,\n    showCharacterCount,\n    colorScheme,\n    handleOnChange,\n    handleOnFocus,\n    handleOnBlur,\n    allowClear,\n    maxLength,\n    dynamicHeight,\n    dynamicMinHeight = 0,\n    dynamicMaxHeight = Infinity,\n    labelPosition,\n    showValidationMessage,\n  } = props\n\n  const limitedStyle = useMemo(() => {\n    const limitLinePosition =\n      labelPosition === \"top\" ? LABEL_TOP_UNIT_HEIGHT : UNIT_HEIGHT\n    const minH = `${\n      showValidationMessage\n        ? dynamicMinHeight - limitLinePosition - VALIDATE_MESSAGE_HEIGHT\n        : dynamicMinHeight - limitLinePosition\n    }px`\n    const maxH = `${\n      showValidationMessage\n        ? dynamicMaxHeight - limitLinePosition - VALIDATE_MESSAGE_HEIGHT\n        : dynamicMaxHeight - limitLinePosition\n    }px`\n    if (dynamicHeight === \"limited\") {\n      return {\n        minH,\n        maxH,\n        h: \"auto\",\n      }\n    }\n    if (dynamicHeight === \"fixed\") {\n      return {\n        maxH: showValidationMessage\n          ? `calc(100% - ${limitLinePosition + VALIDATE_MESSAGE_HEIGHT})px`\n          : `calc(100% - ${limitLinePosition})px`,\n        h: \"auto\",\n      }\n    }\n    return {\n      minH: showValidationMessage\n        ? `calc(100% - ${VALIDATE_MESSAGE_HEIGHT})px`\n        : \"100%\",\n      maxH: showValidationMessage\n        ? `calc(100% - ${VALIDATE_MESSAGE_HEIGHT})px`\n        : \"100%\",\n      h: \"auto\",\n    }\n  }, [\n    dynamicHeight,\n    dynamicMaxHeight,\n    dynamicMinHeight,\n    labelPosition,\n    showValidationMessage,\n  ])\n\n  return (\n    <TextArea\n      css={textAreaStyle}\n      {...limitedStyle}\n      textAreaRef={ref}\n      value={value}\n      placeholder={placeholder}\n      disabled={disabled}\n      readOnly={readOnly}\n      maxLength={maxLength}\n      showWordLimit={showCharacterCount}\n      colorScheme={colorScheme}\n      allowClear={allowClear}\n      onFocus={handleOnFocus}\n      onBlur={handleOnBlur}\n      onChange={handleOnChange}\n      onClear={() => {\n        handleOnChange(\"\")\n      }}\n      autoSize\n    />\n  )\n})\n\nWrappedTextarea.displayName = \"WrappedTextarea\"\n\nexport const TextareaWidget: FC<TextareaWidgetProps> = (props) => {\n  const {\n    value,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    minLength,\n    maxLength,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    pattern,\n    regex,\n    customRule,\n    hideValidationMessage,\n    updateComponentHeight,\n    validateMessage,\n    triggerEventHandler,\n    dynamicHeight = \"fixed\",\n    dynamicMinHeight,\n    dynamicMaxHeight,\n    defaultValue,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  } = props\n\n  const textareaRef = useRef<HTMLTextAreaElement>(null)\n  const textareaWrapperRef = useRef<HTMLDivElement>(null)\n  const [messageWrapperRef, bounds] = useMeasure()\n  const [textAreaValue, setTextAreaValue] = useState(defaultValue)\n\n  useEffect(() => {\n    setTextAreaValue(defaultValue)\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          value: defaultValue || \"\",\n        },\n      },\n    ])\n  }, [defaultValue, displayName, handleUpdateMultiExecutionResult])\n\n  useEffect(() => {\n    if (textareaWrapperRef.current) {\n      updateComponentHeight?.(textareaWrapperRef.current?.clientHeight)\n    }\n  }, [validateMessage, labelPosition, updateComponentHeight])\n\n  const handleValidate = useCallback(\n    (value?: string) => {\n      const message = getValidateMessageFunc(value, {\n        hideValidationMessage: hideValidationMessage,\n        pattern: pattern,\n        regex: regex,\n        minLength: minLength,\n        maxLength: maxLength,\n        required: required,\n        customRule: customRule,\n      })\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [\n      hideValidationMessage,\n      pattern,\n      regex,\n      minLength,\n      maxLength,\n      required,\n      customRule,\n      handleUpdateDsl,\n    ],\n  )\n\n  const debounceOnChange = useRef(\n    debounce(\n      (\n        value: string,\n        triggerEventHandler: TextareaWidgetProps[\"triggerEventHandler\"],\n        options?: {\n          hideValidationMessage?: TextareaWidgetProps[\"hideValidationMessage\"]\n          pattern?: TextareaWidgetProps[\"pattern\"]\n          regex?: TextareaWidgetProps[\"regex\"]\n          minLength?: TextareaWidgetProps[\"minLength\"]\n          maxLength?: TextareaWidgetProps[\"maxLength\"]\n          required?: TextareaWidgetProps[\"required\"]\n          customRule?: TextareaWidgetProps[\"customRule\"]\n        },\n      ) => {\n        new Promise((resolve) => {\n          const message = getValidateMessageFunc(value, options)\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                value: value || \"\",\n                validateMessage: message,\n              },\n            },\n          ])\n          resolve(true)\n        }).then(() => {\n          triggerEventHandler(\"change\")\n        })\n      },\n      180,\n    ),\n  )\n\n  const handleOnChange = useCallback(\n    (value: string) => {\n      setTextAreaValue(value)\n      debounceOnChange.current(value, triggerEventHandler, {\n        hideValidationMessage: hideValidationMessage,\n        pattern: pattern,\n        regex: regex,\n        minLength: minLength,\n        maxLength: maxLength,\n        required: required,\n        customRule: customRule,\n      })\n    },\n    [\n      customRule,\n      hideValidationMessage,\n      maxLength,\n      minLength,\n      pattern,\n      regex,\n      required,\n      triggerEventHandler,\n    ],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      focus: () => {\n        textareaRef.current?.focus()\n      },\n      setValue: (value: boolean | string | number | void) => {\n        if (typeof value === \"string\") {\n          handleOnChange(value)\n        } else {\n          handleOnChange(\"\")\n        }\n      },\n      clearValue: () => {\n        handleOnChange(\"\")\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {\n        handleUpdateDsl({\n          validateMessage: \"\",\n        })\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleOnChange,\n    handleUpdateDsl,\n    handleValidate,\n    updateComponentRuntimeProps,\n    value,\n  ])\n\n  const handleOnFocus = useCallback(() => {\n    triggerEventHandler(\"focus\")\n  }, [triggerEventHandler])\n\n  const handleOnBlur = useCallback(() => {\n    triggerEventHandler(\"blur\")\n  }, [triggerEventHandler])\n\n  const enableAutoHeight = useMemo(() => {\n    switch (dynamicHeight) {\n      case \"auto\":\n        return true\n      case \"limited\":\n        return true\n      case \"fixed\":\n      default:\n        return false\n    }\n  }, [dynamicHeight])\n\n  const minMaxValueRef = useRef<{ min?: number; max?: number }>({})\n  const showValidationMessage = useMemo(() => {\n    return Boolean(!hideValidationMessage && validateMessage)\n  }, [hideValidationMessage, validateMessage])\n\n  const getMinMaxHeight = (\n    width: number,\n    height: number,\n    minMaxHeight?: number,\n  ) => {\n    if (minMaxHeight === undefined) {\n      return minMaxHeight\n    }\n    return minMaxHeight - (width + height)\n  }\n\n  const minValue =\n    labelPosition === \"top\" && label\n      ? getMinMaxHeight(30, bounds.height, dynamicMinHeight)\n      : getMinMaxHeight(6, bounds.height, dynamicMinHeight)\n\n  const maxValue =\n    labelPosition === \"top\" && label\n      ? getMinMaxHeight(30, bounds.height, dynamicMaxHeight)\n      : getMinMaxHeight(6, bounds.height, dynamicMaxHeight)\n\n  if (minValue !== minMaxValueRef.current.min) {\n    minMaxValueRef.current.min = minValue\n  }\n  if (maxValue !== minMaxValueRef.current.max) {\n    minMaxValueRef.current.max = maxValue\n  }\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <AutoHeightContainer\n        updateComponentHeight={updateComponentHeight}\n        enable={enableAutoHeight}\n      >\n        <div\n          css={[\n            applyLabelAndComponentWrapperStyle(labelPosition),\n            getTextareaContentContainerStyle(\n              labelPosition,\n              showValidationMessage,\n            ),\n          ]}\n        >\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedTextarea\n            {...props}\n            value={textAreaValue}\n            ref={textareaRef}\n            handleOnChange={handleOnChange}\n            handleOnFocus={handleOnFocus}\n            handleOnBlur={handleOnBlur}\n            showValidationMessage={showValidationMessage}\n          />\n        </div>\n        {!hideValidationMessage && (\n          <div\n            css={applyValidateMessageWrapperStyle(\n              labelWidth,\n              labelPosition,\n              labelHidden || !label,\n            )}\n            ref={messageWrapperRef}\n          >\n            <InvalidMessage validateMessage={validateMessage} />\n          </div>\n        )}\n      </AutoHeightContainer>\n    </TooltipWrapper>\n  )\n}\n\nWrappedTextarea.displayName = \"WrappedTextarea\"\nexport default TextareaWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextAreaWidget/utils.ts",
    "content": "import {\n  getValidateVFromString,\n  handleValidateCheck,\n} from \"../PublicSector/InvalidMessage/utils\"\nimport { TextareaWidgetProps } from \"./interface\"\n\nexport const getValidateMessageFunc = (\n  value: string | undefined,\n  options: {\n    hideValidationMessage?: TextareaWidgetProps[\"hideValidationMessage\"]\n    pattern?: TextareaWidgetProps[\"pattern\"]\n    regex?: TextareaWidgetProps[\"regex\"]\n    minLength?: TextareaWidgetProps[\"minLength\"]\n    maxLength?: TextareaWidgetProps[\"maxLength\"]\n    required?: TextareaWidgetProps[\"required\"]\n    customRule?: TextareaWidgetProps[\"customRule\"]\n  } = {},\n) => {\n  const {\n    hideValidationMessage,\n    pattern,\n    regex,\n    maxLength,\n    minLength,\n    required,\n    customRule,\n  } = options\n  if (!hideValidationMessage) {\n    const message = handleValidateCheck({\n      value: getValidateVFromString(value),\n      pattern,\n      regex,\n      minLength,\n      maxLength,\n      required,\n      customRule,\n    })\n    const showMessage = message && message.length > 0\n    return showMessage ? message : \"\"\n  }\n  return \"\"\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextAreaWidget/widgetConfig.tsx",
    "content": "import TextAreaWidgetIcon from \"@/assets/widgetCover/text.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const TEXTAREA_WIDGET_CONFIG: WidgetConfig = {\n  type: \"TEXTAREA_INPUT_WIDGET\",\n  displayName: \"textarea\",\n  widgetName: i18n.t(\"widget.textarea.name\"),\n  icon: <TextAreaWidgetIcon />,\n  keywords: [\"Textarea Input\", \"长文本输入框\"],\n  sessionType: \"INPUTS\",\n  w: 7,\n  h: 8,\n  version: 0,\n  defaults: {\n    value: undefined,\n    defaultValue: \"\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    colorScheme: \"blue\",\n    hidden: false,\n    formDataKey: \"textarea\",\n    placeholder: \"enter sth\",\n    dynamicHeight: \"fixed\",\n    resizeDirection: RESIZE_DIRECTION.ALL,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextWidget/constans.ts",
    "content": "export const HTMLTags = [\n  \"address\",\n  \"article\",\n  \"aside\",\n  \"base\",\n  \"basefont\",\n  \"blockquote\",\n  \"body\",\n  \"caption\",\n  \"center\",\n  \"col\",\n  \"colgroup\",\n  \"dd\",\n  \"details\",\n  \"dialog\",\n  \"dir\",\n  \"div\",\n  \"dl\",\n  \"dt\",\n  \"fieldset\",\n  \"figcaption\",\n  \"figure\",\n  \"footer\",\n  \"form\",\n  \"frame\",\n  \"frameset\",\n  \"h1\",\n  \"h2\",\n  \"h3\",\n  \"h4\",\n  \"h5\",\n  \"h6\",\n  \"head\",\n  \"header\",\n  \"hr\",\n  \"html\",\n  \"iframe\",\n  \"legend\",\n  \"li\",\n  \"link\",\n  \"main\",\n  \"menu\",\n  \"menuitem\",\n  \"nav\",\n  \"noframes\",\n  \"ol\",\n  \"optgroup\",\n  \"option\",\n  \"p\",\n  \"param\",\n  \"section\",\n  \"source\",\n  \"summary\",\n  \"table\",\n  \"tbody\",\n  \"td\",\n  \"tfoot\",\n  \"th\",\n  \"thead\",\n  \"title\",\n  \"tr\",\n  \"track\",\n  \"ul\",\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextWidget/eventHandlerConfig.ts",
    "content": "import { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const TEXT_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [],\n  methods: [\"setValue\", \"clearValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextWidget/index.tsx",
    "content": "export { TEXT_PANEL_CONFIG } from \"./panelConfig\"\nexport { TEXT_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { TEXT_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextWidget/interface.tsx",
    "content": "import { TextProps as ILLATextProps } from \"@illa-design/react\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport type HorizontalAlign = \"start\" | \"center\" | \"end\"\nexport type VerticalAlign = \"start\" | \"center\" | \"end\"\n\nexport interface TextProps extends ILLATextProps {\n  value?: string\n  weight?: number\n  disableMarkdown?: boolean\n  horizontalAlign?: HorizontalAlign\n  verticalAlign?: VerticalAlign\n}\n\nexport interface TextWidgetProps\n  extends Omit<TextProps, \"h\" | \"w\">,\n    BaseWidgetProps,\n    TooltipWrapperProps {\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  dynamicMaxHeight?: number\n  dynamicMinHeight?: number\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextWidget/panelConfig.tsx",
    "content": "import {\n  HorizontalCenterIcon,\n  HorizontalEndIcon,\n  HorizontalStartIcon,\n  VerticalCenterIcon,\n  VerticalEndIcon,\n  VerticalStartIcon,\n} from \"@illa-design/react\"\nimport TextSizeIcon from \"@/assets/text-size-icon.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst baseWidgetName = \"text\"\nexport const TEXT_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-inputModal`,\n        labelName: i18n.t(\"editor.inspect.setter_label.content\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.text_value\"),\n        attrName: \"disableMarkdown\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        options: [\n          { label: \"Markdown\", value: false },\n          { label: i18n.t(\"widget.text.text_model\"), value: true },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-value`,\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        isSetterSingleRow: true,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-startAdornment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-height`,\n        labelName: i18n.t(\"editor.inspect.setter_label.height\"),\n        attrName: \"dynamicHeight\",\n        setterType: \"HEIGHT_MODE_SELECT\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.fixed\"),\n            value: \"fixed\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_limited\"),\n            value: \"limited\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_height\"),\n            value: \"auto\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-row`,\n        labelName: i18n.t(\"editor.inspect.setter_label.vertical_alignment\"),\n        shown: (dynamicHeight: string) => dynamicHeight !== \"auto\",\n        bindAttrName: [\"dynamicHeight\"],\n        setterType: \"RADIO_GROUP_SETTER\",\n        attrName: \"verticalAlign\",\n        isSetterSingleRow: true,\n        options: [\n          {\n            label: <VerticalStartIcon />,\n            value: \"start\",\n          },\n          {\n            label: <VerticalCenterIcon />,\n            value: \"center\",\n          },\n          {\n            label: <VerticalEndIcon />,\n            value: \"end\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-col`,\n        labelName: i18n.t(\"editor.inspect.setter_label.horizontal_alignment\"),\n        attrName: \"horizontalAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        isSetterSingleRow: true,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"start\",\n          },\n          {\n            label: <HorizontalCenterIcon />,\n            value: \"center\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"end\",\n          },\n        ],\n      },\n\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-color`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-color`,\n            labelName: i18n.t(\"editor.inspect.setter_label.text\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"grayBlue\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-style-size`,\n        shown: (disableMarkdown: boolean) => disableMarkdown,\n        bindAttrName: [\"disableMarkdown\"],\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.styles\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-text-size`,\n            labelName: i18n.t(\"editor.inspect.setter_label.text_size\"),\n            setterType: \"MEASURE_CHECK_INPUT_SETTER\",\n            useCustomLayout: true,\n            attrName: \"fs\",\n            icon: <TextSizeIcon />,\n            defaultValue: \"14px\",\n            expectedType: VALIDATION_TYPES.STRING,\n          },\n          {\n            id: `${baseWidgetName}-style-text-weight`,\n            setterType: \"MEASURE_SELECT_SETTER\",\n            useCustomLayout: true,\n            defaultValue: 400,\n            labelName: i18n.t(\"editor.inspect.setter_label.weight\"),\n            attrName: \"weight\",\n            options: [\n              {\n                label: \"editor.inspect.setter_option.weight.regular\",\n                value: 400,\n              },\n              {\n                label: \"editor.inspect.setter_option.weight.medium\",\n                value: 500,\n              },\n              { label: \"editor.inspect.setter_option.weight.bold\", value: 700 },\n            ],\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextWidget/style.tsx",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getSpecialThemeColor } from \"@illa-design/react\"\nimport { VerticalAlign } from \"@/widgetLibrary/TextWidget/interface\"\n\nexport function applyAlignStyle(\n  verticalAlign?: VerticalAlign,\n): SerializedStyles {\n  return css`\n    width: 100%;\n    display: flex;\n    align-items: ${verticalAlign};\n  `\n}\n\nconst getRealHeightStyle = (\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\",\n  dynamicMinHeight: number = 0,\n  dynamicMaxHeight: number = 0,\n) => {\n  switch (dynamicHeight) {\n    case \"auto\":\n      return css`\n        height: auto;\n      `\n    case \"limited\":\n      return css`\n        min-height: ${dynamicMinHeight - 6}px;\n        height: auto;\n        max-height: ${dynamicMaxHeight - 6}px;\n      `\n    case \"fixed\":\n      return css`\n        height: 100%;\n      `\n    default:\n      return \"\"\n  }\n}\n\nexport const applyAutoHeightContainerStyle = (\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\",\n  dynamicMinHeight?: number,\n  dynamicMAxHeight?: number,\n) => {\n  return css`\n    display: flex;\n    width: 100%;\n    position: relative;\n    ${getRealHeightStyle(dynamicHeight, dynamicMinHeight, dynamicMAxHeight)};\n  `\n}\n\nexport function applyMarkdownStyle(horizontalAlign?: string): SerializedStyles {\n  return css`\n    width: 100%;\n    text-align: ${horizontalAlign};\n    overflow-wrap: break-word;\n  `\n}\n\nexport const applyTextStyle = (horizontalAlign?: string, weight?: number) => {\n  return css`\n    width: 100%;\n    font-weight: ${weight ?? 400};\n    text-align: ${horizontalAlign};\n    overflow-wrap: break-word;\n  `\n}\n\nexport const applyContainerStyle = (colorScheme: string) => {\n  return css`\n    width: 100%;\n    color: ${getSpecialThemeColor(colorScheme)};\n\n    a,\n    span {\n      color: ${getSpecialThemeColor(colorScheme)};\n    }\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextWidget/text.tsx",
    "content": "import {\n  Table,\n  TableBody,\n  TableCell,\n  TableContainer,\n  TableFooter,\n  TableHead,\n  TableRow,\n} from \"@mui/material\"\nimport Paper from \"@mui/material/Paper\"\nimport React, { FC, useEffect, useLayoutEffect, useRef } from \"react\"\nimport ReactMarkdown from \"react-markdown\"\nimport rehypeRaw from \"rehype-raw\"\nimport rehypeSanitize from \"rehype-sanitize\"\nimport remarkGfm from \"remark-gfm\"\nimport {\n  Heading,\n  Text as ILLAText,\n  Link,\n  Paragraph,\n  Typography,\n} from \"@illa-design/react\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { HTMLTags } from \"@/widgetLibrary/TextWidget/constans\"\nimport { TextProps, TextWidgetProps } from \"./interface\"\nimport {\n  applyAlignStyle,\n  applyAutoHeightContainerStyle,\n  applyMarkdownStyle,\n  applyTextStyle,\n} from \"./style\"\n\nexport const Text: FC<TextProps> = (props) => {\n  const {\n    value,\n    horizontalAlign,\n    verticalAlign,\n    colorScheme,\n    fs,\n    disableMarkdown,\n    weight,\n  } = props\n\n  const sanitizeOptions = {\n    allowedTags: HTMLTags,\n  }\n\n  return (\n    <div css={applyAlignStyle(verticalAlign)}>\n      {disableMarkdown ? (\n        <ILLAText\n          css={applyTextStyle(horizontalAlign, weight)}\n          colorScheme={colorScheme}\n          fs={fs}\n        >\n          {value}\n        </ILLAText>\n      ) : (\n        <Typography w=\"100%\" c={colorScheme}>\n          <ReactMarkdown\n            css={applyMarkdownStyle(horizontalAlign)}\n            remarkPlugins={[remarkGfm]}\n            rehypePlugins={[rehypeRaw, [rehypeSanitize, sanitizeOptions]]}\n            components={{\n              a: ({ href, children }) => (\n                <Link href={href} target=\"_blank\">\n                  {children}\n                </Link>\n              ),\n              code: ({ children }) => (\n                <ILLAText code colorScheme={colorScheme}>\n                  {children}\n                </ILLAText>\n              ),\n              p: ({ children }) => (\n                <Paragraph colorScheme={colorScheme}>{children}</Paragraph>\n              ),\n              h1: ({ children }) => (\n                <Heading level=\"h1\" colorScheme={colorScheme}>\n                  {children}\n                </Heading>\n              ),\n              h2: ({ children }) => (\n                <Heading level=\"h2\" colorScheme={colorScheme}>\n                  {children}\n                </Heading>\n              ),\n              h3: ({ children }) => (\n                <Heading level=\"h3\" colorScheme={colorScheme}>\n                  {children}\n                </Heading>\n              ),\n              h4: ({ children }) => (\n                <Heading level=\"h4\" colorScheme={colorScheme}>\n                  {children}\n                </Heading>\n              ),\n              h5: ({ children }) => (\n                <Heading level=\"h5\" colorScheme={colorScheme}>\n                  {children}\n                </Heading>\n              ),\n              h6: ({ children }) => (\n                <Heading level=\"h6\" colorScheme={colorScheme}>\n                  {children}\n                </Heading>\n              ),\n              tr: ({ children }) => <TableRow>{children}</TableRow>,\n              th: ({ children }) => (\n                <TableCell align=\"center\">{children}</TableCell>\n              ),\n              td: ({ children }) => (\n                <TableCell align=\"left\">{children}</TableCell>\n              ),\n              thead: ({ children }) => <TableHead>{children}</TableHead>,\n              tbody: ({ children }) => <TableBody>{children}</TableBody>,\n              tfoot: ({ children }) => <TableFooter>{children}</TableFooter>,\n              table: ({ children }) => (\n                <TableContainer component={Paper}>\n                  <Table sx={{ minWidth: 650 }}>{children}</Table>\n                </TableContainer>\n              ),\n            }}\n          >\n            {value ?? \"\"}\n          </ReactMarkdown>\n        </Typography>\n      )}\n    </div>\n  )\n}\n\nText.displayName = \"Text\"\n\nexport const TextWidget: FC<TextWidgetProps> = (props) => {\n  const {\n    value,\n    horizontalAlign,\n    verticalAlign = \"start\",\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    updateComponentHeight,\n    disableMarkdown,\n    tooltipText,\n    dynamicHeight = \"fixed\",\n    dynamicMinHeight,\n    dynamicMaxHeight,\n    colorScheme,\n    fs,\n    fw,\n    weight,\n  } = props\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: string) => {\n        handleUpdateDsl({ value })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ value: undefined })\n      },\n    })\n\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n  ])\n\n  const enableAutoHeight =\n    dynamicHeight !== \"fixed\" && dynamicHeight != undefined\n\n  const containerRef = useRef<HTMLDivElement | null>(null)\n\n  useLayoutEffect(() => {\n    const containerDOM = containerRef.current\n    const observerRef = new ResizeObserver((entries) => {\n      if (!updateComponentHeight) return\n      const height = entries[0].contentRect.height\n      updateComponentHeight?.(height)\n    })\n    if (observerRef && containerDOM && enableAutoHeight) {\n      observerRef.unobserve(containerDOM)\n      observerRef.observe(containerDOM)\n    }\n\n    return () => {\n      if (containerDOM && enableAutoHeight) {\n        observerRef.unobserve(containerDOM)\n      }\n    }\n  }, [enableAutoHeight, updateComponentHeight])\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div\n        ref={containerRef}\n        css={applyAutoHeightContainerStyle(\n          dynamicHeight,\n          dynamicMinHeight,\n          dynamicMaxHeight,\n        )}\n      >\n        <Text\n          weight={weight}\n          horizontalAlign={horizontalAlign}\n          value={value}\n          verticalAlign={verticalAlign}\n          colorScheme={colorScheme}\n          fs={fs}\n          fw={fw}\n          disableMarkdown={disableMarkdown}\n        />\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nTextWidget.displayName = \"TextWidget\"\nexport default TextWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TextWidget/widgetConfig.tsx",
    "content": "import TextWidgetIcon from \"@/assets/widgetCover/text.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const TEXT_WIDGET_CONFIG: WidgetConfig = {\n  displayName: \"text\",\n  widgetName: i18n.t(\"widget.text.name\"),\n  h: 5,\n  w: 6,\n  type: \"TEXT_WIDGET\",\n  icon: <TextWidgetIcon />,\n  keywords: [\"Text\", \"文本\"],\n  sessionType: \"PRESENTATION\",\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    value: i18n.t(\"widget.text.default_value\"),\n    horizontalAlign: \"start\",\n    verticalAlign: \"center\",\n    colorScheme: \"grayBlue\",\n    disableMarkdown: false,\n    hidden: false,\n    fs: \"14px\",\n    weight: 400,\n    dynamicHeight: \"fixed\",\n    resizeDirection: RESIZE_DIRECTION.ALL,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimePickerWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const TIME_PICKER_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"setValue\", \"clearValue\", \"validate\", \"clearValidation\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimePickerWidget/index.tsx",
    "content": "export { TIME_PICKER_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { TIME_PICKER_PANEL_CONFIG } from \"./panelConfig\"\nexport { TIME_PICKER_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimePickerWidget/interface.tsx",
    "content": "import { TimePickerProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedTimePickerProps\n  extends Pick<\n    TimePickerProps,\n    \"placeholder\" | \"disabled\" | \"colorScheme\" | \"value\" | \"format\"\n  > {\n  minuteStep?: number\n  tooltipText?: string\n  loading?: boolean\n  showClear?: TimePickerProps[\"allowClear\"]\n  displayName: string\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n}\n\nexport interface TimePickerWidgetProps\n  extends Omit<WrappedTimePickerProps, \"handleOnChange\">,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimePickerWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { TIME_PICKER_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/TimePickerWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"time-picker\"\nexport const TIME_PICKER_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-DefaultValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.default_value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.input_default_value\"),\n        attrName: \"value\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-date-format`,\n        labelName: i18n.t(\"editor.inspect.setter_label.format\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.time_picker.format\"),\n        attrName: \"format\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.placeholder\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.placeholder\"),\n        attrName: \"placeholder\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-basic-minute-step`,\n        labelName: i18n.t(\"editor.inspect.setter_label.step_size\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.time_picker.the_span_of_the_valu\",\n        ),\n        attrName: \"minuteStep\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\", \"labelPosition\"],\n        shown: (hidden, position) => !hidden && position !== \"top\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          TIME_PICKER_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.time_picker.show_a_clear_button_\",\n        ),\n        attrName: \"showClear\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        isSetterSingleRow: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-bg`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimePickerWidget/timePicker.tsx",
    "content": "import { FC, useCallback, useEffect } from \"react\"\nimport { TimePicker } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { TimePickerWidgetProps, WrappedTimePickerProps } from \"./interface\"\n\nexport const WrappedTimePicker: FC<WrappedTimePickerProps> = (props) => {\n  const {\n    value,\n    format,\n    placeholder,\n    showClear,\n    disabled,\n    minuteStep,\n    colorScheme,\n    handleOnChange,\n    getValidateMessage,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  } = props\n\n  const changeValue = (value?: string) => {\n    new Promise((resolve) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value: value || \"\",\n            validateMessage: message,\n          },\n        },\n      ])\n      resolve(true)\n    }).then(() => {\n      handleOnChange?.()\n    })\n  }\n\n  const clearValue = () => {\n    const message = getValidateMessage(undefined)\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          value: undefined,\n          validateMessage: message,\n        },\n      },\n    ])\n  }\n\n  return (\n    <TimePicker\n      w=\"100%\"\n      step={{ minute: minuteStep }}\n      colorScheme={colorScheme}\n      format={format}\n      value={value}\n      disabled={disabled}\n      placeholder={placeholder}\n      allowClear={showClear}\n      onClear={clearValue}\n      onChange={changeValue}\n    />\n  )\n}\n\nWrappedTimePicker.displayName = \"WrappedTimePicker\"\n\nexport const TimePickerWidget: FC<TimePickerWidgetProps> = (props) => {\n  const {\n    value,\n    displayName,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    customRule,\n    hideValidationMessage,\n    validateMessage,\n    triggerEventHandler,\n    updateComponentHeight,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n  } = props\n\n  const getValidateMessage = useCallback(\n    (value?: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value: value ? value : undefined,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required],\n  )\n\n  const handleValidate = useCallback(\n    (value?: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            validateMessage: message,\n          },\n        },\n      ])\n      return message\n    },\n    [displayName, getValidateMessage, handleUpdateMultiExecutionResult],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: string) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value,\n            },\n          },\n        ])\n      },\n      clearValue: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: undefined,\n            },\n          },\n        ])\n      },\n      validate: () => {\n        return handleValidate(value)\n      },\n      clearValidation: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              validateMessage: \"\",\n            },\n          },\n        ])\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    displayName,\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleValidate,\n    value,\n  ])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedTimePicker\n            {...props}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\n\nTimePickerWidget.displayName = \"TimePickerWidget\"\nexport default TimePickerWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimePickerWidget/widgetConfig.tsx",
    "content": "import TimePickerWidgetIcon from \"@/assets/widgetCover/timePicker.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const TIME_PICKER_WIDGET_CONFIG: WidgetConfig = {\n  type: \"TIME_PICKER_WIDGET\",\n  displayName: \"timePicker\",\n  widgetName: i18n.t(\"widget.time_picker.name\"),\n  keywords: [\"Time Picker\", \"时间选择器\"],\n  icon: <TimePickerWidgetIcon />,\n  sessionType: \"CALENDAR\",\n  w: 6,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    placeholder: i18n.t(\n      \"editor.inspect.setter_default_value.time_picker.select_time\",\n    ),\n    format: \"HH:mm:ss\",\n    minuteStep: \"{{15}}\",\n    colorScheme: \"blue\",\n    label: \"Label\",\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    hidden: false,\n    showClear: true,\n    formDataKey: \"timePicker\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimeRangeWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const TIME_RANGE_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\n    \"setStartTime\",\n    \"setEndTime\",\n    \"clearValue\",\n    \"validate\",\n    \"clearValidation\",\n  ],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimeRangeWidget/index.tsx",
    "content": "export { TIME_RANGE_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { TIME_RANGE_PANEL_CONFIG } from \"./panelConfig\"\nexport { TIME_RANGE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimeRangeWidget/interface.tsx",
    "content": "import {\n  RangeDatePickerProps,\n  RangePickerProps,\n  TimePickerValue,\n} from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport LabelProps from \"@/widgetLibrary/PublicSector/Label/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedTimeRangeProps\n  extends Pick<RangePickerProps, \"disabled\" | \"colorScheme\" | \"format\"> {\n  startTime: TimePickerValue\n  endTime: TimePickerValue\n  startPlaceholder?: string\n  endPlaceholder?: string\n  minuteStep?: number\n  showClear?: RangeDatePickerProps[\"allowClear\"]\n  displayName: string\n  getValidateMessage: (value?: unknown) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  handleOnChange?: () => void\n}\n\nexport interface TimeRangeWidgetProps\n  extends Omit<WrappedTimeRangeProps, \"handleOnChange\">,\n    BaseWidgetProps,\n    LabelProps,\n    TooltipWrapperProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  validateMessage: string\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimeRangeWidget/panelConfig.tsx",
    "content": "import { HorizontalEndIcon, HorizontalStartIcon } from \"@illa-design/react\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { TIME_RANGE_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/TimeRangeWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"time-range\"\nexport const TIME_RANGE_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-start-time`,\n        labelName: i18n.t(\"editor.inspect.setter_label.time_range.start_time\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.time_range.start_time\"),\n        attrName: \"startTime\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-end-time`,\n        labelName: i18n.t(\"editor.inspect.setter_label.time_range.end_time\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.time_range.end_time\"),\n        attrName: \"endTime\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-format`,\n        labelName: i18n.t(\"editor.inspect.setter_label.format\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tips.time_picker.format\"),\n        attrName: \"format\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-start-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.start_placeholder\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.time_range.start_placeholder\",\n        ),\n        isSetterSingleRow: true,\n        attrName: \"startPlaceholder\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-end-placeholder`,\n        labelName: i18n.t(\"editor.inspect.setter_label.end_placeholder\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.time_range.end_placeholder\",\n        ),\n        isSetterSingleRow: true,\n        attrName: \"endPlaceholder\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-minute-step`,\n        labelName: i18n.t(\"editor.inspect.setter_label.step_size\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.time_picker.the_span_of_the_valu\",\n        ),\n        attrName: \"minuteStep\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-label`,\n    groupName: i18n.t(\"editor.inspect.setter_group.label\"),\n    children: [\n      {\n        id: `${baseWidgetName}-label-label`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label\"),\n        attrName: \"label\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-caption`,\n        labelName: i18n.t(\"editor.inspect.setter_label.caption\"),\n        attrName: \"labelCaption\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-label-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden_label\"),\n        attrName: \"labelHidden\",\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-label-position`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_position\"),\n        attrName: \"labelPosition\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          { label: i18n.t(\"widget.public.left\"), value: \"left\" },\n          { label: i18n.t(\"widget.public.top\"), value: \"top\" },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-alignment`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_alignment\"),\n        attrName: \"labelAlign\",\n        setterType: \"RADIO_GROUP_SETTER\",\n        bindAttrName: [\"labelHidden\"],\n        shown: (value) => !value,\n        options: [\n          {\n            label: <HorizontalStartIcon />,\n            value: \"left\",\n          },\n          {\n            label: <HorizontalEndIcon />,\n            value: \"right\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-label-labelWidth`,\n        labelName: i18n.t(\"editor.inspect.setter_label.label_width\"),\n        attrName: \"labelWidth\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n        bindAttrName: [\"labelHidden\", \"labelPosition\"],\n        shown: (hidden, position) => !hidden && position !== \"top\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          TIME_RANGE_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-adornments-showClear`,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_clear_button\"),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tips.time_picker.show_a_clear_button_\",\n        ),\n        attrName: \"showClear\",\n        useCustomLayout: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    children: [\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        isSetterSingleRow: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-styles-colorScheme`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimeRangeWidget/timeRange.tsx",
    "content": "import { FC, useCallback, useEffect, useMemo } from \"react\"\nimport { RangePicker } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { Label } from \"@/widgetLibrary/PublicSector/Label\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport {\n  applyLabelAndComponentWrapperStyle,\n  applyValidateMessageWrapperStyle,\n} from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { handleValidateCheck } from \"../PublicSector/InvalidMessage/utils\"\nimport { TimeRangeWidgetProps, WrappedTimeRangeProps } from \"./interface\"\n\nexport const WrappedTimeRange: FC<WrappedTimeRangeProps> = (props) => {\n  const {\n    startTime,\n    endTime,\n    format,\n    startPlaceholder,\n    endPlaceholder,\n    minuteStep,\n    showClear,\n    disabled,\n    colorScheme,\n    handleOnChange,\n    getValidateMessage,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  } = props\n\n  const changeValue = (value?: string[]) => {\n    new Promise((resolve) => {\n      const startMessage = getValidateMessage(value?.[0])\n      const endMessage = getValidateMessage(value?.[1])\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            value: [value?.[0] || \"\", value?.[1] || \"\"],\n            startTime: value?.[0] || \"\",\n            endTime: value?.[1] || \"\",\n            validateMessage: startMessage || endMessage,\n          },\n        },\n      ])\n      resolve(true)\n    }).then(() => {\n      handleOnChange?.()\n    })\n  }\n\n  const clearValue = () => {\n    const startMessage = getValidateMessage(undefined)\n    const endMessage = getValidateMessage(undefined)\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          value: [\"\", \"\"],\n          startTime: \"\",\n          endTime: \"\",\n          validateMessage: startMessage || endMessage,\n        },\n      },\n    ])\n  }\n\n  const _placeholder = [startPlaceholder ?? \"\", endPlaceholder ?? \"\"]\n\n  const timeRangeValue = useMemo(() => {\n    return !startTime && !endTime ? [\"\", \"\"] : [startTime, endTime]\n  }, [startTime, endTime])\n\n  return (\n    <RangePicker\n      w=\"100%\"\n      colorScheme={colorScheme}\n      format={format}\n      value={timeRangeValue}\n      disabled={disabled}\n      placeholder={_placeholder}\n      allowClear={showClear}\n      step={{ minute: minuteStep }}\n      onClear={clearValue}\n      onChange={changeValue}\n    />\n  )\n}\n\nWrappedTimeRange.displayName = \"WrappedTimeRange\"\n\nexport const TimeRangeWidget: FC<TimeRangeWidgetProps> = (props) => {\n  const {\n    startTime,\n    endTime,\n    startPlaceholder,\n    endPlaceholder,\n    showClear,\n    disabled,\n    colorScheme,\n    displayName,\n    labelPosition,\n    labelFull,\n    label,\n    labelAlign,\n    labelWidth = 33,\n    labelCaption,\n    labelWidthUnit,\n    required,\n    labelHidden,\n    tooltipText,\n    validateMessage,\n    customRule,\n    hideValidationMessage,\n    updateComponentHeight,\n    triggerEventHandler,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n  } = props\n\n  const getValidateMessage = useCallback(\n    (value?: unknown) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [customRule, hideValidationMessage, required],\n  )\n\n  const handleValidate = useCallback(\n    (value?: unknown) => {\n      const message = getValidateMessage(value)\n      handleUpdateMultiExecutionResult([\n        {\n          displayName,\n          value: {\n            validateMessage: message,\n          },\n        },\n      ])\n      return message\n    },\n    [displayName, getValidateMessage, handleUpdateMultiExecutionResult],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setStartTime: (startTime: string) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: [startTime, endTime],\n              startTime,\n            },\n          },\n        ])\n      },\n      setEndTime: (endTime: string) => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: [startTime, endTime],\n              endTime,\n            },\n          },\n        ])\n      },\n      clearValue: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              value: [\"\", \"\"],\n              startTime: \"\",\n              endTime: \"\",\n            },\n          },\n        ])\n      },\n      validate: () => {\n        if (!startTime || !endTime) {\n          return handleValidate(undefined)\n        }\n        const startValueChecked = handleValidate(startTime)\n        if (startValueChecked) {\n          return startValueChecked\n        }\n        const endValueChecked = handleValidate(endTime)\n        if (endValueChecked) {\n          return endValueChecked\n        }\n      },\n      clearValidation: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: {\n              validateMessage: \"\",\n            },\n          },\n        ])\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    displayName,\n    startTime,\n    endTime,\n    startPlaceholder,\n    endPlaceholder,\n    showClear,\n    disabled,\n    colorScheme,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleValidate,\n    handleUpdateMultiExecutionResult,\n  ])\n\n  useEffect(() => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: {\n          value: [startTime, endTime],\n        },\n      },\n    ])\n  }, [startTime, endTime, handleUpdateMultiExecutionResult, displayName])\n\n  const handleOnChange = useCallback(() => {\n    triggerEventHandler(\"change\")\n  }, [triggerEventHandler])\n\n  return (\n    <AutoHeightContainer updateComponentHeight={updateComponentHeight}>\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={applyLabelAndComponentWrapperStyle(labelPosition)}>\n          <Label\n            labelFull={labelFull}\n            label={label}\n            labelAlign={labelAlign}\n            labelWidth={labelWidth}\n            labelCaption={labelCaption}\n            labelWidthUnit={labelWidthUnit}\n            labelPosition={labelPosition}\n            required={required}\n            labelHidden={labelHidden}\n            hasTooltip={!!tooltipText}\n          />\n          <WrappedTimeRange\n            {...props}\n            getValidateMessage={getValidateMessage}\n            handleOnChange={handleOnChange}\n          />\n        </div>\n      </TooltipWrapper>\n      {!hideValidationMessage && (\n        <div\n          css={applyValidateMessageWrapperStyle(\n            labelWidth,\n            labelPosition,\n            labelHidden || !label,\n          )}\n        >\n          <InvalidMessage validateMessage={validateMessage} />\n        </div>\n      )}\n    </AutoHeightContainer>\n  )\n}\nTimeRangeWidget.displayName = \"TimeRangeWidget\"\nexport default TimeRangeWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimeRangeWidget/widgetConfig.tsx",
    "content": "import RangeTimePickerWidgetIcon from \"@/assets/widgetCover/rangeTimePicker.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const TIME_RANGE_WIDGET_CONFIG: WidgetConfig = {\n  type: \"TIME_RANGE_WIDGET\",\n  displayName: \"rangeTime\",\n  widgetName: i18n.t(\"widget.time_range.name\"),\n  keywords: [\"Range Time\", \"时间范围选择器\"],\n  icon: <RangeTimePickerWidgetIcon />,\n  sessionType: \"CALENDAR\",\n  w: 10,\n  h: 5,\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    format: \"HH:mm:ss\",\n    minuteStep: \"{{15}}\",\n    startPlaceholder: i18n.t(\n      \"editor.inspect.setter_default_value.time_range.start_placeholder\",\n    ),\n    endPlaceholder: i18n.t(\n      \"editor.inspect.setter_default_value.time_range.end_placeholder\",\n    ),\n    startTime: \"00:00:00\",\n    endTime: \"23:59:59\",\n    colorScheme: \"blue\",\n    label: \"Label\",\n    value: [\"\", \"\"],\n    labelAlign: \"left\",\n    labelPosition: \"left\",\n    labelWidth: \"{{33}}\",\n    hidden: false,\n    showClear: true,\n    formDataKey: \"timeRange\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimelineWidget/eventHandlerConfig.ts",
    "content": "import { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const TIMELINE_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [],\n  methods: [\"setValue\", \"clearValue\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimelineWidget/index.ts",
    "content": "export { TIMELINE_PANEL_CONFIG } from \"./panelConfig\"\nexport { TIMELINE_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { TIMELINE_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimelineWidget/interface.ts",
    "content": "import { TimelineProps } from \"@illa-design/react\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedTimelineProps\n  extends Pick<TimelineProps, \"direction\" | \"pending\"> {\n  items?: string[]\n}\n\nexport interface TimelineWidgetProps\n  extends WrappedTimelineProps,\n    BaseWidgetProps {\n  dynamicHeight: \"auto\" | \"fixed\" | \"limited\"\n  dynamicMinHeight?: number\n  dynamicMaxHeight?: number\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimelineWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\n\nconst baseWidgetName = \"timeline\"\nexport const TIMELINE_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-items`,\n        labelName: i18n.t(\"editor.inspect.setter_label.items\"),\n        attrName: \"items\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n        isSetterSingleRow: true,\n      },\n      {\n        id: `${baseWidgetName}-direction`,\n        labelName: i18n.t(\"editor.inspect.setter_label.direction\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.timeline_direction\"),\n        setterType: \"RADIO_GROUP_SETTER\",\n        attrName: \"direction\",\n        options: [\n          { label: i18n.t(\"widget.timeline.vertical\"), value: \"vertical\" },\n          {\n            label: i18n.t(\"widget.timeline.horizontal\"),\n            value: \"horizontal\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-pending`,\n        labelName: i18n.t(\"editor.inspect.setter_label.pending\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.timeline_pending\"),\n        attrName: \"pending\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-height`,\n        labelName: i18n.t(\"editor.inspect.setter_label.height\"),\n        attrName: \"dynamicHeight\",\n        setterType: \"HEIGHT_MODE_SELECT\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_option.fixed\"),\n            value: \"fixed\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_limited\"),\n            value: \"limited\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_option.auto_height\"),\n            value: \"auto\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimelineWidget/timeline.tsx",
    "content": "import { FC, useEffect, useMemo } from \"react\"\nimport { Timeline, TimelineItem } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport {\n  TimelineWidgetProps,\n  WrappedTimelineProps,\n} from \"@/widgetLibrary/TimelineWidget/interface\"\n\nexport const WrappedTimeline: FC<WrappedTimelineProps> = (props) => {\n  const { items, direction, pending } = props\n\n  const timelineItems = useMemo(() => {\n    if (Array.isArray(items)) {\n      return items.map(\n        (item) =>\n          (typeof item === \"string\" || typeof item === \"number\") && (\n            <TimelineItem key={item}>{item}</TimelineItem>\n          ),\n      )\n    }\n    return null\n  }, [items])\n\n  return (\n    <Timeline direction={direction} pending={pending} h=\"100%\" w=\"100%\">\n      {timelineItems}\n    </Timeline>\n  )\n}\n\nWrappedTimeline.displayName = \"WrappedTimeline\"\n\nexport const TimelineWidget: FC<TimelineWidgetProps> = (props) => {\n  const {\n    items,\n    direction,\n    pending,\n    displayName,\n    dynamicHeight = \"fixed\",\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    updateComponentHeight,\n  } = props\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      setValue: (value: string) => {\n        handleUpdateDsl({ items: value.split(\",\") })\n      },\n      clearValue: () => {\n        handleUpdateDsl({ items: [] })\n      },\n    })\n\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    items,\n    direction,\n    pending,\n    displayName,\n    updateComponentRuntimeProps,\n    handleUpdateDsl,\n    deleteComponentRuntimeProps,\n  ])\n\n  const enableAutoHeight =\n    dynamicHeight !== \"fixed\" && dynamicHeight != undefined\n\n  return (\n    <AutoHeightContainer\n      updateComponentHeight={updateComponentHeight}\n      enable={enableAutoHeight}\n    >\n      <WrappedTimeline {...props} />\n    </AutoHeightContainer>\n  )\n}\n\nTimelineWidget.displayName = \"TimelineWidget\"\nexport default TimelineWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/TimelineWidget/widgetConfig.tsx",
    "content": "import TimelineWidgetIcon from \"@/assets/widgetCover/timeline.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const TIMELINE_WIDGET_CONFIG: WidgetConfig = {\n  type: \"TIMELINE_WIDGET\",\n  widgetName: i18n.t(\"widget.timeline.name\"),\n  displayName: \"timeline\",\n  icon: <TimelineWidgetIcon />,\n  keywords: [\"Timeline\", \"时间线\"],\n  sessionType: \"PRESENTATION\",\n  w: 6,\n  h: 28,\n  version: 0,\n  defaults: {\n    direction: \"vertical\",\n    items: `{{[\"The first milestone\",\"The second milestone\",\"The third milestone\"]}}`,\n    hidden: false,\n    dynamicHeight: \"fixed\",\n    resizeDirection: RESIZE_DIRECTION.ALL,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/UploadWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const UPLOAD_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.change\",\n      ),\n      value: \"change\",\n    },\n  ],\n  methods: [\"clearValidation\", \"clearValue\", \"setDisabled\"],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/UploadWidget/index.tsx",
    "content": "export { UPLOAD_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\nexport { UPLOAD_PANEL_CONFIG } from \"./panelConfig\"\nexport { UPLOAD_WIDGET_CONFIG } from \"./widgetConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/UploadWidget/interface.tsx",
    "content": "import { UploadItem, UploadProps } from \"@illa-design/react\"\nimport { ValidateMessageOldProps } from \"@/widgetLibrary/PublicSector/InvalidMessage/interface\"\nimport { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\nexport interface WrappedUploadProps\n  extends Pick<\n      UploadProps,\n      | \"disabled\"\n      | \"onChange\"\n      | \"onRemove\"\n      | \"variant\"\n      | \"loading\"\n      | \"text\"\n      | \"colorScheme\"\n      | \"customRequest\"\n    >,\n    BaseWidgetProps {\n  type: \"button\" | \"dropzone\"\n  buttonText?: string\n  dropText?: string\n  fileType?: string[]\n  selectionType?: \"single\" | \"multiple\" | \"directory\"\n  appendFiles?: boolean\n  showFileList?: boolean\n  parseValue?: boolean\n  minFiles?: number\n  maxFiles?: number\n  maxSize?: number\n  minSize?: number\n  sizeType?: string\n  fileList?: UploadItem[]\n  getValidateMessage: (value: UploadItem[]) => string\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n}\n\nexport interface UploadWidgetProps\n  extends WrappedUploadProps,\n    BaseWidgetProps,\n    TooltipWrapperProps,\n    Omit<ValidateMessageOldProps, \"value\"> {\n  currentList?: UploadItem[]\n  displayName: string\n  validateMessage: string\n  value?: string[]\n  files?: {\n    lastModified: number\n    name: string\n    size: number\n    type: string\n  }[]\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/UploadWidget/panelConfig.tsx",
    "content": "import i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { UPLOAD_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/UploadWidget\"\n\nconst baseWidgetName = \"upload\"\nexport const UPLOAD_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-type`,\n        labelName: i18n.t(\"editor.inspect.setter_label.type\"),\n        attrName: \"type\",\n        setterType: \"SEARCH_SELECT_SETTER\",\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.upload_type.button\",\n            ),\n            value: \"button\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.upload_type.dropzone\",\n            ),\n            value: \"dropzone\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-buttonText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.text\"),\n        attrName: \"buttonText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        bindAttrName: [\"type\"],\n        shown: (value) => value === \"button\",\n      },\n      {\n        id: `${baseWidgetName}-basic-dropText`,\n        labelName: i18n.t(\"editor.inspect.setter_label.text\"),\n        attrName: \"dropText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        bindAttrName: [\"type\"],\n        shown: (value) => value === \"dropzone\",\n      },\n      {\n        id: `${baseWidgetName}-basic-selectionType`,\n        labelName: i18n.t(\"editor.inspect.setter_label.selection_types\"),\n        attrName: \"selectionType\",\n        isSetterSingleRow: true,\n        setterType: \"SEARCH_SELECT_SETTER\",\n        options: [\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.selection_types.single_file\",\n            ),\n            value: \"single\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.selection_types.multiple_files\",\n            ),\n            value: \"multiple\",\n          },\n          {\n            label: i18n.t(\n              \"editor.inspect.setter_default_value.selection_types.directory\",\n            ),\n            value: \"directory\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-basic-fileTypes`,\n        labelName: i18n.t(\"editor.inspect.setter_label.file_type\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.file_types\"),\n        placeholder: '{{[\".png\",\".jpg\"]}}',\n        attrName: \"fileType\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.ARRAY,\n      },\n\n      {\n        id: `${baseWidgetName}-basic-appendNewFiles`,\n        labelName: i18n.t(\"editor.inspect.setter_label.append_newly_files\"),\n        attrName: \"appendFiles\",\n        setterType: \"SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"selectionType\"],\n        shown: (value) => value !== \"single\",\n      },\n      {\n        id: `${baseWidgetName}-basic-fileList`,\n        labelName: i18n.t(\"editor.inspect.setter_label.file_list\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.file_list\"),\n        attrName: \"showFileList\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-parseValue`,\n        labelName: i18n.t(\"editor.inspect.setter_label.parse_value\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.parse_value\"),\n        attrName: \"parseValue\",\n        useCustomLayout: true,\n        openDynamic: true,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          UPLOAD_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n      {\n        id: `${baseWidgetName}-interaction-loading`,\n        labelName: i18n.t(\"editor.inspect.setter_label.loading\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.loading\"),\n        attrName: \"loading\",\n        setterType: \"INPUT_SETTER\",\n        placeholder: \"{{false}}\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        bindAttrName: [\"type\"],\n        shown: (value) => value === \"button\",\n      },\n      {\n        id: `${baseWidgetName}-interaction-disabled`,\n        labelName: i18n.t(\"editor.inspect.setter_label.disabled\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.disabled\"),\n        attrName: \"disabled\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        placeholder: \"{{false}}\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-validation`,\n    groupName: i18n.t(\"editor.inspect.setter_group.validation\"),\n    children: [\n      {\n        id: `${baseWidgetName}-validation-required`,\n        labelName: i18n.t(\"editor.inspect.setter_label.required_field\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.required_field\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"required\",\n      },\n      {\n        id: `${baseWidgetName}-validation-maxFiles`,\n        labelName: i18n.t(\"editor.inspect.setter_label.max_files\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"maxFiles\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\"selectionType\"],\n        shown: (value) => value !== \"single\",\n      },\n      {\n        id: `${baseWidgetName}-validation-minFiles`,\n        labelName: i18n.t(\"editor.inspect.setter_label.min_files\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"minFiles\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        bindAttrName: [\"selectionType\"],\n        shown: (value) => value !== \"single\",\n      },\n      {\n        id: `${baseWidgetName}-validation-fileSize`,\n        labelName: i18n.t(\"editor.inspect.setter_label.min_max_size\"),\n        placeholder: i18n.t(\"editor.inspect.setter_placeholder.min_max_size\"),\n        setterType: \"FILE_MIN_MAX_SETTER\",\n        attrName: \"\",\n        useCustomLayout: true,\n      },\n      {\n        id: `${baseWidgetName}-validation-custom`,\n        labelName: i18n.t(\"editor.inspect.setter_label.custom_rule\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.custom_rule\"),\n        setterType: \"INPUT_SETTER\",\n        attrName: \"customRule\",\n        expectedType: VALIDATION_TYPES.STRING,\n      },\n      {\n        id: `${baseWidgetName}-validation-hide-message`,\n        labelName: i18n.t(\n          \"editor.inspect.setter_label.hide_validation_message\",\n        ),\n        labelDesc: i18n.t(\n          \"editor.inspect.setter_tooltip.hide_validation_message\",\n        ),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n        useCustomLayout: true,\n        openDynamic: true,\n        attrName: \"hideValidationMessage\",\n      },\n      {\n        id: `${baseWidgetName}-validation-form-data-key`,\n        labelName: i18n.t(\"editor.inspect.setter_label.form_data_key\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.form_data_key\"),\n        setterType: \"INPUT_SETTER\",\n        expectedType: VALIDATION_TYPES.STRING,\n        attrName: \"formDataKey\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        attrName: \"hidden\",\n        placeholder: \"false\",\n        useCustomLayout: true,\n        openDynamic: true,\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-style`,\n    groupName: i18n.t(\"editor.inspect.setter_group.style\"),\n    bindAttrName: [\"type\"],\n    shown: (value) => value === \"button\",\n    children: [\n      {\n        id: `${baseWidgetName}-style-variant`,\n        setterType: \"RADIO_GROUP_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.variant\"),\n        attrName: \"variant\",\n        bindAttrName: [\"type\"],\n        shown: (value) => value === \"button\",\n        options: [\n          {\n            label: i18n.t(\"editor.inspect.setter_default_value.fill\"),\n            value: \"fill\",\n          },\n          {\n            label: i18n.t(\"editor.inspect.setter_default_value.outline\"),\n            value: \"outline\",\n          },\n        ],\n      },\n      {\n        id: `${baseWidgetName}-style-list`,\n        setterType: \"STYLE_CONTAINER_SETTER\",\n        labelName: i18n.t(\"editor.inspect.setter_label.colors\"),\n        attrName: \"styles\",\n        useCustomLayout: true,\n        bindAttrName: [\"type\"],\n        shown: (value) => value === \"button\",\n        childrenSetter: [\n          {\n            id: `${baseWidgetName}-style-bg`,\n            labelName: i18n.t(\"editor.inspect.setter_label.theme_color\"),\n            setterType: \"COLOR_PICKER_SETTER\",\n            useCustomLayout: true,\n            attrName: \"colorScheme\",\n            defaultValue: \"blue\",\n          },\n        ],\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/UploadWidget/style.tsx",
    "content": "import { css } from \"@emotion/react\"\n\nexport const uploadLayoutStyle = css`\n  display: flex;\n  flex-direction: column;\n`\n\nexport const uploadContainerStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  position: relative;\n`\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/UploadWidget/upload.tsx",
    "content": "import { FC, useCallback, useEffect, useRef, useState } from \"react\"\nimport { RequestOptions, Upload, UploadItem } from \"@illa-design/react\"\nimport { AutoHeightContainer } from \"@/widgetLibrary/PublicSector/AutoHeightContainer\"\nimport { InvalidMessage } from \"@/widgetLibrary/PublicSector/InvalidMessage\"\nimport { handleValidateCheck } from \"@/widgetLibrary/PublicSector/InvalidMessage/utils\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { applyValidateMessageWrapperStyle } from \"@/widgetLibrary/PublicSector/TransformWidgetWrapper/style\"\nimport { uploadLayoutStyle } from \"@/widgetLibrary/UploadWidget/style\"\nimport { UploadWidgetProps, WrappedUploadProps } from \"./interface\"\nimport {\n  dataURLtoFile,\n  getFileString,\n  getFilteredValue,\n  toBase64,\n} from \"./util\"\n\nconst getCurrentList = (fileList: UploadItem[]) =>\n  fileList.map((file) => {\n    if (!file) {\n      return\n    }\n    const { originFile: _originFile, ...others } = file\n    return others\n  }) || []\n\nconst getFiles = (fileList: UploadItem[], raws: string[]) =>\n  fileList.map((file, index) => ({\n    lastModified: file.originFile?.lastModified,\n    name: file.originFile?.name,\n    size: file.originFile?.size,\n    type: file.originFile?.type,\n    dataURI: `data:${file.originFile?.type ?? \"text/plain\"};base64,${\n      raws[index]\n    }`,\n    updateStatus: {\n      status: file.status,\n      percent: file.percent,\n      response: file.response,\n    },\n  })) || []\n\nexport const WrappedUpload: FC<WrappedUploadProps> = (props) => {\n  const {\n    selectionType,\n    type,\n    showFileList,\n    disabled,\n    fileType = [],\n    loading,\n    buttonText,\n    dropText,\n    colorScheme,\n    variant,\n    fileList,\n    onRemove,\n    onChange,\n    customRequest,\n  } = props\n\n  const isDrag = type === \"dropzone\"\n  const inputAcceptType = fileType.join(\",\")\n\n  return (\n    <Upload\n      customRequest={customRequest}\n      disabled={disabled}\n      text={isDrag ? dropText : buttonText}\n      colorScheme={colorScheme}\n      variant={variant}\n      loading={loading}\n      multiple={!!(selectionType === \"multiple\")}\n      directory={selectionType === \"directory\"}\n      drag={isDrag}\n      {...(!!inputAcceptType && { accept: inputAcceptType })}\n      {...(fileList && {\n        fileList,\n      })}\n      onRemove={onRemove}\n      onChange={onChange}\n      showUploadList={showFileList}\n    />\n  )\n}\nWrappedUpload.displayName = \"WrappedUpload\"\n\nexport const UploadWidget: FC<UploadWidgetProps> = (props) => {\n  const {\n    displayName,\n    appendFiles,\n    customRule,\n    tooltipText,\n    required,\n    minFiles,\n    maxFiles,\n    sizeType,\n    maxSize,\n    currentList,\n    value,\n    files,\n    parseValue,\n    minSize,\n    validateMessage,\n    triggerEventHandler,\n    hideValidationMessage,\n    updateComponentHeight,\n    handleUpdateDsl,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n  } = props\n\n  const fileListRef = useRef<UploadItem[]>([])\n  const [currentFileList, setFileList] = useState<UploadItem[]>([])\n  const fileCountRef = useRef<number>(0)\n  const previousValueRef = useRef<UploadItem[]>([])\n\n  const prevFileList = useRef<UploadItem[]>(currentFileList ?? [])\n  const prevParseValue = useRef<boolean>(parseValue ?? false)\n\n  useEffect(() => {\n    const canInitialDragValue =\n      currentList &&\n      currentList.length > 0 &&\n      value &&\n      files &&\n      fileListRef.current?.length === 0 &&\n      previousValueRef.current.length === 0\n\n    if (canInitialDragValue) {\n      const shownList = currentList.map((file, index) => {\n        const base64 = value[index]\n        const info = files[index]\n\n        return {\n          ...file,\n          originFile: !base64\n            ? new File([\"\"], info.name, info)\n            : dataURLtoFile(`data:${info.type};base64,${base64}`, info.name),\n        }\n      }) as UploadItem[]\n      setFileList(shownList)\n      fileListRef.current = shownList\n    }\n  }, [currentList, value, files])\n\n  const getFileIndex = useCallback((files: UploadItem[], file: UploadItem) => {\n    const currentFilesKeys = files.map((f) => f.uid || f.name)\n    return currentFilesKeys.indexOf(file.uid || file.name)\n  }, [])\n\n  const getValidateMessage = useCallback(\n    (value?: UploadItem[]) => {\n      if (!hideValidationMessage) {\n        const message = handleValidateCheck({\n          value,\n          minFiles,\n          maxFiles,\n          minSize,\n          maxSize,\n          sizeType,\n          required,\n          customRule,\n        })\n        const showMessage = message && message.length > 0\n        return showMessage ? message : \"\"\n      }\n      return \"\"\n    },\n    [\n      customRule,\n      hideValidationMessage,\n      minFiles,\n      maxFiles,\n      minSize,\n      sizeType,\n      maxSize,\n      required,\n    ],\n  )\n\n  const handleValidate = useCallback(\n    (value?: UploadItem[]) => {\n      const message = getValidateMessage(value)\n      handleUpdateDsl({\n        validateMessage: message,\n      })\n      return message\n    },\n    [getValidateMessage, handleUpdateDsl],\n  )\n\n  const handleFilesChange = useCallback(\n    (fileList?: UploadItem[]) => {\n      if (\n        !fileList ||\n        (prevFileList.current === fileList &&\n          prevParseValue.current === parseValue)\n      ) {\n        return\n      }\n      prevFileList.current = fileList\n      prevParseValue.current = parseValue ?? false\n      new Promise(async (resolve) => {\n        const values = await Promise.allSettled(\n          fileList.map(async (file) => await toBase64(file)),\n        )\n        let parsedValues\n        if (parseValue) {\n          parsedValues = await Promise.allSettled(\n            fileList.map(async (file) => {\n              const res = await getFileString(file)\n              return res\n            }),\n          )\n        }\n        resolve({\n          values,\n          parsedValues,\n          fileList,\n        })\n      })\n        .then((value) => {\n          const {\n            values,\n            parsedValues,\n            fileList = [],\n          } = value as {\n            values: any[]\n            parsedValues: any[]\n            fileList: UploadItem[]\n          }\n          const validateMessage = getValidateMessage(fileList)\n          const base64value = getFilteredValue(values, \"base64\")\n          const files = getFiles(fileList, base64value ?? [])\n          const parsed = getFilteredValue(parsedValues)\n          const currentList = getCurrentList(fileList)\n          handleUpdateMultiExecutionResult([\n            {\n              displayName,\n              value: {\n                files,\n                value: base64value,\n                parsedValue: parsed,\n                validateMessage,\n                currentList,\n              },\n            },\n          ])\n        })\n        .then(() => {\n          triggerEventHandler(\"change\")\n        })\n    },\n    [\n      displayName,\n      getValidateMessage,\n      handleUpdateMultiExecutionResult,\n      parseValue,\n      triggerEventHandler,\n    ],\n  )\n\n  const handleOnRemove = (file: UploadItem) => {\n    const currentFiles =\n      previousValueRef.current.length > 0\n        ? [...previousValueRef.current]\n        : [...(fileListRef.current || [])]\n    const index = getFileIndex(currentFiles, file)\n    currentFiles.splice(index, 1)\n    setFileList(currentFiles)\n    fileListRef.current = currentFiles\n    if (previousValueRef.current.length > 0) {\n      previousValueRef.current = currentFiles\n    }\n    handleFilesChange(currentFiles)\n    return true\n  }\n\n  const customRequest = (options: RequestOptions) => {\n    options.onSuccess()\n  }\n\n  const onChanges = useCallback(\n    (fileList: UploadItem[], file: UploadItem) => {\n      let files = [...previousValueRef.current]\n      if (file.status === \"init\") {\n        files.push(file)\n        previousValueRef.current = [...files]\n        setFileList(files)\n        fileCountRef.current += 1\n        return\n      }\n      const index = getFileIndex(previousValueRef.current, file)\n      if (index < 0) {\n        return\n      }\n      files.splice(index, 1, file)\n      setFileList(files)\n      previousValueRef.current = files\n      if (files.length === fileCountRef.current && !!fileCountRef.current) {\n        const allSettled = files.every(\n          (f) => f.status === \"error\" || f.status === \"done\",\n        )\n        if (allSettled) {\n          const newList = appendFiles\n            ? [...(fileListRef.current || []), ...files]\n            : files\n          setFileList(newList)\n          fileListRef.current = newList\n          previousValueRef.current = []\n          fileCountRef.current = 0\n          handleFilesChange(newList)\n        }\n      }\n      return\n    },\n    [appendFiles, getFileIndex, handleFilesChange],\n  )\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      clearValue: () => {\n        handleUpdateDsl({ value: [] })\n        setFileList([])\n      },\n      validate: () => {\n        return handleValidate(currentFileList)\n      },\n      setDisabled: (value: boolean) => {\n        handleUpdateDsl({\n          disabled: value,\n        })\n      },\n      clearValidation: () => {\n        handleUpdateDsl({\n          validateMessage: \"\",\n        })\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    currentFileList,\n    deleteComponentRuntimeProps,\n    handleUpdateDsl,\n    handleValidate,\n    updateComponentRuntimeProps,\n  ])\n\n  return (\n    <AutoHeightContainer\n      updateComponentHeight={updateComponentHeight}\n      enable={true}\n    >\n      <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n        <div css={uploadLayoutStyle}>\n          <WrappedUpload\n            {...props}\n            fileList={currentFileList}\n            onChange={onChanges}\n            onRemove={handleOnRemove}\n            getValidateMessage={getValidateMessage}\n            customRequest={customRequest}\n          />\n        </div>\n      </TooltipWrapper>\n      <div css={applyValidateMessageWrapperStyle(0, \"left\", true)}>\n        <InvalidMessage validateMessage={validateMessage} />\n      </div>\n    </AutoHeightContainer>\n  )\n}\nUploadWidget.displayName = \"UploadWidget\"\nexport default UploadWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/UploadWidget/util.ts",
    "content": "import { UploadItem } from \"@illa-design/react\"\nimport { handleParseFile } from \"@/utils/file\"\n\nexport const getFileString = (file: UploadItem) =>\n  new Promise((resolve, reject) => {\n    const originFile = file.originFile\n    if (originFile) {\n      handleParseFile(originFile)\n        .then((data) => {\n          // TODO: WFT, dynamic bug\n          resolve(data.replaceAll(\"{{\", \"{ {\").replaceAll(\"}}\", \"} }\"))\n        })\n        .catch(() => {\n          reject()\n        })\n    } else {\n      resolve(undefined)\n    }\n  })\n\nexport const toBase64 = (file: UploadItem) =>\n  new Promise((resolve, reject) => {\n    if (!file) {\n      resolve(undefined)\n    }\n    const reader = new FileReader()\n    if (file.originFile) {\n      reader.onload = () => resolve(reader.result)\n      reader.onerror = (error) => reject(error)\n      reader.readAsDataURL(file.originFile)\n    } else {\n      resolve(undefined)\n    }\n  })\n\ntype ValueType = Array<{ status: string; value: any }>\n\nexport const getFilteredValue = (values?: ValueType, type?: string) => {\n  if (!values) {\n    return\n  }\n  const filteredValue = values.filter(\n    (data) => data.value !== undefined && data.status === \"fulfilled\",\n  )\n  if (filteredValue && filteredValue.length > 0) {\n    const isBase64 = type === \"base64\"\n    return filteredValue.map((data) =>\n      isBase64 ? data.value.split(\",\")[1] : data.value,\n    )\n  }\n  return []\n}\n\nexport const dataURLtoFile = (dataurl: string, filename: string) => {\n  const arr = dataurl.split(\",\")\n  const mime = arr[0].match(/:(.*?);/)?.[1]\n  const bstr = atob(arr[1])\n  let n = bstr.length\n  const u8arr = new Uint8Array(n)\n\n  while (n--) {\n    u8arr[n] = bstr.charCodeAt(n)\n  }\n  return new File([u8arr], filename, { type: mime })\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/UploadWidget/widgetConfig.tsx",
    "content": "import UploadWidgetIcon from \"@/assets/widgetCover/upload.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { RESIZE_DIRECTION, WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const UPLOAD_WIDGET_CONFIG: WidgetConfig = {\n  displayName: \"upload\",\n  widgetName: i18n.t(\"widget.upload.name\"),\n  h: 5,\n  w: 6,\n  type: \"UPLOAD_WIDGET\",\n  icon: <UploadWidgetIcon />,\n  keywords: [\"Upload Input\", \"上传\"],\n  sessionType: \"INPUTS\",\n  resizeDirection: RESIZE_DIRECTION.HORIZONTAL,\n  version: 0,\n  defaults: {\n    type: \"button\",\n    buttonText: i18n.t(\"widget.upload.default_button_text\"),\n    selectionType: \"single\",\n    dropText: i18n.t(\"widget.upload.default_dropzone_text\"),\n    verticalAlign: \"center\",\n    hidden: false,\n    appendFiles: false,\n    fileType: \"\",\n    variant: \"fill\",\n    colorScheme: \"blue\",\n    formDataKey: \"upload\",\n    showFileList: false,\n    sizeType: \"mb\",\n    dynamicHeight: \"auto\",\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/VideoWidget/eventHandlerConfig.ts",
    "content": "import i18n from \"@/i18n/config\"\nimport { EventHandlerConfig } from \"@/widgetLibrary/interface\"\n\nexport const VIDEO_EVENT_HANDLER_CONFIG: EventHandlerConfig = {\n  events: [\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.play\",\n      ),\n      value: \"play\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.pause\",\n      ),\n      value: \"pause\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.loaded\",\n      ),\n      value: \"loaded\",\n    },\n    {\n      label: i18n.t(\n        \"editor.inspect.setter_content.widget_action_type_name.ended\",\n      ),\n      value: \"ended\",\n    },\n  ],\n  methods: [\n    \"play\",\n    \"pause\",\n    \"showControls\",\n    \"setVideoUrl\",\n    \"setVolume\",\n    \"setSpeed\",\n    \"setLoop\",\n    \"seekTo\",\n    \"mute\",\n  ],\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/VideoWidget/index.tsx",
    "content": "export { VIDEO_WIDGET_CONFIG } from \"./widgetConfig\"\nexport { VIDEO_PANEL_CONFIG } from \"./panelConfig\"\nexport { VIDEO_EVENT_HANDLER_CONFIG } from \"./eventHandlerConfig\"\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/VideoWidget/interface.tsx",
    "content": "import { TooltipWrapperProps } from \"@/widgetLibrary/PublicSector/TooltipWrapper/interface\"\nimport { BaseWidgetProps } from \"@/widgetLibrary/interface\"\n\n// todo: @echoxyc error extends\nexport interface WrappedVideoProps extends BaseWidgetProps {\n  url?: string\n  controls?: boolean\n  autoPlay?: boolean\n  playing?: boolean\n  loop?: boolean\n  volume?: number\n  playbackRate?: number\n  muted?: boolean\n  onPlay: () => void\n  onPause: () => void\n  onEnded: () => void\n  onReady: () => void\n  onPlaybackRateChange: (rate: number) => void\n}\n\nexport interface VideoWidgetProps\n  extends Omit<WrappedVideoProps, \"onPlay\" | \"onPause\" | \"onEnded\" | \"onReady\">,\n    BaseWidgetProps,\n    TooltipWrapperProps {}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/VideoWidget/panelConfig.tsx",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport i18n from \"@/i18n/config\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { VALIDATION_TYPES } from \"@/utils/validationFactory\"\nimport { generatorEventHandlerConfig } from \"@/widgetLibrary/PublicSector/utils/generatorEventHandlerConfig\"\nimport { VIDEO_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/VideoWidget/eventHandlerConfig\"\n\nconst baseWidgetName = \"video\"\nexport const VIDEO_PANEL_CONFIG: PanelConfig[] = [\n  {\n    id: `${baseWidgetName}-basic`,\n    groupName: i18n.t(\"editor.inspect.setter_group.basic\"),\n    children: [\n      {\n        id: `${baseWidgetName}-basic-source-self-host`,\n        attrName: \"url\",\n        expectedType: VALIDATION_TYPES.STRING,\n        labelName: i18n.t(\"editor.inspect.setter_label.video_url\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.video_url\"),\n        isSetterSingleRow: true,\n        bindAttrName: [],\n        shown: () => !isCloudVersion,\n        setterType: \"INPUT_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-source-cloud-version`,\n        attrName: \"url\",\n        expectedType: VALIDATION_TYPES.STRING,\n        labelName: i18n.t(\"editor.inspect.setter_label.video_url\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.video_url\"),\n        isSetterSingleRow: true,\n        bindAttrName: [],\n        shown: () => isCloudVersion,\n        setterType: \"DRIVE_SOURCE_GROUP_SETTER\",\n      },\n      {\n        id: `${baseWidgetName}-basic-autoPlay`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.autoplay\"),\n        useCustomLayout: true,\n        attrName: \"autoPlay\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-loop`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.loop\"),\n        useCustomLayout: true,\n        attrName: \"loop\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-controls`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.show_controls\"),\n        useCustomLayout: true,\n        attrName: \"controls\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-mute`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.mute\"),\n        useCustomLayout: true,\n        attrName: \"muted\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n      {\n        id: `${baseWidgetName}-basic-volume`,\n        labelName: i18n.t(\"editor.inspect.setter_label.volume\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tootip.volume\"),\n        placeholder: \"{{ 0.5 }}\",\n        attrName: \"volume\",\n        expectedType: VALIDATION_TYPES.NUMBER,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-interaction`,\n    groupName: i18n.t(\"editor.inspect.setter_group.interaction\"),\n    children: [\n      {\n        ...generatorEventHandlerConfig(\n          baseWidgetName,\n          VIDEO_EVENT_HANDLER_CONFIG.events,\n        ),\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-adornments`,\n    groupName: i18n.t(\"editor.inspect.setter_group.adornments\"),\n    children: [\n      {\n        id: `${baseWidgetName}-adornments-tooltip`,\n        labelName: i18n.t(\"editor.inspect.setter_label.tooltip\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.tooltip\"),\n        attrName: \"tooltipText\",\n        expectedType: VALIDATION_TYPES.STRING,\n        setterType: \"INPUT_SETTER\",\n      },\n    ],\n  },\n  {\n    id: `${baseWidgetName}-layout`,\n    groupName: i18n.t(\"editor.inspect.setter_group.layout\"),\n    children: [\n      {\n        id: `${baseWidgetName}-layout-hidden`,\n        setterType: \"DYNAMIC_SWITCH_SETTER\",\n        openDynamic: true,\n        labelName: i18n.t(\"editor.inspect.setter_label.hidden\"),\n        labelDesc: i18n.t(\"editor.inspect.setter_tooltip.hidden\"),\n        useCustomLayout: true,\n        attrName: \"hidden\",\n        expectedType: VALIDATION_TYPES.BOOLEAN,\n      },\n    ],\n  },\n]\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/VideoWidget/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const fullStyle = css`\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n`\n\nexport const loadingStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background-color: ${getColor(\"gray\", \"01\")};\n  color: ${getColor(\"white\", \"01\")};\n`\n\nexport const applyHiddenStyle = (hidden: boolean): SerializedStyles => {\n  return css`\n    visibility: ${hidden ? \"hidden\" : \"visible\"};\n  `\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/VideoWidget/video.tsx",
    "content": "import { isBoolean } from \"lodash-es\"\nimport {\n  FC,\n  forwardRef,\n  useCallback,\n  useContext,\n  useEffect,\n  useRef,\n  useState,\n} from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport ReactPlayer from \"react-player\"\nimport { Loading, isNumber, isString } from \"@illa-design/react\"\nimport { MediaSourceLoadContext } from \"@/utils/mediaSourceLoad\"\nimport { TooltipWrapper } from \"@/widgetLibrary/PublicSector/TooltipWrapper\"\nimport { fullStyle, loadingStyle } from \"@/widgetLibrary/VideoWidget/style\"\nimport { VideoWidgetProps, WrappedVideoProps } from \"./interface\"\n\nexport const WrappedVideo = forwardRef<ReactPlayer, WrappedVideoProps>(\n  (props, ref) => {\n    const {\n      url,\n      playing,\n      autoPlay,\n      controls = true,\n      loop,\n      volume,\n      muted,\n      playbackRate,\n      onPlay,\n      onReady,\n      onPause,\n      onEnded,\n      onPlaybackRateChange,\n    } = props\n    const { t } = useTranslation()\n    const [loading, setLoading] = useState(true)\n    const [error, setError] = useState(false)\n    const { sourceLoadErrorHandler } = useContext(MediaSourceLoadContext)\n\n    if (url === \"\") {\n      return <div css={loadingStyle}>{t(\"widget.video.empty\")}</div>\n    }\n\n    return (\n      <>\n        {loading ? (\n          <div css={loadingStyle}>\n            <Loading colorScheme=\"white\" />\n          </div>\n        ) : error ? (\n          <div css={loadingStyle}>{t(\"widget.video.fail\")}</div>\n        ) : null}\n        <ReactPlayer\n          style={loading || error ? { display: \"none\" } : undefined}\n          fallback={\n            <div css={loadingStyle}>\n              <Loading colorScheme=\"white\" />\n            </div>\n          }\n          ref={ref}\n          width=\"100%\"\n          height=\"100%\"\n          url={url}\n          volume={volume}\n          muted={muted}\n          controls={controls}\n          playbackRate={playbackRate}\n          loop={loop}\n          playing={autoPlay || playing}\n          draggable={false}\n          onReady={() => {\n            setLoading(false)\n            setError(false)\n            onReady()\n          }}\n          onPlay={onPlay}\n          onPause={onPause}\n          onEnded={onEnded}\n          onError={() => {\n            sourceLoadErrorHandler?.(url, \"VIDEO_WIDGET\")\n            setLoading(false)\n            setError(true)\n          }}\n          onPlaybackRateChange={onPlaybackRateChange}\n        />\n      </>\n    )\n  },\n)\n\nWrappedVideo.displayName = \"WrappedVideo\"\n\nexport const VideoWidget: FC<VideoWidgetProps> = (props) => {\n  const {\n    handleUpdateMultiExecutionResult,\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    displayName,\n    tooltipText,\n    triggerEventHandler,\n    controls,\n  } = props\n\n  const videoRef = useRef<ReactPlayer>(null)\n\n  useEffect(() => {\n    updateComponentRuntimeProps({\n      play: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { playing: true },\n          },\n        ])\n      },\n      pause: () => {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { playing: false },\n          },\n        ])\n      },\n      setVideoUrl: (url: string) => {\n        if (!isString(url)) {\n          console.error(\"TypeError: url is not a string\")\n          return\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { url },\n          },\n        ])\n      },\n      seekTo: (time: number, type: \"seconds\" | \"fraction\" = \"seconds\") => {\n        if (!isNumber(time)) {\n          console.error(\"TypeError: value is not a number\")\n          return\n        }\n        videoRef.current?.seekTo(time, type)\n      },\n      mute: (value: boolean) => {\n        if (!isBoolean(value)) {\n          console.error(\"TypeError: value is not a boolean\")\n          return\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { muted: value },\n          },\n        ])\n      },\n      showControls: (value: boolean) => {\n        if (!isBoolean(value)) {\n          console.error(\"TypeError: value is not a boolean\")\n          return\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { controls: value },\n          },\n        ])\n      },\n      setLoop: (value: boolean) => {\n        if (!isBoolean(value)) {\n          console.error(\"TypeError: value is not a boolean\")\n          return\n        }\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { loop: value },\n          },\n        ])\n      },\n      setSpeed: (value: number) => {\n        if (!isNumber(value)) {\n          console.error(\"TypeError: value is not a number\")\n          return\n        }\n        // playbackRate range [0.0625, 16]\n        const clampedValue = Math.max(0.0625, Math.min(16, value))\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { playbackRate: clampedValue },\n          },\n        ])\n      },\n      setVolume: (value: number) => {\n        if (!isNumber(value)) {\n          console.error(\"TypeError: value is not a number\")\n          return\n        }\n        // volume range [0, 1]\n        const clampedValue = Math.max(0, Math.min(1, value))\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { volume: clampedValue },\n          },\n        ])\n      },\n    })\n    return () => {\n      deleteComponentRuntimeProps()\n    }\n  }, [\n    updateComponentRuntimeProps,\n    deleteComponentRuntimeProps,\n    handleUpdateMultiExecutionResult,\n    displayName,\n  ])\n\n  const onPlay = useCallback(() => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: { playing: true },\n      },\n    ])\n    triggerEventHandler(\"play\")\n  }, [displayName, triggerEventHandler, handleUpdateMultiExecutionResult])\n\n  const onPause = useCallback(() => {\n    handleUpdateMultiExecutionResult([\n      {\n        displayName,\n        value: { playing: false },\n      },\n    ])\n    triggerEventHandler(\"pause\")\n  }, [displayName, triggerEventHandler, handleUpdateMultiExecutionResult])\n\n  const onReady = useCallback(() => {\n    triggerEventHandler(\"loaded\")\n  }, [triggerEventHandler])\n\n  const onEnded = useCallback(() => {\n    triggerEventHandler(\"ended\")\n  }, [triggerEventHandler])\n\n  const onPlaybackRateChange = useCallback(\n    (playbackRate: number) => {\n      if (isNumber(playbackRate)) {\n        handleUpdateMultiExecutionResult([\n          {\n            displayName,\n            value: { playbackRate },\n          },\n        ])\n      }\n    },\n    [displayName, handleUpdateMultiExecutionResult],\n  )\n\n  return (\n    <TooltipWrapper tooltipText={tooltipText} tooltipDisabled={!tooltipText}>\n      <div css={fullStyle}>\n        <WrappedVideo\n          {...props}\n          // controls change need to reload react-player\n          key={Number(controls)}\n          ref={videoRef}\n          onReady={onReady}\n          onPlay={onPlay}\n          onPause={onPause}\n          onEnded={onEnded}\n          onPlaybackRateChange={onPlaybackRateChange}\n        />\n      </div>\n    </TooltipWrapper>\n  )\n}\n\nVideoWidget.displayName = \"VideoWidget\"\nexport default VideoWidget\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/VideoWidget/widgetConfig.tsx",
    "content": "import VideoWidgetIcon from \"@/assets/widgetCover/video.svg?react\"\nimport i18n from \"@/i18n/config\"\nimport { WidgetConfig } from \"@/widgetLibrary/interface\"\n\nexport const VIDEO_WIDGET_CONFIG: WidgetConfig = {\n  type: \"VIDEO_WIDGET\",\n  displayName: \"video\",\n  widgetName: i18n.t(\"widget.video.name\"),\n  keywords: [\"Video\", \"视频\"],\n  icon: <VideoWidgetIcon />,\n  sessionType: \"PRESENTATION\",\n  w: 16,\n  h: 25,\n  version: 0,\n  defaults: {\n    url: \"https://youtu.be/8sUovZlBh_M\",\n    hidden: false,\n    autoPlay: false,\n    loop: false,\n    playing: false,\n    muted: false,\n    controls: true,\n    volume: undefined,\n  },\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/interface.ts",
    "content": "import { CONTAINER_TYPE } from \"@illa-public/public-types\"\nimport { FC, ReactNode } from \"react\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport { WidgetType } from \"@/widgetLibrary/widgetBuilder\"\nimport { SessionType } from \"../page/App/components/ComponentPanel/componentListBuilder\"\n\nexport interface EventHandlerConfig {\n  events: {\n    label: string\n    value: string\n  }[]\n  methods: string[]\n}\n\nexport interface WidgetConfigs {\n  [key: string]: {\n    widget: FC<any>\n    config: WidgetConfig\n    panelConfig: PanelConfig[]\n    eventHandlerConfig?: EventHandlerConfig\n  }\n}\n\nexport interface DraggableWrapperShape {\n  w: number\n  h: number\n  minW?: number\n  minH?: number\n  x?: number\n  y?: number\n}\n\nexport enum RESIZE_DIRECTION {\n  \"ALL\" = \"ALL\",\n  \"HORIZONTAL\" = \"HORIZONTAL\",\n  \"VERTICAL\" = \"VERTICAL\",\n}\n\nexport interface BaseWidgetInfo {\n  displayName: string\n  widgetName: any\n  icon: ReactNode\n  type: WidgetType\n  containerType?: CONTAINER_TYPE\n  sessionType?: SessionType\n  keywords?: string[]\n  resizeDirection?: RESIZE_DIRECTION\n  version: number\n}\n\ntype defaultsType = () => Record<string, any>\n\nexport interface WidgetCardInfo extends DraggableWrapperShape, BaseWidgetInfo {\n  id: string\n  childrenNode?: Omit<WidgetConfig, \"icon\" | \"keywords\" | \"sessionType\">[]\n  defaults?: defaultsType | Record<string, any>\n}\n\nexport type WidgetConfig = Omit<WidgetCardInfo, \"id\">\n\nexport interface EventsInProps {\n  script: string\n  eventType: string\n  enabled?: string\n}\n\nexport interface BaseWidgetProps {\n  displayName: string\n  childrenNode: string[]\n  handleUpdateDsl: (value: any) => void\n  handleUpdateMultiExecutionResult: (\n    updateSlice: {\n      displayName: string\n      value: Record<string, any>\n    }[],\n  ) => void\n  updateComponentHeight: (newHeight: number) => void\n  handleUpdateOriginalDSLMultiAttr: (\n    updateSlice: Record<string, any>,\n    notUseUndoRedo?: boolean,\n  ) => void\n  handleUpdateOriginalDSLOtherMultiAttr: (\n    displayName: string,\n    updateSlice: Record<string, any>,\n    notUseUndoRedo?: boolean,\n  ) => void\n  triggerEventHandler: (\n    eventType: string,\n    path?: string,\n    otherCalcContext?: Record<string, any>,\n    formatPath?: (path: string) => string,\n  ) => void\n  triggerMappedEventHandler: (\n    eventType: string,\n    path: string,\n    index?: number,\n    formatPath?: (path: string) => string,\n    isMapped?: (dynamicString: string, calcValue: unknown) => boolean,\n  ) => void\n  w: number\n  h: number\n  unitW: number\n  unitH: number\n  updateComponentRuntimeProps: (runtimeProps: unknown) => void\n  deleteComponentRuntimeProps: () => void\n}\n\nexport interface BaseComponentNodeProps {\n  w: number\n  h: number\n  unitW: number\n  unitH: number\n}\n"
  },
  {
    "path": "apps/builder/src/widgetLibrary/widgetBuilder.tsx",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport { FC, LazyExoticComponent, lazy } from \"react\"\nimport { PanelConfig } from \"@/page/App/components/InspectPanel/interface\"\nimport {\n  AUDIO_EVENT_HANDLER_CONFIG,\n  AUDIO_PANEL_CONFIG,\n  AUDIO_WIDGET_CONFIG,\n} from \"@/widgetLibrary/AudioWidget\"\nimport {\n  BAR_PROGRESS_EVENT_HANDLER_CONFIG,\n  BAR_PROGRESS_PANEL_CONFIG,\n  BAR_PROGRESS_WIDGET_CONFIG,\n} from \"@/widgetLibrary/BarProgressWidget\"\nimport {\n  BUTTON_EVENT_HANDLER_CONFIG,\n  BUTTON_PANEL_CONFIG,\n  BUTTON_WIDGET_CONFIG,\n} from \"@/widgetLibrary/ButtonWidget\"\nimport {\n  CAROUSEL_EVENT_HANDLER_CONFIG,\n  CAROUSEL_PANEL_CONFIG,\n  CAROUSEL_WIDGET_CONFIG,\n} from \"@/widgetLibrary/CarouselWidget\"\nimport {\n  CASCADER_PANEL_CONFIG,\n  CASCADER_WIDGET_CONFIG,\n} from \"@/widgetLibrary/CascaderWidget\"\nimport { CASCADER_EVENT_HANDLER_CONFIG } from \"@/widgetLibrary/CascaderWidget/eventHandlerConfig\"\nimport {\n  CHART_PANEL_CONFIG,\n  CHART_WIDGET_CONFIG,\n  CHART_WIDGET_V2_CONFIG,\n} from \"@/widgetLibrary/ChartWidget\"\nimport {\n  CHAT_EVENT_HANDLER_CONFIG,\n  CHAT_PANEL_CONFIG,\n  CHAT_WIDGET_CONFIG,\n} from \"@/widgetLibrary/ChatWidget\"\nimport {\n  CHECKBOX_GROUP_PANEL_CONFIG,\n  CHECKBOX_GROUP_WIDGET_CONFIG,\n  CHECK_BOX_GROUP_EVENT_HANDLER_CONFIG,\n} from \"@/widgetLibrary/CheckboxGroupWidget\"\nimport {\n  CIRCLE_PROGRESS_EVENT_HANDLER_CONFIG,\n  CIRCLE_PROGRESS_PANEL_CONFIG,\n  CIRCLE_PROGRESS_WIDGET_CONFIG,\n} from \"@/widgetLibrary/CircleProgressWidget\"\nimport {\n  CONTAINER_EVENT_HANDLER_CONFIG,\n  CONTAINER_PANEL_CONFIG,\n  CONTAINER_WIDGET_CONFIG,\n} from \"@/widgetLibrary/ContainerWidget\"\nimport {\n  DATA_GRID_EVENT_HANDLER_CONFIG,\n  DATA_GRID_PANEL_CONFIG,\n  DATA_GRID_WIDGET_CONFIG,\n} from \"@/widgetLibrary/DataGridWidget\"\nimport {\n  DATE_RANGE_EVENT_HANDLER_CONFIG,\n  DATE_RANGE_PANEL_CONFIG,\n  DATE_RANGE_WIDGET_CONFIG,\n} from \"@/widgetLibrary/DateRangeWidget\"\nimport {\n  DATE_TIME_EVENT_HANDLER_CONFIG,\n  DATE_TIME_PANEL_CONFIG,\n  DATE_TIME_WIDGET_CONFIG,\n} from \"@/widgetLibrary/DateTimeWidget\"\nimport {\n  DATE_EVENT_HANDLER_CONFIG,\n  DATE_PANEL_CONFIG,\n  DATE_WIDGET_CONFIG,\n} from \"@/widgetLibrary/DateWidget\"\nimport {\n  DIVIDER_EVENT_HANDLER_CONFIG,\n  DIVIDER_PANEL_CONFIG,\n  DIVIDER_WIDGET_CONFIG,\n} from \"@/widgetLibrary/DividerWidget\"\nimport {\n  DRIVE_PICKER_EVENT_HANDLER_CONFIG,\n  DRIVE_PICKER_PANEL_CONFIG,\n  DRIVE_PICKER_WIDGET_CONFIG,\n} from \"@/widgetLibrary/DrivePickerWidget\"\nimport {\n  EDITABLE_EVENT_HANDLER_CONFIG,\n  EDITABLE_TEXT_PANEL_CONFIG,\n  EDITABLE_TEXT_WIDGET_CONFIG,\n} from \"@/widgetLibrary/EditableWidget\"\nimport {\n  EVENT_CALENDAR_EVENT_HANDLER_CONFIG,\n  EVENT_CALENDAR_PANEL_CONFIG,\n  EVENT_CALENDAR_WIDGET_CONFIG,\n} from \"@/widgetLibrary/EventCalendarWidget\"\nimport {\n  FORM_EVENT_HANDLER_CONFIG,\n  FORM_PANEL_CONFIG,\n  FORM_WIDGET_CONFIG,\n} from \"@/widgetLibrary/FormWidget\"\nimport {\n  IFRAME_PANEL_CONFIG,\n  IFRAME_WIDGET_CONFIG,\n} from \"@/widgetLibrary/IFrameWidget\"\nimport {\n  ICON_EVENT_HANDLER_CONFIG,\n  ICON_PANEL_CONFIG,\n  ICON_WIDGET_CONFIG,\n} from \"@/widgetLibrary/IconWidget\"\nimport {\n  IMAGE_EVENT_HANDLER_CONFIG,\n  IMAGE_PANEL_CONFIG,\n  IMAGE_WIDGET_CONFIG,\n} from \"@/widgetLibrary/ImageWidget\"\nimport {\n  INPUT_EVENT_HANDLER_CONFIG,\n  INPUT_PANEL_CONFIG,\n  INPUT_WIDGET_CONFIG,\n} from \"@/widgetLibrary/InputWidget\"\nimport {\n  JSON_EDITOR_EVENT_HANDLER_CONFIG,\n  JSON_EDITOR_PANEL_CONFIG,\n  JSON_EDITOR_WIDGET_CONFIG,\n} from \"@/widgetLibrary/JsonEditorWidget\"\nimport {\n  JSON_SCHEMA_FORM_EVENT_HANDLER_CONFIG,\n  JSON_SCHEMA_FORM_PANEL_CONFIG,\n  JSON_SCHEMA_FORM_WIDGET_CONFIG,\n} from \"@/widgetLibrary/JsonSchemaFormWidget\"\nimport {\n  LIST_EVENT_HANDLER_CONFIG,\n  LIST_PANEL_CONFIG,\n  LIST_WIDGET_CONFIG,\n} from \"@/widgetLibrary/ListWidget\"\nimport {\n  MAP_EVENT_HANDLER_CONFIG,\n  MAP_PANEL_CONFIG,\n  MAP_WIDGET_CONFIG,\n} from \"@/widgetLibrary/MapBoxWidget\"\nimport {\n  MENU_EVENT_HANDLER_CONFIG,\n  MENU_PANEL_CONFIG,\n  MENU_WIDGET_CONFIG,\n} from \"@/widgetLibrary/MenuWidget\"\nimport {\n  MODAL_EVENT_HANDLER_CONFIG,\n  MODAL_PANEL_CONFIG,\n  MODAL_WIDGET_CONFIG,\n} from \"@/widgetLibrary/ModalWidget\"\nimport {\n  MULTISELECT_EVENT_HANDLER_CONFIG,\n  MULTISELECT_PANEL_CONFIG,\n  MULTISELECT_WIDGET_CONFIG,\n} from \"@/widgetLibrary/MultiselectWidget\"\nimport {\n  INPUT_NUMBER_EVENT_HANDLER_CONFIG,\n  NUMBER_INPUT_PANEL_CONFIG,\n  NUMBER_INPUT_WIDGET_CONFIG,\n} from \"@/widgetLibrary/NumberInputWidget\"\nimport {\n  PDF_EVENT_HANDLER_CONFIG,\n  PDF_PANEL_CONFIG,\n  PDF_WIDGET_CONFIG,\n} from \"@/widgetLibrary/PdfWidget\"\nimport {\n  RADIO_BUTTON_EVENT_HANDLER_CONFIG,\n  RADIO_BUTTON_PANEL_CONFIG,\n  RADIO_BUTTON_WIDGET_CONFIG,\n} from \"@/widgetLibrary/RadioButtonWidget\"\nimport {\n  RADIO_GROUP_EVENT_HANDLER_CONFIG,\n  RADIO_GROUP_PANEL_CONFIG,\n  RADIO_GROUP_WIDGET_CONFIG,\n} from \"@/widgetLibrary/RadioGroupWidget\"\nimport {\n  RANGE_SLIDER_EVENT_HANDLER_CONFIG,\n  RANGE_SLIDER_PANEL_CONFIG,\n  RANGE_SLIDER_WIDGET_CONFIG,\n} from \"@/widgetLibrary/RangeSliderWidget\"\nimport {\n  RATE_EVENT_HANDLER_CONFIG,\n  RATE_PANEL_CONFIG,\n  RATE_WIDGET_CONFIG,\n} from \"@/widgetLibrary/RateWidget\"\nimport {\n  RECORDING_HANDLER_CONFIG,\n  RECORDING_PANEL_CONFIG,\n  RECORDING_WIDGET_CONFIG,\n} from \"@/widgetLibrary/RecordingWidget\"\nimport {\n  RICH_TEXT_EVENT_HANDLER_CONFIG,\n  RICH_TEXT_PANEL_CONFIG,\n  RICH_TEXT_WIDGET_CONFIG,\n} from \"@/widgetLibrary/RichTextWidget\"\nimport {\n  SELECT_EVENT_HANDLER_CONFIG,\n  SELECT_PANEL_CONFIG,\n  SELECT_WIDGET_CONFIG,\n} from \"@/widgetLibrary/SelectWidget\"\nimport {\n  SLIDER_EVENT_HANDLER_CONFIG,\n  SLIDER_PANEL_CONFIG,\n  SLIDER_WIDGET_CONFIG,\n} from \"@/widgetLibrary/SliderWidget\"\nimport {\n  STATISTICS_EVENT_HANDLER_CONFIG,\n  STATISTICS_PANEL_CONFIG,\n  STATISTICS_WIDGET_CONFIG,\n} from \"@/widgetLibrary/StatisticsWidget\"\nimport {\n  STEPS_EVENT_HANDLER_CONFIG,\n  STEPS_PANEL_CONFIG,\n  STEPS_WIDGET_CONFIG,\n} from \"@/widgetLibrary/StepsWidget\"\nimport {\n  SWITCH_GROUP_EVENT_HANDLER_CONFIG,\n  SWITCH_GROUP_PANEL_CONFIG,\n  SWITCH_GROUP_WIDGET_CONFIG,\n} from \"@/widgetLibrary/SwitchGroupWidget\"\nimport {\n  SWITCH_EVENT_HANDLER_CONFIG,\n  SWITCH_PANEL_CONFIG,\n  SWITCH_WIDGET_CONFIG,\n} from \"@/widgetLibrary/SwitchWidget\"\nimport {\n  TABLE_EVENT_HANDLER_CONFIG,\n  TABLE_PANEL_CONFIG,\n  TABLE_WIDGET_CONFIG,\n} from \"@/widgetLibrary/TableWidget\"\nimport {\n  TABS_EVENT_HANDLER_CONFIG,\n  TABS_PANEL_CONFIG,\n  TABS_WIDGET_CONFIG,\n} from \"@/widgetLibrary/TabsWidget\"\nimport {\n  TAGS_EVENT_HANDLER_CONFIG,\n  TAGS_PANEL_CONFIG,\n  TAGS_WIDGET_CONFIG,\n} from \"@/widgetLibrary/TagsWidget\"\nimport {\n  TEXTAREA_EVENT_HANDLER_CONFIG,\n  TEXTAREA_PANEL_CONFIG,\n  TEXTAREA_WIDGET_CONFIG,\n} from \"@/widgetLibrary/TextAreaWidget\"\nimport {\n  TEXT_EVENT_HANDLER_CONFIG,\n  TEXT_PANEL_CONFIG,\n  TEXT_WIDGET_CONFIG,\n} from \"@/widgetLibrary/TextWidget\"\nimport {\n  TIME_PICKER_EVENT_HANDLER_CONFIG,\n  TIME_PICKER_PANEL_CONFIG,\n  TIME_PICKER_WIDGET_CONFIG,\n} from \"@/widgetLibrary/TimePickerWidget\"\nimport {\n  TIME_RANGE_EVENT_HANDLER_CONFIG,\n  TIME_RANGE_PANEL_CONFIG,\n  TIME_RANGE_WIDGET_CONFIG,\n} from \"@/widgetLibrary/TimeRangeWidget\"\nimport {\n  TIMELINE_EVENT_HANDLER_CONFIG,\n  TIMELINE_PANEL_CONFIG,\n  TIMELINE_WIDGET_CONFIG,\n} from \"@/widgetLibrary/TimelineWidget\"\nimport {\n  UPLOAD_EVENT_HANDLER_CONFIG,\n  UPLOAD_PANEL_CONFIG,\n  UPLOAD_WIDGET_CONFIG,\n} from \"@/widgetLibrary/UploadWidget\"\nimport {\n  VIDEO_EVENT_HANDLER_CONFIG,\n  VIDEO_PANEL_CONFIG,\n  VIDEO_WIDGET_CONFIG,\n} from \"@/widgetLibrary/VideoWidget\"\nimport {\n  AVATAR_EVENT_HANDLER_CONFIG,\n  AVATAR_PANEL_CONFIG,\n  AVATAR_WIDGET_CONFIG,\n} from \"./AvatarWidget\"\nimport {\n  CODE_SCANNER_EVENT_HANDLER_CONFIG,\n  CODE_SCANNER_PANEL_CONFIG,\n  CODE_SCANNER_WIDGET_CONFIG,\n} from \"./CodeScannerWidget\"\nimport {\n  GRID_LIST_EVENT_HANDLER_CONFIG,\n  GRID_LIST_PANEL_CONFIG,\n  GRID_LIST_WIDGET_CONFIG,\n} from \"./GridListWidget\"\nimport { IFRAME_EVENT_HANDLER_CONFIG } from \"./IFrameWidget/eventHandlerConfig\"\nimport {\n  QR_CODE_EVENT_HANDLER_CONFIG,\n  QR_CODE_PANEL_CONFIG,\n  QR_CODE_WIDGET_CONFIG,\n} from \"./QRCodeWidget\"\nimport {\n  SIGNATURE_EVENT_HANDLER_CONFIG,\n  SIGNATURE_PANEL_CONFIG,\n  SIGNATURE_WIDGET_CONFIG,\n} from \"./SignatureWidget\"\nimport { EventHandlerConfig, WidgetConfig } from \"./interface\"\n\nexport const WidgetConfigMap: Record<\n  string,\n  {\n    config: WidgetConfig\n    panelConfig: PanelConfig[]\n    eventHandlerConfig?: EventHandlerConfig\n    widget: LazyExoticComponent<FC<any>>\n  }\n> = {\n  // inputs\n  INPUT_WIDGET: {\n    config: INPUT_WIDGET_CONFIG,\n    panelConfig: INPUT_PANEL_CONFIG,\n    eventHandlerConfig: INPUT_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/InputWidget/input\")),\n  },\n  NUMBER_INPUT_WIDGET: {\n    config: NUMBER_INPUT_WIDGET_CONFIG,\n    panelConfig: NUMBER_INPUT_PANEL_CONFIG,\n    eventHandlerConfig: INPUT_NUMBER_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/NumberInputWidget/numberInput\")),\n  },\n  EDITABLE_TEXT_WIDGET: {\n    config: EDITABLE_TEXT_WIDGET_CONFIG,\n    panelConfig: EDITABLE_TEXT_PANEL_CONFIG,\n    eventHandlerConfig: EDITABLE_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/EditableWidget/editableText\")),\n  },\n  TEXTAREA_INPUT_WIDGET: {\n    config: TEXTAREA_WIDGET_CONFIG,\n    panelConfig: TEXTAREA_PANEL_CONFIG,\n    eventHandlerConfig: TEXTAREA_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/TextAreaWidget/textArea\")),\n  },\n  UPLOAD_WIDGET: {\n    config: UPLOAD_WIDGET_CONFIG,\n    panelConfig: UPLOAD_PANEL_CONFIG,\n    eventHandlerConfig: UPLOAD_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/UploadWidget/upload\")),\n  },\n  SLIDER_WIDGET: {\n    config: SLIDER_WIDGET_CONFIG,\n    panelConfig: SLIDER_PANEL_CONFIG,\n    eventHandlerConfig: SLIDER_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/SliderWidget/slider\")),\n  },\n  RANGE_SLIDER_WIDGET: {\n    config: RANGE_SLIDER_WIDGET_CONFIG,\n    panelConfig: RANGE_SLIDER_PANEL_CONFIG,\n    eventHandlerConfig: RANGE_SLIDER_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/RangeSliderWidget/rangeSlider\")),\n  },\n  RECORDING_WIDGET: {\n    config: RECORDING_WIDGET_CONFIG,\n    panelConfig: RECORDING_PANEL_CONFIG,\n    eventHandlerConfig: RECORDING_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/RecordingWidget/recording\")),\n  },\n  JSON_EDITOR_WIDGET: {\n    config: JSON_EDITOR_WIDGET_CONFIG,\n    panelConfig: JSON_EDITOR_PANEL_CONFIG,\n    eventHandlerConfig: JSON_EDITOR_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/JsonEditorWidget/jsonEditor\")),\n  },\n  RICH_TEXT_WIDGET: {\n    widget: lazy(() => import(\"@/widgetLibrary/RichTextWidget/richText\")),\n    config: RICH_TEXT_WIDGET_CONFIG,\n    panelConfig: RICH_TEXT_PANEL_CONFIG,\n    eventHandlerConfig: RICH_TEXT_EVENT_HANDLER_CONFIG,\n  },\n  JSON_SCHEMA_FORM_WIDGET: {\n    widget: lazy(\n      () => import(\"@/widgetLibrary/JsonSchemaFormWidget/jsonSchemaForm\"),\n    ),\n    config: JSON_SCHEMA_FORM_WIDGET_CONFIG,\n    panelConfig: JSON_SCHEMA_FORM_PANEL_CONFIG,\n    eventHandlerConfig: JSON_SCHEMA_FORM_EVENT_HANDLER_CONFIG,\n  },\n  SIGNATURE_WIDGET: {\n    widget: lazy(() => import(\"@/widgetLibrary/SignatureWidget/signature\")),\n    config: SIGNATURE_WIDGET_CONFIG,\n    panelConfig: SIGNATURE_PANEL_CONFIG,\n    eventHandlerConfig: SIGNATURE_EVENT_HANDLER_CONFIG,\n  },\n  // select inputs\n  SWITCH_WIDGET: {\n    config: SWITCH_WIDGET_CONFIG,\n    panelConfig: SWITCH_PANEL_CONFIG,\n    eventHandlerConfig: SWITCH_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/SwitchWidget/switch\")),\n  },\n  SWITCH_GROUP_WIDGET: {\n    config: SWITCH_GROUP_WIDGET_CONFIG,\n    panelConfig: SWITCH_GROUP_PANEL_CONFIG,\n    eventHandlerConfig: SWITCH_GROUP_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/SwitchGroupWidget/switchGroup\")),\n  },\n  SELECT_WIDGET: {\n    config: SELECT_WIDGET_CONFIG,\n    panelConfig: SELECT_PANEL_CONFIG,\n    eventHandlerConfig: SELECT_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/SelectWidget/select\")),\n  },\n  MULTISELECT_WIDGET: {\n    config: MULTISELECT_WIDGET_CONFIG,\n    panelConfig: MULTISELECT_PANEL_CONFIG,\n    eventHandlerConfig: MULTISELECT_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/MultiselectWidget/multiselect\")),\n  },\n  CHECKBOX_GROUP_WIDGET: {\n    config: CHECKBOX_GROUP_WIDGET_CONFIG,\n    panelConfig: CHECKBOX_GROUP_PANEL_CONFIG,\n    eventHandlerConfig: CHECK_BOX_GROUP_EVENT_HANDLER_CONFIG,\n    widget: lazy(\n      () => import(\"@/widgetLibrary/CheckboxGroupWidget/checkboxGroup\"),\n    ),\n  },\n  CASCADER_WIDGET: {\n    config: CASCADER_WIDGET_CONFIG,\n    panelConfig: CASCADER_PANEL_CONFIG,\n    eventHandlerConfig: CASCADER_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/CascaderWidget/cascader\")),\n  },\n  RADIO_GROUP_WIDGET: {\n    config: RADIO_GROUP_WIDGET_CONFIG,\n    panelConfig: RADIO_GROUP_PANEL_CONFIG,\n    eventHandlerConfig: RADIO_GROUP_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/RadioGroupWidget/radioGroup\")),\n  },\n  RADIO_BUTTON_WIDGET: {\n    config: RADIO_BUTTON_WIDGET_CONFIG,\n    panelConfig: RADIO_BUTTON_PANEL_CONFIG,\n    eventHandlerConfig: RADIO_BUTTON_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/RadioButtonWidget/radioButton\")),\n  },\n  // calendar inputs\n  EVENT_CALENDAR_WIDGET: {\n    config: EVENT_CALENDAR_WIDGET_CONFIG,\n    panelConfig: EVENT_CALENDAR_PANEL_CONFIG,\n    eventHandlerConfig: EVENT_CALENDAR_EVENT_HANDLER_CONFIG,\n    widget: lazy(\n      () => import(\"@/widgetLibrary/EventCalendarWidget/eventCalendar\"),\n    ),\n  },\n  DATE_WIDGET: {\n    config: DATE_WIDGET_CONFIG,\n    panelConfig: DATE_PANEL_CONFIG,\n    eventHandlerConfig: DATE_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/DateWidget/date\")),\n  },\n  DATE_RANGE_WIDGET: {\n    config: DATE_RANGE_WIDGET_CONFIG,\n    panelConfig: DATE_RANGE_PANEL_CONFIG,\n    eventHandlerConfig: DATE_RANGE_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/DateRangeWidget/dateRange\")),\n  },\n  DATE_TIME_WIDGET: {\n    config: DATE_TIME_WIDGET_CONFIG,\n    panelConfig: DATE_TIME_PANEL_CONFIG,\n    eventHandlerConfig: DATE_TIME_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/DateTimeWidget/dateTime\")),\n  },\n  // data\n  DATA_GRID_WIDGET: {\n    config: DATA_GRID_WIDGET_CONFIG,\n    panelConfig: DATA_GRID_PANEL_CONFIG,\n    eventHandlerConfig: DATA_GRID_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/DataGridWidget/dataGrid\")),\n  },\n  CHART_WIDGET: {\n    config: CHART_WIDGET_V2_CONFIG,\n    panelConfig: CHART_PANEL_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/ChartWidget/chart\")),\n  },\n  CHART: {\n    config: CHART_WIDGET_CONFIG,\n    panelConfig: CHART_PANEL_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/ChartWidget/chart\")),\n  },\n  TABLE_WIDGET: {\n    config: TABLE_WIDGET_CONFIG,\n    panelConfig: TABLE_PANEL_CONFIG,\n    eventHandlerConfig: TABLE_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/TableWidget/table\")),\n  },\n  // container\n  CONTAINER_WIDGET: {\n    config: CONTAINER_WIDGET_CONFIG,\n    panelConfig: CONTAINER_PANEL_CONFIG,\n    eventHandlerConfig: CONTAINER_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/ContainerWidget/container\")),\n  },\n  FORM_WIDGET: {\n    config: FORM_WIDGET_CONFIG,\n    panelConfig: FORM_PANEL_CONFIG,\n    eventHandlerConfig: FORM_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/FormWidget/form\")),\n  },\n  MODAL_WIDGET: {\n    config: MODAL_WIDGET_CONFIG,\n    panelConfig: MODAL_PANEL_CONFIG,\n    eventHandlerConfig: MODAL_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/ModalWidget/modal\")),\n  },\n  LIST_WIDGET: {\n    config: LIST_WIDGET_CONFIG,\n    panelConfig: LIST_PANEL_CONFIG,\n    eventHandlerConfig: LIST_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/ListWidget/list\")),\n  },\n  GRID_LIST_WIDGET: {\n    config: GRID_LIST_WIDGET_CONFIG,\n    panelConfig: GRID_LIST_PANEL_CONFIG,\n    eventHandlerConfig: GRID_LIST_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/GridListWidget/gridList\")),\n  },\n  // navigation\n  MENU_WIDGET: {\n    config: MENU_WIDGET_CONFIG,\n    panelConfig: MENU_PANEL_CONFIG,\n    eventHandlerConfig: MENU_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/MenuWidget/menu\")),\n  },\n  TABS_WIDGET: {\n    config: TABS_WIDGET_CONFIG,\n    panelConfig: TABS_PANEL_CONFIG,\n    eventHandlerConfig: TABS_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/TabsWidget/tabs\")),\n  },\n  STEPS_WIDGET: {\n    config: STEPS_WIDGET_CONFIG,\n    panelConfig: STEPS_PANEL_CONFIG,\n    eventHandlerConfig: STEPS_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/StepsWidget/steps\")),\n  },\n  // presentation\n  TEXT_WIDGET: {\n    config: TEXT_WIDGET_CONFIG,\n    panelConfig: TEXT_PANEL_CONFIG,\n    eventHandlerConfig: TEXT_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/TextWidget/text\")),\n  },\n  IMAGE_WIDGET: {\n    config: IMAGE_WIDGET_CONFIG,\n    panelConfig: IMAGE_PANEL_CONFIG,\n    eventHandlerConfig: IMAGE_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/ImageWidget/image\")),\n  },\n  BUTTON_WIDGET: {\n    config: BUTTON_WIDGET_CONFIG,\n    panelConfig: BUTTON_PANEL_CONFIG,\n    eventHandlerConfig: BUTTON_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/ButtonWidget/button\")),\n  },\n  QR_CODE_WIDGET: {\n    config: QR_CODE_WIDGET_CONFIG,\n    panelConfig: QR_CODE_PANEL_CONFIG,\n    eventHandlerConfig: QR_CODE_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/QRCodeWidget/qrCode\")),\n  },\n  CODE_SCANNER_WIDGET: {\n    config: CODE_SCANNER_WIDGET_CONFIG,\n    panelConfig: CODE_SCANNER_PANEL_CONFIG,\n    eventHandlerConfig: CODE_SCANNER_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/CodeScannerWidget/codeScanner\")),\n  },\n  TAGS_WIDGET: {\n    config: TAGS_WIDGET_CONFIG,\n    panelConfig: TAGS_PANEL_CONFIG,\n    eventHandlerConfig: TAGS_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/TagsWidget/tags\")),\n  },\n  CHAT_WIDGET: {\n    widget: lazy(() => import(\"@/widgetLibrary/ChatWidget/chat\")),\n    config: CHAT_WIDGET_CONFIG,\n    panelConfig: CHAT_PANEL_CONFIG,\n    eventHandlerConfig: CHAT_EVENT_HANDLER_CONFIG,\n  },\n  ICON_WIDGET: {\n    config: ICON_WIDGET_CONFIG,\n    panelConfig: ICON_PANEL_CONFIG,\n    eventHandlerConfig: ICON_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/IconWidget/icon\")),\n  },\n  AVATAR_WIDGET: {\n    config: AVATAR_WIDGET_CONFIG,\n    panelConfig: AVATAR_PANEL_CONFIG,\n    eventHandlerConfig: AVATAR_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/AvatarWidget/avatar\")),\n  },\n  STATISTIC_WIDGET: {\n    config: STATISTICS_WIDGET_CONFIG,\n    panelConfig: STATISTICS_PANEL_CONFIG,\n    eventHandlerConfig: STATISTICS_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/StatisticsWidget/statistics\")),\n  },\n  TIME_PICKER_WIDGET: {\n    config: TIME_PICKER_WIDGET_CONFIG,\n    panelConfig: TIME_PICKER_PANEL_CONFIG,\n    eventHandlerConfig: TIME_PICKER_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/TimePickerWidget/timePicker\")),\n  },\n  TIME_RANGE_WIDGET: {\n    config: TIME_RANGE_WIDGET_CONFIG,\n    panelConfig: TIME_RANGE_PANEL_CONFIG,\n    eventHandlerConfig: TIME_RANGE_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/TimeRangeWidget/timeRange\")),\n  },\n  RATE_WIDGET: {\n    config: RATE_WIDGET_CONFIG,\n    panelConfig: RATE_PANEL_CONFIG,\n    eventHandlerConfig: RATE_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/RateWidget/rate\")),\n  },\n  BAR_PROGRESS_WIDGET: {\n    config: BAR_PROGRESS_WIDGET_CONFIG,\n    panelConfig: BAR_PROGRESS_PANEL_CONFIG,\n    eventHandlerConfig: BAR_PROGRESS_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/BarProgressWidget/barProgress\")),\n  },\n  CIRCLE_PROGRESS_WIDGET: {\n    config: CIRCLE_PROGRESS_WIDGET_CONFIG,\n    panelConfig: CIRCLE_PROGRESS_PANEL_CONFIG,\n    eventHandlerConfig: CIRCLE_PROGRESS_EVENT_HANDLER_CONFIG,\n    widget: lazy(\n      () => import(\"@/widgetLibrary/CircleProgressWidget/circleProgress\"),\n    ),\n  },\n  TIMELINE_WIDGET: {\n    config: TIMELINE_WIDGET_CONFIG,\n    panelConfig: TIMELINE_PANEL_CONFIG,\n    eventHandlerConfig: TIMELINE_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/TimelineWidget/timeline\")),\n  },\n  DIVIDER_WIDGET: {\n    config: DIVIDER_WIDGET_CONFIG,\n    panelConfig: DIVIDER_PANEL_CONFIG,\n    eventHandlerConfig: DIVIDER_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/DividerWidget/divider\")),\n  },\n  PDF_WIDGET: {\n    config: PDF_WIDGET_CONFIG,\n    panelConfig: PDF_PANEL_CONFIG,\n    eventHandlerConfig: PDF_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/PdfWidget/pdf\")),\n  },\n  VIDEO_WIDGET: {\n    config: VIDEO_WIDGET_CONFIG,\n    panelConfig: VIDEO_PANEL_CONFIG,\n    eventHandlerConfig: VIDEO_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/VideoWidget/video\")),\n  },\n  AUDIO_WIDGET: {\n    config: AUDIO_WIDGET_CONFIG,\n    panelConfig: AUDIO_PANEL_CONFIG,\n    eventHandlerConfig: AUDIO_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/AudioWidget/audio\")),\n  },\n  CAROUSEL_WIDGET: {\n    config: CAROUSEL_WIDGET_CONFIG,\n    panelConfig: CAROUSEL_PANEL_CONFIG,\n    eventHandlerConfig: CAROUSEL_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/CarouselWidget/carousel\")),\n  },\n  IFRAME_WIDGET: {\n    config: IFRAME_WIDGET_CONFIG,\n    panelConfig: IFRAME_PANEL_CONFIG,\n    eventHandlerConfig: IFRAME_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/IFrameWidget/iframe\")),\n  },\n}\n\nif (isCloudVersion) {\n  WidgetConfigMap[\"DRIVE_PICKER_WIDGET\"] = {\n    config: DRIVE_PICKER_WIDGET_CONFIG,\n    panelConfig: DRIVE_PICKER_PANEL_CONFIG,\n    eventHandlerConfig: DRIVE_PICKER_EVENT_HANDLER_CONFIG,\n    widget: lazy(() => import(\"@/widgetLibrary/DrivePickerWidget/drivePicker\")),\n  }\n  if (import.meta.env.ILLA_GOOGLE_MAP_KEY) {\n    WidgetConfigMap[\"MAP_WIDGET\"] = {\n      config: MAP_WIDGET_CONFIG,\n      panelConfig: MAP_PANEL_CONFIG,\n      eventHandlerConfig: MAP_EVENT_HANDLER_CONFIG,\n      widget: lazy(() => import(\"@/widgetLibrary/MapBoxWidget/map\")),\n    }\n  }\n}\n\nexport type WidgetType = keyof typeof WidgetConfigMap\n\nexport const WidgetTypeList = Object.keys(WidgetConfigMap)\n\nexport const widgetBuilder = (type: WidgetType) => {\n  return WidgetConfigMap[type]\n}\n"
  },
  {
    "path": "apps/builder/tsconfig.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/tsconfig\",\n  \"extends\": \"tsconfig/react.json\",\n  \"compilerOptions\": {\n    \"baseUrl\": \"./src\",\n    \"paths\": {\n      \"@/*\": [\"./*\"],\n      \"@assets/*\": [\"./src/assets/*\"]\n    },\n    \"types\": [\n      \"vite/client\",\n      \"vite-plugin-svgr/client\",\n      \"mdx\",\n      \"node\",\n      \"@types/gtag.js\"\n    ]\n  },\n  \"include\": [\n    \"./src/**/*.tsx\",\n    \"./src/**/*.ts\",\n    \"./src/assets/animationForLottie/*.json\"\n  ],\n  \"references\": [\n    {\n      \"path\": \"./tsconfig.node.json\"\n    }\n  ]\n}\n"
  },
  {
    "path": "apps/builder/tsconfig.node.json",
    "content": "{\n  \"compilerOptions\": {\n    \"composite\": true,\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Node\",\n    \"allowSyntheticDefaultImports\": true,\n    \"resolveJsonModule\": true\n  },\n  \"include\": [\"vite.config.mts\", \"package.json\",\"./public/appInfo.json\"]\n}\n"
  },
  {
    "path": "apps/builder/vite.config.mts",
    "content": "import mdx from \"@mdx-js/rollup\"\nimport { sentryVitePlugin } from \"@sentry/vite-plugin\"\nimport basicSsl from \"@vitejs/plugin-basic-ssl\"\nimport react from \"@vitejs/plugin-react-swc\"\nimport { writeFileSync } from \"fs\"\nimport { resolve } from \"path\"\nimport copy from \"rollup-plugin-copy\"\nimport { visualizer } from \"rollup-plugin-visualizer\"\nimport { PluginOption, defineConfig, loadEnv } from \"vite\"\nimport checker from \"vite-plugin-checker\"\nimport svgr from \"vite-plugin-svgr\"\nimport pkg from \"./package.json\"\n\nconst I18N_SOURCE_PATH = resolve(\n  __dirname,\n  \"../../packages/illa-public-component\",\n  \"locales/*.json\",\n)\nconst I18N_TARGET_PATH = resolve(__dirname, \"src/i18n/locale\")\n\nconst getUsedEnv = (env: Record<string, string>) => {\n  const usedEnv: Record<string, string> = {}\n  Object.keys(env).forEach((key) => {\n    if (key.startsWith(\"ILLA_\")) {\n      let value = env[key]\n      usedEnv[`import.meta.env.${key}`] = JSON.stringify(value)\n      usedEnv[`process.env.${key}`] = JSON.stringify(value)\n    }\n  })\n  usedEnv[`import.meta.env.ILLA_APP_VERSION`] = JSON.stringify(pkg.version)\n  usedEnv[`process.env.ILLA_APP_VERSION`] = JSON.stringify(pkg.version)\n  return usedEnv\n}\n\n// https://vitejs.dev/config/\nexport default defineConfig(({ command, mode }) => {\n  const env = loadEnv(mode, process.cwd(), \"\")\n\n  const useHttps = env.ILLA_USE_HTTPS === \"true\"\n  const BASIC_PLUGIN: PluginOption[] = [\n    copy({\n      targets: [\n        {\n          src: [I18N_SOURCE_PATH, \"!**/package.json\"],\n          dest: I18N_TARGET_PATH,\n        },\n      ],\n      hook: \"buildStart\",\n    }) as unknown as PluginOption,\n    mdx() as unknown as PluginOption,\n    react({\n      jsxImportSource: \"@emotion/react\",\n    }),\n    svgr(),\n    checker({\n      typescript: true,\n      eslint: {\n        lintCommand: 'eslint \"./src/**/**.{ts,tsx}\" --config \".eslintrc.js\"',\n        dev: {\n          logLevel: [\"error\", \"warning\"],\n        },\n      },\n    }),\n    visualizer({\n      template: \"network\",\n    }) as unknown as PluginOption,\n  ]\n\n  const plugin = BASIC_PLUGIN\n  const version = pkg.version\n\n  if (command === \"serve\" && useHttps) {\n    plugin.push(basicSsl())\n  } else {\n    if (\n      env.ILLA_INSTANCE_ID === \"CLOUD\" &&\n      env.ILLA_SENTRY_AUTH_TOKEN &&\n      env.ILLA_APP_ENV === \"production\"\n    ) {\n      plugin.push(\n        sentryVitePlugin({\n          authToken: env.ILLA_SENTRY_AUTH_TOKEN,\n          org: \"illa-cloud\",\n          project: \"illa-builder\",\n          release: {\n            name: `illa-builder@${version}`,\n            dist: env.ILLA_APP_ENV,\n          },\n        }),\n      )\n    }\n  }\n  writeFileSync(\"./public/appInfo.json\", `{\"version\":${version}}`)\n\n  return {\n    base: env.ILLA_BASE_PATH ?? \"/\",\n    plugins: plugin,\n    esbuild: {\n      logOverride: { \"this-is-undefined-in-esm\": \"silent\" },\n    },\n    resolve: {\n      alias: {\n        \"@\": resolve(__dirname, \"src\"),\n        \"@assets\": resolve(__dirname, \"src/assets\"),\n      },\n    },\n    envPrefix: [\"ILLA_\"],\n    define: getUsedEnv(env),\n    build: {\n      sourcemap: true,\n      reportCompressedSize: false,\n      rollupOptions: {\n        output: {\n          manualChunks: {\n            react: [\"react\", \"react-dom\", \"react-router-dom\"],\n            \"@emotion\": [\"@emotion/react\"],\n            \"@illa-design\": [\"@illa-design/react\"],\n            \"react-icons-vendor\": [\n              \"react-icons\",\n              \"react-icons/bs\",\n              \"react-icons/fc\",\n              \"react-icons/sl\",\n              \"react-icons/tb\",\n            ],\n            \"codeMirror-vendor\": [\n              \"@codemirror/autocomplete\",\n              \"@codemirror/commands\",\n              \"@codemirror/lang-html\",\n              \"@codemirror/lang-javascript\",\n              \"@codemirror/lang-sql\",\n              \"@codemirror/lang-xml\",\n              \"@codemirror/language\",\n              \"@codemirror/lint\",\n              \"@codemirror/search\",\n              \"@codemirror/state\",\n              \"@codemirror/view\",\n              \"@uiw/codemirror-theme-github\",\n            ],\n            \"lodash-lib\": [\"lodash-es\"],\n          },\n        },\n      },\n    },\n    server: {\n      port: 3000,\n    },\n    preview: {\n      port: 4173,\n    },\n  }\n})\n"
  },
  {
    "path": "apps/cloud/.eslintrc.cjs",
    "content": "module.exports = {\n  root: true,\n  settings: {\n    \"import/resolver\": {\n      typescript: {\n        project: \"./tsconfig.json\",\n      }\n    },\n  },\n  extends: [\"illa\"],\n}\n"
  },
  {
    "path": "apps/cloud/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\ndist\ndist-ssr\ndev-dist\n*.local\n\n# Editor directories and files\n.vscode/*\n!.vscode/extensions.json\n.idea\n.DS_Store\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n/test-results/\n/playwright-report/\n/playwright/.cache/\n/playwright/.auth\nstats.html\n/e2e/drive/download-files\npublic/locales"
  },
  {
    "path": "apps/cloud/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <title>ILLA Cloud</title>\n    <meta charset=\"UTF-8\" />\n    <link rel=\"icon\" href=\"/favicon.ico\" sizes=\"any\" />\n    <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\" />\n    <link rel=\"apple-touch-icon\" href=\"/apple-touch-icon-180x180.png\" />\n    <meta\n      name=\"viewport\"\n      content=\"width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\"\n    />\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <script>\n      if (!CSS.supports(\"height\", \"100dvh\")) {\n        const dvh = window.innerHeight * 0.01\n        window.document?.documentElement?.style.setProperty(\"--dvh\", `${dvh}px`)\n      }\n    </script>\n    <script type=\"module\" src=\"/src/main.tsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "apps/cloud/package.json",
    "content": "{\n  \"name\": \"illa-cloud-fe\",\n  \"private\": true,\n  \"version\": \"3.0.10\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite --strictPort --force\",\n    \"build-self\": \"tsc && vite build\",\n    \"preview\": \"vite preview\",\n    \"lint\": \"eslint \\\"./src/**/**.{ts,tsx}\\\" --config \\\".eslintrc.cjs\\\"\",\n    \"lint:fix\": \"eslint --fix \\\"./src/**/**.{ts,tsx}\\\" --config \\\".eslintrc.cjs\\\"\",\n    \"format\": \"prettier --write \\\"src/**/*.{ts,tsx}\\\"\"\n  },\n  \"dependencies\": {\n    \"@emotion/cache\": \"^11.10.5\",\n    \"@emotion/core\": \"^11.0.0\",\n    \"@illa-design/react\": \"workspace:*\",\n    \"@illa-design/table\": \"workspace:*\",\n    \"@illa-public/avatar\": \"workspace:*\",\n    \"@illa-public/cloud-dashboard-layout\": \"workspace:*\",\n    \"@illa-public/cropper\": \"workspace:*\",\n    \"@illa-public/dashboard\": \"workspace:*\",\n    \"@illa-public/icon\": \"workspace:*\",\n    \"@illa-public/illa-markdown\": \"workspace:*\",\n    \"@illa-public/illa-net\": \"workspace:*\",\n    \"@illa-public/illa-storage\": \"workspace:*\",\n    \"@illa-public/invite-modal\": \"workspace:*\",\n    \"@illa-public/layout-auto-change\": \"workspace:*\",\n    \"@illa-public/member-page\": \"workspace:*\",\n    \"@illa-public/public-configs\": \"workspace:*\",\n    \"@illa-public/public-types\": \"workspace:*\",\n    \"@illa-public/resource-generator\": \"workspace:*\",\n    \"@illa-public/sso-module\": \"workspace:*\",\n    \"@illa-public/styleis-plugin\": \"workspace:*\",\n    \"@illa-public/user-data\": \"workspace:*\",\n    \"@illa-public/user-role-utils\": \"workspace:*\",\n    \"@illa-public/utils\": \"workspace:*\",\n    \"@reduxjs/toolkit\": \"^2.0.1\",\n    \"axios\": \"^1.6.2\",\n    \"dayjs\": \"^1.11.10\",\n    \"fuse.js\": \"^6.6.2\",\n    \"i18next\": \"^23.7.6\",\n    \"i18next-browser-languagedetector\": \"^7.0.1\",\n    \"i18next-http-backend\": \"^2.2.2\",\n    \"lodash-es\": \"^4.17.21\",\n    \"react-hook-form\": \"^7.40.0\",\n    \"react-i18next\": \"^13.5.0\",\n    \"react-redux\": \"^9.0.4\",\n    \"react-router-dom\": \"^6.14.0\",\n    \"swr\": \"^2.2.4\",\n    \"uuid\": \"^9.0.0\"\n  },\n  \"devDependencies\": {\n    \"@types/gtag.js\": \"^0.0.18\",\n    \"@types/lodash-es\": \"^4.17.12\",\n    \"@types/uuid\": \"^9.0.0\",\n    \"eslint-config-illa\": \"workspace:*\",\n    \"rollup-plugin-copy\": \"^3.5.0\",\n    \"rollup-plugin-visualizer\": \"^5.12.0\",\n    \"tsconfig\": \"workspace:*\"\n  }\n}\n"
  },
  {
    "path": "apps/cloud/src/App.tsx",
    "content": "import createCache from \"@emotion/cache\"\nimport { CacheProvider, Global } from \"@emotion/react\"\nimport { px2Rem } from \"@illa-public/styleis-plugin\"\nimport { getCurrentTranslateLanguage } from \"@illa-public/user-data\"\nimport { FC, useEffect } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { RouterProvider } from \"react-router-dom\"\nimport { MessageGroup, ModalGroup } from \"@illa-design/react\"\nimport { getLocalLanguage } from \"@/i18n\"\nimport { ILLARoute } from \"@/router\"\nimport { globalStyles, messageStyle } from \"./style\"\n\nconst App: FC = () => {\n  const currentLanguage =\n    useSelector(getCurrentTranslateLanguage) || getLocalLanguage()\n  const { i18n } = useTranslation()\n\n  useEffect(() => {\n    if (currentLanguage && currentLanguage !== i18n.language) {\n      i18n.changeLanguage(currentLanguage)\n    }\n  }, [currentLanguage, i18n])\n\n  let cache = createCache({\n    key: \"css\",\n    stylisPlugins: [\n      px2Rem({\n        unit: \"rem\",\n        remSize: 100,\n      }),\n    ],\n  })\n\n  return (\n    <CacheProvider value={cache}>\n      <Global styles={globalStyles} />\n      <MessageGroup _css={messageStyle} />\n      <ModalGroup />\n      <RouterProvider router={ILLARoute} />\n    </CacheProvider>\n  )\n}\n\nexport default App\n"
  },
  {
    "path": "apps/cloud/src/api/auth/index.ts",
    "content": "import { authCloudRequest } from \"@illa-public/illa-net\"\nimport { v4 } from \"uuid\"\nimport { upload } from \"@/api/custom\"\n\nexport interface UploadResponse {\n  uploadAddress: string\n}\n\nexport const getUserAvatarUploadAddress = async (type: string) => {\n  const fileName = v4()\n  try {\n    const response = await authCloudRequest<UploadResponse>({\n      url: `/users/avatar/uploadAddress/fileName/${fileName}.${type}`,\n      method: \"GET\",\n    })\n    return response.data\n  } catch (e) {\n    throw e\n  }\n}\n\nexport const uploadUserAvatar = (file: Blob) => {\n  return new Promise<string>(async (resolve, reject) => {\n    try {\n      const type = file.type.split(\"/\")[1]\n      const uploadUrl = await getUserAvatarUploadAddress(type)\n      if (uploadUrl) {\n        const imgUrl = await upload(uploadUrl.uploadAddress, file)\n        resolve(imgUrl)\n      }\n    } catch (e) {\n      reject(e)\n    }\n  })\n}\n\nexport const updateUserAvatar = async (avatar: string) => {\n  try {\n    return await authCloudRequest({\n      url: \"/users/avatar\",\n      method: \"PATCH\",\n      data: {\n        avatar,\n      },\n    })\n  } catch (e) {\n    throw e\n  }\n}\n"
  },
  {
    "path": "apps/cloud/src/api/custom/index.ts",
    "content": "import Axios from \"axios\"\n\nexport const upload = (url: string, file: Blob) => {\n  const resUrl = url.split(\"?\")[0]\n\n  return new Promise<string>(async (resolve, reject) => {\n    try {\n      await Axios.put(url, file, {\n        headers: {\n          \"Content-Type\": \"multipart/form-data\",\n          \"x-amz-acl\": \"public-read\",\n        },\n      })\n      resolve(resUrl)\n    } catch (e) {\n      reject(e)\n    }\n  })\n}\n"
  },
  {
    "path": "apps/cloud/src/api/http/base.ts",
    "content": "import {\n  authInterceptor,\n  errorHandlerInterceptor,\n  needAuthAxios,\n} from \"@illa-public/illa-net\"\n\nneedAuthAxios.interceptors.request.use(authInterceptor)\nneedAuthAxios.interceptors.response.use(undefined, errorHandlerInterceptor)\n"
  },
  {
    "path": "apps/cloud/src/components/FullPageLoading/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { fullPageLoadingWrapperStyle } from \"./style\"\n\nexport const FullPageLoading: FC = () => {\n  return (\n    <div css={fullPageLoadingWrapperStyle}>\n      <Loading colorScheme=\"techPurple\" />\n    </div>\n  )\n}\n\nFullPageLoading.displayName = \"FullPageLoading\"\n"
  },
  {
    "path": "apps/cloud/src/components/FullPageLoading/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const fullPageLoadingWrapperStyle = css`\n  width: 100vw;\n  height: 100vh;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/cloud/src/components/FullSectionLoading/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Loading } from \"@illa-design/react\"\nimport { fullSectionLoadingWrapperStyle } from \"./style\"\n\nexport const FullSectionLoading: FC = () => {\n  return (\n    <div css={fullSectionLoadingWrapperStyle}>\n      <Loading colorScheme=\"techPurple\" />\n    </div>\n  )\n}\n\nFullSectionLoading.displayName = \"FullSectionLoading\"\n"
  },
  {
    "path": "apps/cloud/src/components/FullSectionLoading/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const fullSectionLoadingWrapperStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/cloud/src/components/Menu/index.tsx",
    "content": "import { FC, useMemo } from \"react\"\nimport { useLocation } from \"react-router-dom\"\nimport { MenuProps } from \"@/components/Menu/interface\"\nimport {\n  menuWrapperStyle,\n  mobileMenuWrapperStyle,\n  subMenuWrapperStyle,\n} from \"@/components/Menu/style\"\nimport { MenuItem } from \"./menuItem\"\n\nexport const Menu: FC<MenuProps> = (props) => {\n  const {\n    containerClassName,\n    itemClassName,\n    itemList,\n    isMobile,\n    onClickMenuItem,\n  } = props\n  const location = useLocation()\n\n  const wrapperStyle = useMemo(() => {\n    if (isMobile) {\n      return mobileMenuWrapperStyle\n    }\n    return menuWrapperStyle\n  }, [isMobile])\n\n  return (\n    <div css={wrapperStyle} className={containerClassName}>\n      {itemList?.map((item, index) => {\n        const { path, hash = \"\", hidden, subMenu, ...rest } = item\n        const selected = location.pathname === path && location.hash === hash\n\n        if (hidden) {\n          return null\n        }\n\n        return (\n          <div key={path + hash}>\n            <MenuItem\n              {...rest}\n              isMobile={isMobile}\n              selected={selected}\n              index={index}\n              path={path}\n              hash={hash}\n              className={itemClassName}\n              onClickMenuItem={onClickMenuItem}\n            />\n            {subMenu?.map((item, index) => {\n              const { path, hash = \"\", hidden, ...subProps } = item\n              const selected =\n                location.pathname === path && location.hash === hash\n\n              if (hidden) {\n                return null\n              }\n              return (\n                <MenuItem\n                  css={subMenuWrapperStyle}\n                  key={path + hash}\n                  {...subProps}\n                  isMobile={isMobile}\n                  selected={selected}\n                  index={index}\n                  path={path}\n                  hash={hash}\n                  className={itemClassName}\n                  onClickMenuItem={onClickMenuItem}\n                />\n              )\n            })}\n          </div>\n        )\n      })}\n    </div>\n  )\n}\n\nMenu.displayName = \"Menu\"\n"
  },
  {
    "path": "apps/cloud/src/components/Menu/interface.ts",
    "content": "import { HTMLAttributes, ReactNode } from \"react\"\n\nexport interface MenuItems {\n  subMenu?: MenuItems[]\n  path?: string\n  hash?: string\n  label: ReactNode\n  icon?: ReactNode\n  hidden?: boolean\n  onClick?: () => void\n}\n\nexport interface MenuProps extends HTMLAttributes<HTMLDivElement> {\n  itemList: MenuItems[]\n  isMobile?: boolean\n  containerClassName?: string\n  itemClassName?: string\n  onClickMenuItem?: (index: number) => void\n}\n"
  },
  {
    "path": "apps/cloud/src/components/Menu/menuItem.tsx",
    "content": "import { FC, HTMLAttributes, ReactNode, useMemo } from \"react\"\nimport { useLocation, useNavigate } from \"react-router-dom\"\nimport {\n  applyLinkStyle,\n  applyMobileLinkStyle,\n  iconStyle,\n  mobileIconStyle,\n} from \"@/components/Menu/style\"\n\ninterface MenuItem extends HTMLAttributes<HTMLDivElement> {\n  selected: boolean\n  index: number\n  isMobile?: boolean\n  path?: string\n  hash?: string\n  label: ReactNode\n  icon?: ReactNode\n  onClickMenuItem?: (index: number) => void\n}\n\nexport const MenuItem: FC<MenuItem> = (props) => {\n  const {\n    isMobile,\n    index,\n    icon,\n    label,\n    path,\n    hash = \"\",\n    onClickMenuItem,\n    onClick,\n    ...rest\n  } = props\n  const navigate = useNavigate()\n  const location = useLocation()\n\n  const selected = location.pathname === path && location.hash === hash\n\n  const [applyCurrentLinkStyle, currentIconStyle] = useMemo(() => {\n    if (isMobile) {\n      return [applyMobileLinkStyle, mobileIconStyle]\n    }\n    return [applyLinkStyle, iconStyle]\n  }, [isMobile])\n\n  const scrollIntoView = (hash?: string) => {\n    if (!hash) return\n    const targetElement = document.querySelector(hash)\n    if (targetElement) {\n      targetElement.scrollIntoView({ behavior: \"smooth\" })\n    }\n  }\n\n  return (\n    <div\n      css={applyCurrentLinkStyle(selected)}\n      key={index}\n      {...rest}\n      onClick={(e) => {\n        onClick && onClick(e)\n        onClickMenuItem && onClickMenuItem(index)\n        if (!selected && path) {\n          navigate({\n            pathname: path,\n            hash,\n          })\n          scrollIntoView(hash)\n        }\n      }}\n    >\n      {icon ? <div css={currentIconStyle}>{icon}</div> : null}\n      {label}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/components/Menu/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\nimport { columnCenter } from \"@/style\"\n\nexport const menuWrapperStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n`\n\nexport const applyLinkStyle = (selected: boolean): SerializedStyles => {\n  const selectedStyle = selected\n    ? css`\n        background: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n        font-weight: 600;\n      `\n    : null\n\n  return css`\n    display: flex;\n    align-items: center;\n    padding: 9px 24px;\n    font-weight: 500;\n    font-size: 14px;\n    line-height: 22px;\n    color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n    cursor: pointer;\n    ${selectedStyle};\n  `\n}\n\nexport const iconStyle = css`\n  ${columnCenter};\n  width: 24px;\n  height: 24px;\n  margin-right: 12px;\n  color: inherit;\n`\n\nexport const subMenuWrapperStyle = css`\n  padding: 10px 40px;\n\n  ${applyMobileStyle(css`\n    padding: 20rem 70rem;\n  `)}\n`\n\n// Mobile\n\nexport const mobileMenuWrapperStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 8rem;\n`\n\nexport const applyMobileLinkStyle = (selected: boolean): SerializedStyles => {\n  const selectedStyle = selected\n    ? css`\n        background: ${globalColor(`--${illaPrefix}-techPurple-08`)};\n        color: ${globalColor(`--${illaPrefix}-techPurple-03`)};\n        font-weight: 500;\n      `\n    : null\n\n  return css`\n    display: flex;\n    align-items: center;\n    padding: 20rem 32rem;\n    font-weight: 400;\n    font-size: 32rem;\n    line-height: 40rem;\n    color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n    cursor: pointer;\n    ${selectedStyle};\n  `\n}\n\nexport const mobileIconStyle = css`\n  ${columnCenter};\n  width: 48rem;\n  height: 48rem;\n  margin-right: 12px;\n  color: inherit;\n  & > svg {\n    width: 48rem;\n    height: 48rem;\n  }\n`\n"
  },
  {
    "path": "apps/cloud/src/env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n\ninterface ImportMetaEnv {\n  readonly ILLA_API_BASE_URL: string\n  readonly ILLA_APP_VERSION: string\n  readonly ILLA_BUILDER_URL: string\n  readonly ILLA_CLOUD_URL: string\n  readonly ILLA_INSTANCE_ID: string\n  readonly ILLA_APP_ENV: string\n}\n\ninterface ImportMeta {\n  readonly env: ImportMetaEnv\n}\n"
  },
  {
    "path": "apps/cloud/src/i18n/i18next.d.ts",
    "content": "import \"i18next\"\n\ndeclare module \"i18next\" {\n  interface CustomTypeOptions {\n    returnNull: false\n  }\n}\n"
  },
  {
    "path": "apps/cloud/src/i18n/index.ts",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport i18n from \"i18next\"\nimport I18nextBrowserLanguageDetector from \"i18next-browser-languagedetector\"\nimport HttpApi, { HttpBackendOptions } from \"i18next-http-backend\"\nimport { initReactI18next } from \"react-i18next\"\n\nexport const defaultLanguage = \"en-US\"\n\nexport const languageKeys = [\n  \"en-US\",\n  \"zh-CN\",\n  \"ja-JP\",\n  \"ko-KR\",\n  \"cs-CZ\",\n  \"da-DK\",\n  \"de-DE\",\n  \"el-GR\",\n  \"es-ES\",\n  \"fi-FI\",\n  \"fr-FR\",\n  \"it-IT\",\n  \"nl-NL\",\n  \"no-NO\",\n  \"pl-PL\",\n  \"pt-PT\",\n  \"ru-RU\",\n  \"ro-RO\",\n  \"sv-SE\",\n  \"uk-UA\",\n]\n\nexport const formatLanguage = (code: string) => {\n  if (code) {\n    if (languageKeys.includes(code)) {\n      return code\n    }\n    const mainLanguage = code.slice(0, 2)\n    for (let i = 0; i < languageKeys.length; i++) {\n      if (languageKeys[i].slice(0, 2) === mainLanguage) {\n        return languageKeys[i]\n      }\n    }\n  }\n  return \"en-US\"\n}\n\nexport function getLocalLanguage(): string {\n  const lang =\n    window.localStorage.getItem(\"i18nextLng\") || window.navigator.language\n  return formatLanguage(lang)\n}\n\ni18n\n  .use(I18nextBrowserLanguageDetector)\n  .use(HttpApi)\n  .use(initReactI18next)\n  .init<HttpBackendOptions>({\n    load: \"currentOnly\",\n    backend: {\n      loadPath:\n        (import.meta.env.PROD && !isCloudVersion ? \"/cloud/\" : \"/\") +\n        \"locales/{{lng}}.json\",\n    },\n    fallbackLng: (code) => {\n      const language = formatLanguage(code)\n      return [language, \"en-US\"]\n    },\n    debug: false,\n    interpolation: {\n      escapeValue: false, // not needed for react as it escapes by default\n    },\n    returnNull: false,\n  })\n\nexport default i18n\n"
  },
  {
    "path": "apps/cloud/src/i18n/react-i18next.d.ts",
    "content": "import \"react-i18next\"\n\ndeclare module \"react-i18next\" {\n  interface CustomTypeOptions {\n    returnNull: false\n  }\n}\n"
  },
  {
    "path": "apps/cloud/src/main.tsx",
    "content": "import React from \"react\"\nimport { createRoot } from \"react-dom/client\"\nimport { Provider } from \"react-redux\"\nimport \"@/api/http/base\"\nimport \"@/i18n\"\nimport { store } from \"@/store\"\nimport \"@/utils/dayjs\"\nimport App from \"./App\"\n\ncreateRoot(document.getElementById(\"root\") as HTMLElement).render(\n  <React.StrictMode>\n    <Provider store={store}>\n      <App />\n    </Provider>\n  </React.StrictMode>,\n)\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/language/hook.ts",
    "content": "import { useTranslation } from \"react-i18next\"\nimport { languageKeys } from \"@/i18n\"\n\nexport const useLangOptions = () => {\n  const { t } = useTranslation()\n\n  return languageKeys.map((key) => ({\n    label: t(`language.${key}`),\n    value: key,\n  }))\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/language/index.tsx",
    "content": "import { LayoutAutoChange } from \"@illa-public/layout-auto-change\"\nimport { getCurrentTranslateLanguage } from \"@illa-public/user-data\"\nimport { FC, useEffect, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { defaultLanguage } from \"@/i18n\"\nimport { fetchUpdateUserLanguage } from \"@/services/user\"\nimport MobileLanguageSetting from \"./mobile\"\nimport PCLanguageSetting from \"./pc\"\n\nconst LanguageSetting: FC = () => {\n  const language = useSelector(getCurrentTranslateLanguage) || defaultLanguage\n  const [currentLanguage, setCurrentLanguage] = useState(language)\n  const [languageLoading, setLanguageLoading] = useState(false)\n\n  useEffect(() => {\n    if (language !== currentLanguage) {\n      setCurrentLanguage(language)\n    }\n    // todo: @echoxyc\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [language])\n\n  const onSaveLanguageChange = async () => {\n    try {\n      setLanguageLoading(true)\n      await fetchUpdateUserLanguage(currentLanguage)\n      window.location.reload()\n    } catch (e) {\n    } finally {\n      setLanguageLoading(false)\n    }\n  }\n  return (\n    <LayoutAutoChange\n      desktopPage={\n        <PCLanguageSetting\n          loading={languageLoading}\n          language={language}\n          currentLanguage={currentLanguage}\n          onChangeLanguage={setCurrentLanguage}\n          onSubmit={onSaveLanguageChange}\n        />\n      }\n      mobilePage={\n        <MobileLanguageSetting\n          loading={languageLoading}\n          language={language}\n          currentLanguage={currentLanguage}\n          onChangeLanguage={setCurrentLanguage}\n          onSubmit={onSaveLanguageChange}\n        />\n      }\n    />\n  )\n}\nexport default LanguageSetting\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/language/mobile/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button, Select } from \"@illa-design/react\"\nimport SettingMobileLayout from \"@/page/setting/layout/mobile\"\nimport { useLangOptions } from \"../hook\"\nimport { LanguageSettingMobileProps } from \"./interface\"\nimport {\n  controllerContainerStyle,\n  mobileContainerStyle,\n  mobileSelectStyle,\n} from \"./style\"\n\nconst MobileLanguageSetting: FC<LanguageSettingMobileProps> = (props) => {\n  const { t } = useTranslation()\n  const { onSubmit, loading, language, currentLanguage, onChangeLanguage } =\n    props\n\n  const buttonDisabled = language === currentLanguage\n  const LANG_OPTIONS = useLangOptions()\n\n  return (\n    <SettingMobileLayout>\n      <div css={mobileContainerStyle}>\n        <section css={controllerContainerStyle}>\n          <label>{t(\"profile.setting.language\")}</label>\n          <Select\n            _css={mobileSelectStyle}\n            value={currentLanguage}\n            size=\"large\"\n            colorScheme=\"techPurple\"\n            options={LANG_OPTIONS}\n            onChange={(value) => {\n              onChangeLanguage(value as string)\n            }}\n          />\n        </section>\n        <Button\n          colorScheme=\"techPurple\"\n          size=\"large\"\n          disabled={buttonDisabled}\n          loading={loading}\n          fullWidth\n          onClick={() => {\n            onSubmit()\n          }}\n        >\n          {t(\"profile.setting.save\")}\n        </Button>\n      </div>\n    </SettingMobileLayout>\n  )\n}\n\nMobileLanguageSetting.displayName = \"LanguageSettingMobile\"\n\nexport default MobileLanguageSetting\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/language/mobile/interface.ts",
    "content": "export interface LanguageSettingMobileProps {\n  loading: boolean\n  language: string\n  currentLanguage: string\n  onChangeLanguage: (language: string) => void\n  onSubmit: () => void\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/language/mobile/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const mobileSelectStyle = css`\n  & input {\n    font-size: 28rem;\n  }\n\n  & > span {\n    font-size: 28rem;\n    height: 96rem;\n    & > div {\n      padding: 0 32rem;\n    }\n    & svg {\n      font-size: 28rem;\n    }\n  }\n`\n\nexport const mobileContainerStyle = css`\n  display: grid;\n  gap: 64rem;\n  padding-bottom: 40px;\n`\n\nexport const submitButtonStyle = css`\n  height: 88rem;\n  border-radius: 16rem;\n\n  & > span {\n    font-size: 32rem;\n  }\n`\n\nexport const controllerContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 32rem;\n`\n\nexport const formContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 64rem;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/language/pc/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button, Select } from \"@illa-design/react\"\nimport { Header } from \"@/page/setting/components/Header\"\nimport { containerStyle, formTitleStyle } from \"@/page/setting/style\"\nimport { useLangOptions } from \"../hook\"\nimport { LanguageSettingProps } from \"./interface\"\nimport { formFieldStyle, innerContainerStyle } from \"./style\"\n\nconst PCLanguageSetting: FC<LanguageSettingProps> = (props) => {\n  const { t } = useTranslation()\n  const { onSubmit, loading, language, currentLanguage, onChangeLanguage } =\n    props\n\n  const buttonDisabled = language === currentLanguage\n  const LANG_OPTIONS = useLangOptions()\n\n  return (\n    <>\n      <Header title={t(\"profile.setting.language\")} />\n      <div css={containerStyle}>\n        <div css={innerContainerStyle}>\n          <header css={formTitleStyle}>{t(\"profile.setting.language\")}</header>\n          <div css={formFieldStyle}>\n            <Select\n              value={currentLanguage}\n              size=\"large\"\n              colorScheme=\"techPurple\"\n              options={LANG_OPTIONS}\n              onChange={(value) => {\n                onChangeLanguage(value as string)\n              }}\n            />\n            <span>\n              <Button\n                colorScheme=\"techPurple\"\n                size=\"large\"\n                disabled={buttonDisabled}\n                loading={loading}\n                onClick={() => {\n                  onSubmit()\n                }}\n              >\n                {t(\"profile.setting.save\")}\n              </Button>\n            </span>\n          </div>\n        </div>\n      </div>\n    </>\n  )\n}\n\nPCLanguageSetting.displayName = \"LanguageSetting\"\n\nexport default PCLanguageSetting\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/language/pc/interface.ts",
    "content": "export interface LanguageSettingProps {\n  loading: boolean\n  language: string\n  currentLanguage: string\n  onChangeLanguage: (language: string) => void\n  onSubmit: () => void\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/language/pc/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const innerContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n  justify-content: center;\n  max-width: 600px;\n  width: 100%;\n`\n\nexport const formFieldStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 40px;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/index.tsx",
    "content": "import { isILLAAPiError } from \"@illa-public/illa-net\"\nimport { LayoutAutoChange } from \"@illa-public/layout-auto-change\"\nimport { ResetPwdFields } from \"@illa-public/sso-module/ResetPasswordPage/interface\"\nimport { getCurrentUser } from \"@illa-public/user-data\"\nimport { FC, useState } from \"react\"\nimport { FormProvider, SubmitHandler, useForm } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { useMessage } from \"@illa-design/react\"\nimport { TeamProvider } from \"@/page/setting/context\"\nimport { PasswordSettingFields } from \"@/page/setting/interface\"\nimport { fetchUpdateUserPassword } from \"@/services/user\"\nimport { MobilePasswordSettingContent } from \"./mobile\"\nimport { PasswordSettingContent } from \"./pc\"\n\nconst PasswordSettingPage: FC = () => {\n  const { t } = useTranslation()\n  const userInfo = useSelector(getCurrentUser)\n  const [passwordLoading, setPasswordLoading] = useState(false)\n\n  const message = useMessage()\n\n  const passwordFormProps = useForm<PasswordSettingFields>({\n    mode: \"onSubmit\",\n    criteriaMode: \"firstError\",\n  })\n  const setPasswordFormProps = useForm<ResetPwdFields>({\n    mode: \"onSubmit\",\n    criteriaMode: \"firstError\",\n    defaultValues: {\n      email: userInfo?.email,\n    },\n  })\n\n  const onPasswordFormSubmit: SubmitHandler<PasswordSettingFields> = async (\n    data,\n  ) => {\n    try {\n      setPasswordLoading(true)\n      await fetchUpdateUserPassword(data)\n      message.success({\n        content: t(\"team_setting.message.save_suc\"),\n      })\n      passwordFormProps.reset()\n    } catch (e) {\n      if (isILLAAPiError(e)) {\n      }\n    } finally {\n      setPasswordLoading(false)\n    }\n  }\n\n  return (\n    <TeamProvider passwordFormProps={passwordFormProps}>\n      <FormProvider {...setPasswordFormProps}>\n        <LayoutAutoChange\n          desktopPage={\n            <PasswordSettingContent\n              onPasswordFormSubmit={onPasswordFormSubmit}\n              passwordLoading={passwordLoading}\n            />\n          }\n          mobilePage={\n            <MobilePasswordSettingContent\n              onPasswordFormSubmit={onPasswordFormSubmit}\n              passwordLoading={passwordLoading}\n            />\n          }\n        />\n      </FormProvider>\n    </TeamProvider>\n  )\n}\n\nexport default PasswordSettingPage\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/interface.ts",
    "content": "import { SubmitHandler } from \"react-hook-form\"\n\nexport interface PasswordSettingFields {\n  currentPassword: string\n  newPassword: string\n  confirmPassword: string\n}\n\nexport type PasswordSettingErrorMsg = Partial<\n  Record<keyof PasswordSettingFields, string>\n>\nexport interface PasswordSettingProps {\n  onPasswordFormSubmit: SubmitHandler<PasswordSettingFields>\n  passwordLoading: boolean\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/mobile/changePassword/index.tsx",
    "content": "import { FC, useContext, useMemo } from \"react\"\nimport { Controller, UseFormReturn } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button, Password } from \"@illa-design/react\"\nimport { TeamContext } from \"@/page/setting/context\"\nimport { PasswordSettingFields } from \"@/page/setting/interface\"\nimport SettingMobileLayout from \"@/page/setting/layout/mobile\"\nimport { controllerContainerStyle, formContainerStyle } from \"../style\"\nimport { PasswordSettingMobileProps } from \"./interface\"\nimport { errorMsgStyle, mobileInputStyle, submitButtonStyle } from \"./style\"\n\nconst MobileChangePassword: FC<PasswordSettingMobileProps> = (props) => {\n  const { t } = useTranslation()\n  const { passwordFormProps } = useContext(TeamContext)\n  const { onSubmit, loading } = props\n  const { handleSubmit, control, formState, getValues, watch } =\n    passwordFormProps as UseFormReturn<PasswordSettingFields>\n\n  const { currentPassword, newPassword, confirmPassword } = watch()\n\n  const disabled = useMemo(() => {\n    return !(currentPassword && newPassword && confirmPassword)\n  }, [currentPassword, newPassword, confirmPassword])\n\n  return (\n    <SettingMobileLayout>\n      <form onSubmit={handleSubmit?.(onSubmit)} css={formContainerStyle}>\n        <section css={controllerContainerStyle}>\n          <label>{t(\"profile.setting.current_pwd\")}</label>\n          <div>\n            <Controller\n              name=\"currentPassword\"\n              control={control}\n              render={({ field }) => (\n                <Password\n                  {...field}\n                  _css={mobileInputStyle}\n                  size=\"large\"\n                  error={!!formState?.errors.currentPassword}\n                  variant=\"fill\"\n                  placeholder={t(\"profile.setting.password_placeholder\")}\n                  colorScheme=\"techPurple\"\n                />\n              )}\n              rules={{\n                required: t(\"profile.setting.password_empty\"),\n                minLength: {\n                  value: 6,\n                  message: t(\"profile.setting.password_length\"),\n                },\n                maxLength: {\n                  value: 20,\n                  message: t(\"profile.setting.password_length\"),\n                },\n              }}\n            />\n            {formState?.errors.currentPassword && (\n              <div css={errorMsgStyle}>\n                {formState?.errors.currentPassword?.message}\n              </div>\n            )}\n          </div>\n        </section>\n        <section css={controllerContainerStyle}>\n          <label>{t(\"profile.setting.new_pwd\")}</label>\n          <div>\n            <Controller\n              name=\"newPassword\"\n              control={control}\n              render={({ field }) => (\n                <Password\n                  {...field}\n                  _css={mobileInputStyle}\n                  size=\"large\"\n                  error={!!formState?.errors.newPassword}\n                  variant=\"fill\"\n                  placeholder={t(\"profile.setting.new_password_placeholder\")}\n                  colorScheme=\"techPurple\"\n                />\n              )}\n              rules={{\n                required: t(\"profile.setting.new_password_empty\"),\n                minLength: {\n                  value: 6,\n                  message: t(\"profile.setting.password_length\"),\n                },\n                maxLength: {\n                  value: 20,\n                  message: t(\"profile.setting.password_length\"),\n                },\n              }}\n            />\n            {formState?.errors.newPassword && (\n              <div css={errorMsgStyle}>\n                {formState?.errors.newPassword?.message}\n              </div>\n            )}\n          </div>\n        </section>\n        <section css={controllerContainerStyle}>\n          <label>{t(\"profile.setting.confirm_pwd\")}</label>\n          <div>\n            <Controller\n              name=\"confirmPassword\"\n              control={control}\n              render={({ field }) => (\n                <Password\n                  {...field}\n                  _css={mobileInputStyle}\n                  size=\"large\"\n                  error={!!formState?.errors.confirmPassword}\n                  variant=\"fill\"\n                  placeholder={t(\n                    \"profile.setting.new_password_again_placeholder\",\n                  )}\n                  colorScheme=\"techPurple\"\n                />\n              )}\n              rules={{\n                validate: (value) =>\n                  value === getValues?.(\"newPassword\") ||\n                  t(\"profile.setting.password_not_match\"),\n              }}\n            />\n            {formState?.errors.confirmPassword && (\n              <div css={errorMsgStyle}>\n                {formState?.errors.confirmPassword?.message}\n              </div>\n            )}\n          </div>\n        </section>\n        <Button\n          _css={submitButtonStyle}\n          colorScheme=\"techPurple\"\n          size=\"large\"\n          loading={loading}\n          disabled={disabled}\n          fullWidth\n        >\n          {t(\"profile.setting.save\")}\n        </Button>\n      </form>\n    </SettingMobileLayout>\n  )\n}\n\nMobileChangePassword.displayName = \"PasswordSettingMobile\"\n\nexport default MobileChangePassword\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/mobile/changePassword/interface.ts",
    "content": "import { SubmitHandler } from \"react-hook-form\"\nimport { PasswordSettingFields } from \"@/page/setting/interface\"\n\nexport interface PasswordSettingMobileProps {\n  loading: boolean\n  onSubmit: SubmitHandler<PasswordSettingFields>\n  validPasswordReport?: () => void\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/mobile/changePassword/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const gridFormFieldStyle: SerializedStyles = css`\n  display: grid;\n  gap: 24px;\n  margin-bottom: 40px;\n`\nexport const formTitleStyle: SerializedStyles = css`\n  font-weight: 600;\n  font-size: 18px;\n  line-height: 26px;\n  color: ${globalColor(`--${illaPrefix}-gray-02`)};\n  margin-bottom: 16px;\n`\nexport const submitButtonStyle: SerializedStyles = css`\n  height: 88rem;\n  border-radius: 16rem;\n\n  & > span {\n    font-size: 32rem;\n  }\n`\n\nexport const errorMsgStyle: SerializedStyles = css`\n  position: absolute;\n  font-size: 24rem;\n  padding-top: 8rem;\n  color: ${globalColor(`--${illaPrefix}-orange-03`)};\n`\n\nexport const mobileInputStyle = css`\n  font-size: 28rem;\n  height: 96rem;\n\n  & > span {\n    padding: 0 32rem;\n\n    & svg {\n      font-size: 40rem;\n    }\n  }\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/mobile/index.tsx",
    "content": "import { FC } from \"react\"\nimport { PasswordSettingProps } from \"../interface\"\nimport MobileChangePassword from \"./changePassword\"\n\nexport const MobilePasswordSettingContent: FC<PasswordSettingProps> = (\n  props,\n) => {\n  const { passwordLoading, onPasswordFormSubmit } = props\n\n  return (\n    <MobileChangePassword\n      onSubmit={onPasswordFormSubmit}\n      loading={passwordLoading}\n    />\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/mobile/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const controllerContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 32rem;\n`\n\nexport const formContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 64rem;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/pc/changePassword/index.tsx",
    "content": "import { FC, useContext, useMemo } from \"react\"\nimport { Controller, UseFormReturn } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button, Password, WarningCircleIcon } from \"@illa-design/react\"\nimport { Header } from \"@/page/setting/components/Header\"\nimport { TeamContext } from \"@/page/setting/context\"\nimport { PasswordSettingFields } from \"@/page/setting/interface\"\nimport { PasswordSettingProps } from \"./interface\"\nimport {\n  formLabelStyle,\n  gridFormFieldStyle,\n  innerContainerStyle,\n} from \"./style\"\nimport {\n  errorIconStyle,\n  errorMsgStyle,\n  gridItemStyle,\n  passwordFormContainerStyle,\n} from \"./style\"\n\nconst PCChangePassword: FC<PasswordSettingProps> = (props) => {\n  const { t } = useTranslation()\n  const { passwordFormProps } = useContext(TeamContext)\n  const { onSubmit, loading } = props\n  const { handleSubmit, control, formState, watch } =\n    passwordFormProps as UseFormReturn<PasswordSettingFields>\n\n  const { currentPassword, newPassword, confirmPassword } = watch()\n\n  const disabled = useMemo(() => {\n    return !(currentPassword && newPassword && confirmPassword)\n  }, [currentPassword, newPassword, confirmPassword])\n\n  return (\n    <>\n      <Header title={t(\"profile.setting.password.title\")} />\n      <div css={innerContainerStyle}>\n        <form\n          onSubmit={handleSubmit?.(onSubmit)}\n          css={passwordFormContainerStyle}\n        >\n          <section css={gridFormFieldStyle}>\n            <section css={gridItemStyle}>\n              <label css={formLabelStyle}>\n                {t(\"profile.setting.current_pwd\")}\n              </label>\n              <div>\n                <Controller\n                  name=\"currentPassword\"\n                  control={control}\n                  render={({ field }) => (\n                    <Password\n                      {...field}\n                      size=\"large\"\n                      error={!!formState?.errors.currentPassword}\n                      variant=\"fill\"\n                      placeholder={t(\"profile.setting.password_placeholder\")}\n                      colorScheme=\"techPurple\"\n                    />\n                  )}\n                  rules={{\n                    required: t(\"profile.setting.password_empty\"),\n                    minLength: {\n                      value: 6,\n                      message: t(\"profile.setting.password_length\"),\n                    },\n                    maxLength: {\n                      value: 20,\n                      message: t(\"profile.setting.password_length\"),\n                    },\n                  }}\n                />\n                {formState?.errors.currentPassword && (\n                  <div css={errorMsgStyle}>\n                    <WarningCircleIcon css={errorIconStyle} />\n                    {formState?.errors.currentPassword?.message}\n                  </div>\n                )}\n              </div>\n            </section>\n            <section css={gridItemStyle}>\n              <label css={formLabelStyle}>{t(\"profile.setting.new_pwd\")}</label>\n              <div>\n                <Controller\n                  name=\"newPassword\"\n                  control={control}\n                  render={({ field }) => (\n                    <Password\n                      {...field}\n                      size=\"large\"\n                      error={!!formState?.errors.newPassword}\n                      variant=\"fill\"\n                      placeholder={t(\n                        \"profile.setting.new_password_placeholder\",\n                      )}\n                      colorScheme=\"techPurple\"\n                    />\n                  )}\n                  rules={{\n                    required: t(\"profile.setting.new_password_empty\"),\n                    minLength: {\n                      value: 6,\n                      message: t(\"profile.setting.password_length\"),\n                    },\n                    maxLength: {\n                      value: 20,\n                      message: t(\"profile.setting.password_length\"),\n                    },\n                  }}\n                />\n                {formState?.errors.newPassword && (\n                  <div css={errorMsgStyle}>\n                    <WarningCircleIcon css={errorIconStyle} />\n                    {formState?.errors.newPassword?.message}\n                  </div>\n                )}\n              </div>\n            </section>\n            <section css={gridItemStyle}>\n              <label css={formLabelStyle}>\n                {t(\"profile.setting.confirm_pwd\")}\n              </label>\n              <div>\n                <Controller\n                  name=\"confirmPassword\"\n                  control={control}\n                  render={({ field }) => (\n                    <Password\n                      {...field}\n                      size=\"large\"\n                      error={!!formState?.errors.confirmPassword}\n                      variant=\"fill\"\n                      placeholder={t(\n                        \"profile.setting.new_password_again_placeholder\",\n                      )}\n                      colorScheme=\"techPurple\"\n                    />\n                  )}\n                  rules={{\n                    validate: (value) =>\n                      value === newPassword ||\n                      t(\"profile.setting.password_not_match\"),\n                  }}\n                />\n                {formState?.errors.confirmPassword && (\n                  <div css={errorMsgStyle}>\n                    <WarningCircleIcon css={errorIconStyle} />\n                    {formState?.errors.confirmPassword?.message}\n                  </div>\n                )}\n              </div>\n            </section>\n            <span>\n              <Button\n                colorScheme=\"techPurple\"\n                size=\"large\"\n                loading={loading}\n                disabled={disabled}\n              >\n                {t(\"profile.setting.save\")}\n              </Button>\n            </span>\n          </section>\n        </form>\n      </div>\n    </>\n  )\n}\n\nPCChangePassword.displayName = \"PasswordSetting\"\n\nexport default PCChangePassword\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/pc/changePassword/interface.ts",
    "content": "import { SubmitHandler } from \"react-hook-form\"\nimport { PasswordSettingFields } from \"@/page/setting/interface\"\n\nexport interface PasswordSettingProps {\n  loading: boolean\n  onSubmit: SubmitHandler<PasswordSettingFields>\n  validPasswordReport?: () => void\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/pc/changePassword/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const gridFormFieldStyle: SerializedStyles = css`\n  display: flex;\n  flex-direction: column;\n  gap: 24px;\n  width: 100%;\n`\n\nexport const passwordFormContainerStyle = css`\n  display: flex;\n  width: 600px;\n  justify-content: center;\n`\n\nexport const formTitleStyle: SerializedStyles = css`\n  font-weight: 600;\n  font-size: 18px;\n  line-height: 26px;\n  color: ${globalColor(`--${illaPrefix}-gray-02`)};\n  margin-bottom: 16px;\n`\n\nexport const errorMsgStyle: SerializedStyles = css`\n  position: relative;\n  font-size: 14px;\n  padding-left: 24px;\n  line-height: 22px;\n  color: ${globalColor(`--${illaPrefix}-orange-03`)};\n`\n\nexport const errorIconStyle: SerializedStyles = css`\n  position: absolute;\n  font-size: 16px;\n  line-height: 0;\n  top: 3px;\n  left: 0;\n`\nexport const gridItemStyle: SerializedStyles = css`\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n`\n\nexport const formLabelStyle = css`\n  font-size: 14px;\n  line-height: 22px;\n  font-weight: 500;\n`\n\nexport const innerContainerStyle = css`\n  display: flex;\n  justify-content: center;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/password/pc/index.tsx",
    "content": "import { FC } from \"react\"\nimport { PasswordSettingProps } from \"../interface\"\nimport PCChangePassword from \"./changePassword\"\n\nexport const PasswordSettingContent: FC<PasswordSettingProps> = (props) => {\n  const { passwordLoading, onPasswordFormSubmit } = props\n\n  return (\n    <PCChangePassword\n      onSubmit={onPasswordFormSubmit}\n      loading={passwordLoading}\n    />\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/personal/index.tsx",
    "content": "import { LayoutAutoChange } from \"@illa-public/layout-auto-change\"\nimport { currentUserActions, getCurrentUser } from \"@illa-public/user-data\"\nimport { FC, useEffect, useState } from \"react\"\nimport { SubmitHandler, useForm } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { useMessage } from \"@illa-design/react\"\nimport { updateUserAvatar, uploadUserAvatar } from \"@/api/auth\"\nimport { TeamProvider } from \"@/page/setting/context\"\nimport { AccountSettingFields } from \"@/page/setting/interface\"\nimport { fetchUpdateNickName } from \"@/services/user\"\nimport MobileAccountSetting from \"./mobile\"\nimport PCAccountSetting from \"./pc\"\n\nexport const PersonalSetting: FC = () => {\n  const { t } = useTranslation()\n  const dispatch = useDispatch()\n  const userInfo = useSelector(getCurrentUser)\n  const [accountLoading, setAccountLoading] = useState(false)\n\n  const message = useMessage()\n  const accountFormProps = useForm<AccountSettingFields>({\n    mode: \"onSubmit\",\n    criteriaMode: \"firstError\",\n  })\n\n  useEffect(() => {\n    if (userInfo) {\n      accountFormProps.reset({\n        nickname: userInfo?.nickname,\n      })\n    }\n    // todo: @echoxyc\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [userInfo?.nickname])\n\n  const onAccountSubmit: SubmitHandler<AccountSettingFields> = async (data) => {\n    try {\n      setAccountLoading(true)\n      await fetchUpdateNickName(data.nickname)\n      message.success({\n        content: t(\"team_setting.message.save_suc\"),\n      })\n      window.location.reload()\n    } catch (e) {\n    } finally {\n      setAccountLoading(false)\n    }\n  }\n\n  const handleUpdateAvatar = async (file: Blob) => {\n    try {\n      const icon = await uploadUserAvatar(file)\n      await updateUserAvatar(icon)\n      dispatch(currentUserActions.updateUserAvatarReducer(icon))\n      message.success({\n        content: t(\"profile.setting.message.save_suc\"),\n      })\n      return true\n    } catch (e) {\n      console.error(\"handleUpdateAvatar error:\", e)\n      message.error({\n        content: t(\"profile.setting.message.save_fail\"),\n      })\n    }\n    return false\n  }\n\n  return (\n    <TeamProvider accountFormProps={accountFormProps}>\n      <LayoutAutoChange\n        desktopPage={\n          <PCAccountSetting\n            loading={accountLoading}\n            onSubmit={onAccountSubmit}\n            handleUpdateAvatar={handleUpdateAvatar}\n          />\n        }\n        mobilePage={\n          <MobileAccountSetting\n            loading={accountLoading}\n            onSubmit={onAccountSubmit}\n            handleUpdateAvatar={handleUpdateAvatar}\n          />\n        }\n      />\n    </TeamProvider>\n  )\n}\n\nPersonalSetting.displayName = \"PersonalSetting\"\n\nexport default PersonalSetting\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/personal/mobile/index.tsx",
    "content": "import { Avatar } from \"@illa-public/avatar\"\nimport { AvatarUpload } from \"@illa-public/cropper\"\nimport { getCurrentUser } from \"@illa-public/user-data\"\nimport { FC, useContext } from \"react\"\nimport { Controller, UseFormReturn } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { Button, CameraIcon, Input } from \"@illa-design/react\"\nimport { TeamContext } from \"@/page/setting/context\"\nimport { AccountSettingFields } from \"@/page/setting/interface\"\nimport SettingMobileLayout from \"@/page/setting/layout/mobile\"\nimport { AccountSettingMobileProps } from \"./interface\"\nimport {\n  avatarContainerStyle,\n  cameraIconContainerStyle,\n  containerStyle,\n  controllerContainerStyle,\n  formContainerStyle,\n  formLabelStyle,\n  tipTextStyle,\n} from \"./style\"\nimport { errorMsgStyle } from \"./style\"\n\nconst MobileAccountSetting: FC<AccountSettingMobileProps> = (props) => {\n  const { t } = useTranslation()\n  const { accountFormProps } = useContext(TeamContext)\n  const { onSubmit, loading, handleUpdateAvatar } = props\n  const {\n    handleSubmit,\n    control,\n    formState,\n    formState: { isDirty },\n  } = accountFormProps as UseFormReturn<AccountSettingFields>\n  const userInfo = useSelector(getCurrentUser)\n\n  return (\n    <SettingMobileLayout>\n      <div css={containerStyle}>\n        <div css={avatarContainerStyle}>\n          <AvatarUpload isMobile onOk={handleUpdateAvatar}>\n            <div css={cameraIconContainerStyle}>\n              <CameraIcon />\n            </div>\n            <Avatar\n              size={100}\n              id={userInfo?.userID}\n              name={userInfo?.nickname}\n              avatarUrl={userInfo?.avatar}\n            />\n          </AvatarUpload>\n        </div>\n        <form onSubmit={handleSubmit?.(onSubmit)} css={formContainerStyle}>\n          <section css={controllerContainerStyle}>\n            <label css={formLabelStyle}>{t(\"profile.setting.username\")}</label>\n            <div>\n              <Controller\n                name=\"nickname\"\n                control={control}\n                render={({ field }) => (\n                  <Input\n                    {...field}\n                    size=\"large\"\n                    error={!!formState?.errors.nickname}\n                    variant=\"fill\"\n                    placeholder={t(\"profile.setting.username\")}\n                    colorScheme=\"techPurple\"\n                  />\n                )}\n                rules={{\n                  required: t(\"profile.setting.username_empty\"),\n                  maxLength: {\n                    value: 15,\n                    message: t(\"profile.setting.username_length\"),\n                  },\n                  minLength: {\n                    value: 3,\n                    message: t(\"profile.setting.username_length\"),\n                  },\n                }}\n              />\n              {formState?.errors.nickname && (\n                <div css={errorMsgStyle}>\n                  {formState?.errors.nickname?.message}\n                </div>\n              )}\n            </div>\n          </section>\n          <section css={controllerContainerStyle}>\n            <label css={formLabelStyle}>\n              {t(\"profile.setting.email\")}\n              <span css={tipTextStyle}> {t(\"profile.setting.uneditable\")}</span>\n            </label>\n            <div>\n              <Input\n                disabled\n                size=\"large\"\n                variant=\"fill\"\n                value={userInfo.email}\n                placeholder={t(\"profile.setting.new_password_placeholder\")}\n                colorScheme=\"techPurple\"\n              />\n            </div>\n          </section>\n          <Button\n            colorScheme=\"techPurple\"\n            size=\"large\"\n            loading={loading}\n            disabled={!isDirty}\n            fullWidth\n          >\n            {t(\"profile.setting.save\")}\n          </Button>\n        </form>\n      </div>\n    </SettingMobileLayout>\n  )\n}\n\nMobileAccountSetting.displayName = \"AccountSettingMobile\"\n\nexport default MobileAccountSetting\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/personal/mobile/interface.ts",
    "content": "import { SubmitHandler } from \"react-hook-form\"\nimport { AccountSettingFields } from \"@/page/setting/interface\"\n\nexport interface AccountSettingMobileProps {\n  loading: boolean\n  onSubmit: SubmitHandler<AccountSettingFields>\n  validAccountReport?: () => void\n  handleUpdateAvatar: (file: Blob) => Promise<boolean>\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/personal/mobile/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const tipTextStyle: SerializedStyles = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const errorMsgStyle: SerializedStyles = css`\n  position: absolute;\n  font-size: 24rem;\n  padding-top: 8rem;\n  color: ${globalColor(`--${illaPrefix}-orange-03`)};\n`\n\nexport const mobileInputStyle = css`\n  font-size: 28rem;\n  height: 96rem;\n\n  & > span {\n    padding: 0 32rem;\n\n    & svg {\n      font-size: 40rem;\n    }\n  }\n`\n\nexport const avatarContainerStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`\n\nexport const cameraIconContainerStyle = css`\n  border-radius: 50%;\n  padding: 4px;\n  background-color: ${getColor(\"grayBlue\", \"09\")};\n  font-size: 16px;\n  position: absolute;\n  bottom: 0;\n  right: 0;\n`\n\nexport const containerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 48px;\n`\n\nexport const formLabelStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 16px;\n  font-weight: 500;\n  line-height: 20px;\n`\n\nexport const controllerContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 32rem;\n`\n\nexport const formContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 64rem;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/personal/pc/index.tsx",
    "content": "import { Avatar } from \"@illa-public/avatar\"\nimport { AvatarUpload } from \"@illa-public/cropper\"\nimport { getCurrentUser } from \"@illa-public/user-data\"\nimport { FC, useContext } from \"react\"\nimport { Controller, UseFormReturn } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { Button, Input, WarningCircleIcon } from \"@illa-design/react\"\nimport { Header } from \"@/page/setting/components/Header\"\nimport { TeamContext } from \"@/page/setting/context\"\nimport { AccountSettingFields } from \"@/page/setting/interface\"\nimport { AccountSettingProps } from \"./interface\"\nimport Logout from \"./logout\"\nimport {\n  avatarStyle,\n  contentContainerStyle,\n  editLabelStyle,\n  errorIconStyle,\n  errorMsgStyle,\n  formContainerStyle,\n  formLabelStyle,\n  gridItemStyle,\n  tipTextStyle,\n} from \"./style\"\nimport { gridFormFieldStyle } from \"./style\"\n\nconst PCAccountSetting: FC<AccountSettingProps> = (props) => {\n  const { t } = useTranslation()\n  const { accountFormProps } = useContext(TeamContext)\n  const { onSubmit, loading, handleUpdateAvatar } = props\n  const {\n    handleSubmit,\n    control,\n    formState,\n    formState: { isDirty },\n  } = accountFormProps as UseFormReturn<AccountSettingFields>\n  const userInfo = useSelector(getCurrentUser)\n\n  return (\n    <>\n      <Header title={t(\"profile.setting.personal_info\")} extra={<Logout />} />\n      <div css={contentContainerStyle}>\n        <div>\n          <AvatarUpload onOk={handleUpdateAvatar}>\n            <Avatar\n              css={avatarStyle}\n              id={userInfo?.userID}\n              name={userInfo?.nickname}\n              avatarUrl={userInfo?.avatar}\n            />\n            <span css={editLabelStyle}>Edit</span>\n          </AvatarUpload>\n        </div>\n        <form onSubmit={handleSubmit?.(onSubmit)} css={formContainerStyle}>\n          <section css={gridFormFieldStyle}>\n            <section css={gridItemStyle}>\n              <label css={formLabelStyle}>\n                {t(\"profile.setting.username\")}\n              </label>\n              <div>\n                <Controller\n                  name=\"nickname\"\n                  control={control}\n                  render={({ field }) => (\n                    <Input\n                      {...field}\n                      size=\"large\"\n                      error={!!formState?.errors.nickname}\n                      variant=\"fill\"\n                      placeholder={t(\"profile.setting.username\")}\n                      colorScheme=\"techPurple\"\n                    />\n                  )}\n                  rules={{\n                    required: t(\"profile.setting.username_empty\"),\n                    maxLength: {\n                      value: 15,\n                      message: t(\"profile.setting.username_length\"),\n                    },\n                    minLength: {\n                      value: 3,\n                      message: t(\"profile.setting.username_length\"),\n                    },\n                  }}\n                />\n                {formState?.errors.nickname && (\n                  <div css={errorMsgStyle}>\n                    <WarningCircleIcon css={errorIconStyle} />\n                    {formState?.errors.nickname?.message}\n                  </div>\n                )}\n              </div>\n            </section>\n            <section css={gridItemStyle}>\n              <label css={formLabelStyle}>\n                {t(\"profile.setting.email\")}\n                <span css={tipTextStyle}>\n                  {\" \"}\n                  {t(\"profile.setting.uneditable\")}\n                </span>\n              </label>\n              <div>\n                <Input\n                  size=\"large\"\n                  value={userInfo.email}\n                  disabled\n                  variant=\"fill\"\n                  placeholder={userInfo.email}\n                  colorScheme=\"techPurple\"\n                />\n              </div>\n            </section>\n            <span>\n              <Button\n                colorScheme=\"techPurple\"\n                size=\"large\"\n                loading={loading}\n                disabled={!isDirty}\n              >\n                {t(\"profile.setting.save\")}\n              </Button>\n            </span>\n          </section>\n        </form>\n      </div>\n    </>\n  )\n}\n\nPCAccountSetting.displayName = \"AccountSetting\"\n\nexport default PCAccountSetting\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/personal/pc/interface.ts",
    "content": "import { SubmitHandler } from \"react-hook-form\"\nimport { AccountSettingFields } from \"@/page/setting/interface\"\n\nexport interface AccountSettingProps {\n  loading: boolean\n  onSubmit: SubmitHandler<AccountSettingFields>\n  validAccountReport?: () => void\n  handleUpdateAvatar: (file: Blob) => Promise<boolean>\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/personal/pc/logout.tsx",
    "content": "import { FC, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button } from \"@illa-design/react\"\nimport { onClickLogout } from \"@/utils/auth\"\n\nconst Logout: FC = () => {\n  const { t } = useTranslation()\n  const [isLoading, setIsLoading] = useState(false)\n\n  return (\n    <div>\n      <Button\n        colorScheme=\"red\"\n        variant=\"light\"\n        size=\"large\"\n        loading={isLoading}\n        onClick={() => {\n          setIsLoading(true)\n          onClickLogout()\n        }}\n      >\n        {t(\"profile.setting.logout\")}\n      </Button>\n    </div>\n  )\n}\n\nLogout.displayName = \"Logout\"\n\nexport default Logout\n"
  },
  {
    "path": "apps/cloud/src/page/setting/account/personal/pc/style.ts",
    "content": "import { SerializedStyles, css } from \"@emotion/react\"\nimport { getColor, globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const gridFormFieldStyle: SerializedStyles = css`\n  display: flex;\n  flex-direction: column;\n  gap: 24px;\n  width: 100%;\n`\n\nexport const tipTextStyle: SerializedStyles = css`\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const errorMsgStyle: SerializedStyles = css`\n  position: relative;\n  font-size: 14px;\n  padding-left: 24px;\n  line-height: 22px;\n  color: ${globalColor(`--${illaPrefix}-orange-03`)};\n`\n\nexport const errorIconStyle: SerializedStyles = css`\n  position: absolute;\n  font-size: 16px;\n  line-height: 0;\n  top: 3px;\n  left: 0;\n`\nexport const gridItemStyle: SerializedStyles = css`\n  display: grid;\n  gap: 8px;\n`\n\nexport const avatarStyle = css`\n  width: 120px;\n  height: 120px;\n  margin-right: 64px;\n  font-size: 50px;\n  flex: none;\n`\n\nexport const editLabelStyle = css`\n  margin-right: 64px;\n  margin-top: 8px;\n  text-align: center;\n  font-weight: 400;\n  font-size: 14px;\n  line-height: 22px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-04`)};\n`\n\nexport const contentContainerStyle = css`\n  display: flex;\n  justify-content: center;\n  gap: 64px;\n`\n\nexport const outerContainerStyle = css`\n  display: flex;\n  justify-content: center;\n`\n\nexport const formLabelStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n  line-height: 1;\n`\n\nexport const formContainerStyle = css`\n  width: 600px;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/components/Header/index.tsx",
    "content": "import { FC } from \"react\"\nimport { HeaderProps } from \"./interface\"\nimport { settingHeaderStyle, titleStyle } from \"./style\"\n\nexport const Header: FC<HeaderProps> = (props) => {\n  const { title, extra } = props\n  return (\n    <div css={settingHeaderStyle}>\n      <h2 css={titleStyle}>{title}</h2>\n      {extra && <div>{extra}</div>}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/components/Header/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface HeaderProps {\n  title: string\n  extra?: ReactNode\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/components/Header/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const settingHeaderStyle = css`\n  width: 100%;\n  padding: 40px 0px;\n  display: flex;\n  justify-content: space-between;\n`\n\nexport const titleStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 24px;\n  font-weight: 600;\n  line-height: 32px;\n  margin: 0;\n  padding: 0;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/context/index.tsx",
    "content": "import { ResetPwdFields } from \"@illa-public/sso-module/ResetPasswordPage/interface\"\nimport { FC, ReactNode, createContext } from \"react\"\nimport { UseFormReturn } from \"react-hook-form\"\nimport {\n  AccountSettingFields,\n  PasswordSettingFields,\n} from \"@/page/setting/interface\"\n\ninterface TeamProps {\n  passwordFormProps?: UseFormReturn<PasswordSettingFields>\n  accountFormProps?: UseFormReturn<AccountSettingFields>\n  setPasswordFormProps?: UseFormReturn<ResetPwdFields>\n}\n\ninterface Inject extends TeamProps {\n  children: ReactNode\n}\n\nexport const TeamContext = createContext<TeamProps>({\n  passwordFormProps: {} as UseFormReturn<PasswordSettingFields>,\n  accountFormProps: {} as UseFormReturn<AccountSettingFields>,\n  setPasswordFormProps: {} as UseFormReturn<ResetPwdFields>,\n} as TeamProps)\n\nexport const TeamProvider: FC<Inject> = (props) => {\n  const { children, ...data } = props\n\n  return (\n    <TeamContext.Provider value={{ ...data }}>{children}</TeamContext.Provider>\n  )\n}\n\nTeamProvider.displayName = \"TeamProvider\"\n"
  },
  {
    "path": "apps/cloud/src/page/setting/index.tsx",
    "content": "import { LayoutAutoChange } from \"@illa-public/layout-auto-change\"\nimport { getCurrentUserID } from \"@illa-public/user-data\"\nimport { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Navigate, Outlet } from \"react-router-dom\"\nimport SettingLayout from \"./layout/pc\"\n\nexport const Setting: FC = () => {\n  const isLogin = useSelector(getCurrentUserID)\n\n  return isLogin ? (\n    <LayoutAutoChange\n      desktopPage={\n        <SettingLayout>\n          <Outlet />\n        </SettingLayout>\n      }\n      mobilePage={<Outlet />}\n    />\n  ) : (\n    <Navigate to=\"/login\" replace={true} />\n  )\n}\n\nSetting.displayName = \"Setting\"\n\nexport default Setting\n"
  },
  {
    "path": "apps/cloud/src/page/setting/interface.ts",
    "content": "export interface PasswordSettingFields {\n  currentPassword: string\n  newPassword: string\n  confirmPassword: string\n}\n\nexport interface AccountSettingFields {\n  nickname: string\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/landing/index.tsx",
    "content": "import { LayoutAutoChange } from \"@illa-public/layout-auto-change\"\nimport { FC } from \"react\"\nimport { Navigate } from \"react-router-dom\"\nimport SettingMobileLayout from \"@/page/setting/layout/mobile\"\nimport MobileEntrance from \"./mobileEntrance\"\n\nconst SettingLanding: FC = () => {\n  return (\n    <LayoutAutoChange\n      desktopPage={<Navigate to=\"/setting/account\" replace />}\n      mobilePage={\n        <SettingMobileLayout withoutPadding>\n          <MobileEntrance />\n        </SettingMobileLayout>\n      }\n    />\n  )\n}\n\nexport default SettingLanding\n"
  },
  {
    "path": "apps/cloud/src/page/setting/landing/interface.ts",
    "content": "export interface LandingMenuItems {\n  path: string\n  label: string\n  needPro?: boolean\n  hidden?: boolean\n  onClick?: () => void\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/landing/landingMenu/index.tsx",
    "content": "import { FC } from \"react\"\nimport { LandingMenuItems } from \"../interface\"\nimport { Item } from \"./items\"\n\nexport const MobileMenuItems: FC<{\n  itemList: LandingMenuItems[]\n}> = ({ itemList }) => {\n  return (\n    <div>\n      {itemList.map((item) =>\n        item.hidden ? null : <Item key={item.path} item={item} />,\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/landing/landingMenu/interface.ts",
    "content": "import { LandingMenuItems } from \"../interface\"\n\nexport interface LandingMenuItemProps {\n  item: LandingMenuItems\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/landing/landingMenu/items.tsx",
    "content": "import { FC } from \"react\"\nimport { useNavigate } from \"react-router-dom\"\nimport { NextIcon } from \"@illa-design/react\"\nimport { menuItemStyle, rightIconStyle } from \"../style\"\nimport { LandingMenuItemProps } from \"./interface\"\n\nexport const Item: FC<LandingMenuItemProps> = ({ item }) => {\n  const navigate = useNavigate()\n\n  const handleClick = (key: string) => {\n    navigate(key)\n  }\n  return (\n    <div\n      css={menuItemStyle}\n      onClick={() => (item.onClick ? item.onClick() : handleClick(item.path))}\n    >\n      <div>{item.label}</div>\n      <NextIcon css={rightIconStyle} />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/landing/mobileEntrance.tsx",
    "content": "import { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport ProfileIcon from \"@/assets/page/setting/profile.svg?react\"\nimport TeamIcon from \"@/assets/page/setting/team.svg?react\"\nimport { canMemberAccess } from \"@/router/loader/accessUtils\"\nimport { onClickLogout } from \"@/utils/auth\"\nimport { MobileMenuItems } from \"./landingMenu\"\nimport {\n  landingMenuItemsStyle,\n  landingMenuTitleStyle,\n  landingTitleStyle,\n} from \"./style\"\n\nconst MobileEntrance: FC = () => {\n  const { t } = useTranslation()\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n\n  const notCanAccessMember = !canMemberAccess(currentTeamInfo)\n\n  const accountOptions = [\n    {\n      path: \"/setting/account\",\n      label: t(\"profile.setting.personal_info\"),\n    },\n    {\n      path: \"/setting/password\",\n      label: t(\"profile.setting.password.title\"),\n    },\n    {\n      path: \"/setting/language\",\n      label: t(\"profile.setting.language\"),\n    },\n    {\n      path: \"\",\n      label: t(\"profile.setting.logout\"),\n      onClick: onClickLogout,\n    },\n  ]\n\n  const teamOptions = [\n    {\n      path: `/setting/${currentTeamInfo?.identifier}/members`,\n      label: t(\"team_setting.left_panel.member\"),\n      hidden: notCanAccessMember,\n    },\n  ]\n\n  return (\n    <>\n      <div css={landingTitleStyle}>{t(\"profile.setting.title\")}</div>\n      <div css={landingMenuTitleStyle}>\n        <ProfileIcon />\n        <span>{t(\"profile.setting.group.account\")}</span>\n      </div>\n      <MobileMenuItems itemList={accountOptions} />\n      {notCanAccessMember && (\n        <>\n          <div css={landingMenuItemsStyle} />\n          {currentTeamInfo && (\n            <>\n              <div css={landingMenuTitleStyle}>\n                <TeamIcon />\n                <span>{t(\"profile.setting.group.team\")}</span>\n              </div>\n            </>\n          )}\n          <MobileMenuItems itemList={teamOptions} />\n        </>\n      )}\n    </>\n  )\n}\n\nMobileEntrance.displayName = \"MobileEntrance\"\n\nexport default MobileEntrance\n"
  },
  {
    "path": "apps/cloud/src/page/setting/landing/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const landingTitleStyle = css`\n  width: 100%;\n  padding: 4px 16px 20px 16px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 24px;\n  font-weight: 600;\n`\nexport const landingMenuItemsStyle = css`\n  background-color: #f7f8fa;\n  width: 100%;\n  height: 12px;\n`\nexport const landingMenuTitleStyle = css`\n  display: flex;\n  padding: 9px 16px;\n  align-items: center;\n  gap: 8px;\n  color: ${getColor(\"grayBlue\", \"04\")};\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 22px;\n`\n\nexport const menuItemStyle = css`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 11px 16px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 15px;\n  font-style: normal;\n  font-weight: 400;\n  line-height: 22px;\n  &:hover {\n    background-color: ${getColor(\"grayBlue\", \"09\")};\n  }\n`\n\nexport const rightIconStyle = css`\n  color: #a9aeb8;\n`\n\n// mobile\nexport const landingWrapperStyle = css`\n  position: relative;\n  margin: 16px;\n  min-height: 500px;\n`\nexport const avatarStyle = css`\n  margin: 0 auto 48px;\n  width: 100px;\n  height: 100px;\n`\n\nexport const cameraIconStyle = css`\n  width: 28px;\n  height: 28px;\n  position: absolute;\n  top: 72px;\n  right: 113px;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/layout/mobile/index.tsx",
    "content": "import { getCurrentTeamIdentifier } from \"@illa-public/user-data\"\nimport { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { useLocation, useNavigate } from \"react-router-dom\"\nimport { PreviousIcon } from \"@illa-design/react\"\nimport { SettingMobileLayoutProps } from \"./interface\"\nimport {\n  applyContentStyle,\n  mobileTitleStyle,\n  navStyle,\n  prevIconStyle,\n  wrapperStyle,\n} from \"./style\"\n\nconst SettingMobileLayout: FC<SettingMobileLayoutProps> = (props) => {\n  const { children, navRight, withoutPadding, title } = props\n  const navigate = useNavigate()\n  const history = useLocation()\n\n  const currentTeamIdentifier = useSelector(getCurrentTeamIdentifier)\n  const extraPath = history.pathname.split(\"/\")[2]\n\n  const clickBackBtn = () => {\n    if (Boolean(extraPath)) {\n      navigate(\"/setting\")\n    } else {\n      currentTeamIdentifier\n        ? navigate(`/workspace/${currentTeamIdentifier}`)\n        : navigate(\"/workspace\")\n    }\n  }\n\n  return (\n    <div css={wrapperStyle}>\n      <div css={navStyle}>\n        <PreviousIcon css={prevIconStyle} onClick={clickBackBtn} />\n        {navRight}\n      </div>\n      <div css={applyContentStyle(withoutPadding)}>\n        {title && <div css={mobileTitleStyle}>{title}</div>}\n        {children}\n      </div>\n    </div>\n  )\n}\n\nSettingMobileLayout.displayName = \"SettingMobileLayout\"\n\nexport default SettingMobileLayout\n"
  },
  {
    "path": "apps/cloud/src/page/setting/layout/mobile/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface SettingMobileLayoutProps {\n  children: ReactNode\n  navRight?: ReactNode\n  withoutPadding?: boolean\n  title?: string\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/layout/mobile/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const navStyle = css`\n  position: absolute;\n  top: 0;\n  width: 100%;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 24rem 12rem;\n  background: ${getColor(\"white\", \"01\")};\n  z-index: 2;\n`\n\nexport const wrapperStyle = css`\n  font-size: 32rem;\n  line-height: 44rem;\n`\nexport const contentStyle = css`\n  height: calc(var(--dvh, 1vh) * 100);\n  padding: 136rem 0 8rem 0;\n  font-size: 28rem;\n  overflow: auto;\n`\nexport const prevIconStyle = css`\n  font-size: 40rem;\n  margin: 20rem;\n  cursor: pointer;\n`\n\nexport const applyContentStyle = (withoutPadding?: boolean) => {\n  return css`\n    ${contentStyle};\n    padding: ${withoutPadding ? \"136rem 0 0\" : `136rem 32rem 8rem`};\n  `\n}\n\nexport const mobileTitleStyle = css`\n  width: 100%;\n  padding: 8rem 0 40rem 0;\n  margin-bottom: 40rem;\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 48rem;\n  font-weight: 600;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/layout/pc/index.tsx",
    "content": "import { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { useNavigate } from \"react-router-dom\"\nimport { PreviousIcon } from \"@illa-design/react\"\nimport ProfileIcon from \"@/assets/page/setting/profile.svg?react\"\nimport { Menu } from \"@/components/Menu\"\nimport { SettingLayoutProps } from \"./interface\"\nimport {\n  asideMenuStyle,\n  backIconStyle,\n  layoutWrapperStyle,\n  leftAsideWrapperStyle,\n  menuContainerStyle,\n  menuWrapperTittleStyle,\n  navWrapperStyle,\n  rightAsideWrapperStyle,\n  rightSectionContainerStyle,\n} from \"./style\"\n\nconst SettingLayout: FC<SettingLayoutProps> = (props) => {\n  const { children } = props\n  const { t } = useTranslation()\n  const navigate = useNavigate()\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)!\n\n  const accountOptions = [\n    {\n      path: \"/setting/account\",\n      label: t(\"profile.setting.personal_info\"),\n      icon: <></>,\n    },\n    {\n      path: \"/setting/password\",\n      label: t(\"profile.setting.password.title\"),\n      icon: <></>,\n    },\n    {\n      path: \"/setting/language\",\n      label: t(\"profile.setting.language\"),\n      icon: <></>,\n    },\n  ]\n\n  return (\n    <div css={layoutWrapperStyle}>\n      <aside css={leftAsideWrapperStyle}>\n        <div css={navWrapperStyle}>\n          <PreviousIcon\n            css={backIconStyle}\n            onClick={() => {\n              navigate(`/workspace/${currentTeamInfo?.identifier}`)\n            }}\n          />\n          {t(\"profile.setting.title\")}\n        </div>\n        <div css={asideMenuStyle}>\n          <div>\n            <div css={menuWrapperTittleStyle}>\n              <ProfileIcon />\n              <span>{t(\"profile.setting.group.account\")}</span>\n            </div>\n            <div css={menuContainerStyle}>\n              <Menu\n                itemList={accountOptions}\n                containerClassName=\"settingMenuClass\"\n                itemClassName=\"settingMenuItemClass\"\n              />\n            </div>\n          </div>\n        </div>\n      </aside>\n      <aside css={rightAsideWrapperStyle}>\n        <section css={rightSectionContainerStyle}>{children}</section>\n      </aside>\n    </div>\n  )\n}\n\nSettingLayout.displayName = \"AccountLayout\"\n\nexport default SettingLayout\n"
  },
  {
    "path": "apps/cloud/src/page/setting/layout/pc/interface.ts",
    "content": "import { ReactNode } from \"react\"\n\nexport interface SettingLayoutProps {\n  children: ReactNode\n}\n"
  },
  {
    "path": "apps/cloud/src/page/setting/layout/pc/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const rightAsideWrapperStyle = css`\n  position: relative;\n  display: flex;\n  flex-grow: 1;\n  justify-content: center;\n  background: ${getColor(\"white\", \"01\")};\n  border-radius: 16px;\n  overflow: auto;\n`\n\nexport const backIconStyle = css`\n  width: 16px;\n  height: 16px;\n  font-size: 16px;\n  margin-right: 12px;\n  cursor: pointer;\n`\n\nexport const leftAsideWrapperStyle = css`\n  padding: 24px 0;\n  width: 240px;\n  position: relative;\n  align-items: center;\n  flex: none;\n  overflow-y: auto;\n  border-right: 1px solid ${getColor(\"grayBlue\", \"09\")};\n`\n\nexport const navWrapperStyle = css`\n  padding: 16px 24px 24px;\n  display: flex;\n  align-items: center;\n  font-weight: 600;\n  font-size: 18px;\n  line-height: 32px;\n`\n\nexport const layoutWrapperStyle = css`\n  background: ${getColor(\"white\", \"01\")};\n  width: 100vw;\n  height: 100vh;\n  display: flex;\n`\n\nexport const menuContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 24px;\n  margin-left: -12px;\n  .settingMenuClass {\n    gap: 0;\n  }\n  .settingMenuItemClass {\n    padding-top: 8px;\n    padding-bottom: 8px;\n  }\n`\n\nexport const menuWrapperTittleStyle = css`\n  display: flex;\n  padding: 9px 24px;\n  align-items: center;\n  gap: 8px;\n  color: ${getColor(\"grayBlue\", \"03\")};\n  font-size: 14px;\n  font-style: normal;\n  font-weight: 500;\n  line-height: 22px;\n`\n\nexport const asideMenuStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 24px;\n`\n\nexport const rightSectionContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  padding: 0 32px;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/setting/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const formTitleStyle = css`\n  font-weight: 600;\n  font-size: 18px;\n  line-height: 26px;\n  color: ${globalColor(`--${illaPrefix}-gray-02`)};\n`\n\nexport const containerStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/status/403/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useNavigate } from \"react-router-dom\"\nimport { useSearchParams } from \"react-router-dom\"\nimport { Button, Result404Icon } from \"@illa-design/react\"\nimport { buttonStyle, errorPageStyle, iconStyle } from \"@/page/status/style\"\n\nexport const Status403: FC = () => {\n  const navigate = useNavigate()\n  const { t } = useTranslation()\n  const [searchParams] = useSearchParams()\n\n  const handleClickAgain = () => {\n    const redirectURL = searchParams.get(\"redirectURL\")\n    if (redirectURL) {\n      window.location.href = decodeURIComponent(redirectURL)\n    } else {\n      navigate(\"/\")\n    }\n  }\n  return (\n    <div css={errorPageStyle}>\n      <Result404Icon css={iconStyle} />\n      <span>403</span>\n      <span>{t(\"error_page.fobidden\")}</span>\n      <div css={buttonStyle}>\n        <Button onClick={handleClickAgain} colorScheme={\"gray\"}>\n          {t(\"error_page.again\")}\n        </Button>\n        <Button onClick={() => navigate(\"/\")} colorScheme=\"techPurple\">\n          {t(\"error_page.back\")}\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/status/404/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useNavigate } from \"react-router-dom\"\nimport { Button, Result404Icon } from \"@illa-design/react\"\nimport { buttonStyle, errorPageStyle, iconStyle } from \"@/page/status/style\"\n\nexport const Status404: FC = () => {\n  const navigate = useNavigate()\n  const { t } = useTranslation()\n  return (\n    <div css={errorPageStyle}>\n      <Result404Icon css={iconStyle} />\n      <span>404</span>\n      <span>{t(\"error_page.not_found\")}</span>\n      <div css={buttonStyle}>\n        <Button onClick={() => navigate(0)} colorScheme={\"gray\"}>\n          {t(\"error_page.again\")}\n        </Button>\n        <Button onClick={() => navigate(\"/\")} colorScheme=\"techPurple\">\n          {t(\"error_page.back\")}\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/status/500/index.tsx",
    "content": "import { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useNavigate } from \"react-router-dom\"\nimport { Button, Result500Icon } from \"@illa-design/react\"\nimport { buttonStyle, errorPageStyle, iconStyle } from \"@/page/status/style\"\n\nexport const Status500: FC = () => {\n  const navigate = useNavigate()\n  const { t } = useTranslation()\n\n  return (\n    <div css={errorPageStyle}>\n      <Result500Icon css={iconStyle} />\n      <span>500</span>\n      <span>{t(\"status.500.des\")}</span>\n      <div css={buttonStyle}>\n        <Button onClick={() => navigate(0)} colorScheme={\"gray\"}>\n          {t(\"error_page.again\")}\n        </Button>\n        <Button onClick={() => navigate(\"/\")} colorScheme=\"techPurple\">\n          {t(\"status.back\")}\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/status/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const errorPageStyle = css`\n  width: 100%;\n  height: 100vh;\n  display: flex;\n  flex-direction: column;\n  justify-content: start;\n  align-items: center;\n  padding-top: 30vh;\n  font-size: 14px;\n  color: ${globalColor(`--${illaPrefix}-grayBlue-02`)};\n  font-weight: bold;\n  line-height: 22px;\n  span + span {\n    font-weight: normal;\n    color: ${globalColor(`--${illaPrefix}-grayBlue-03`)};\n  }\n`\n\nexport const iconStyle = css`\n  height: 96px;\n  width: 96px;\n  border-radius: 50px;\n  background-color: ${globalColor(`--${illaPrefix}-grayBlue-09`)};\n  margin-bottom: 24px;\n`\n\nexport const buttonStyle = css`\n  margin-top: 24px;\n  display: flex;\n  gap: 8px;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/user/login/index.tsx",
    "content": "import { ERROR_FLAG, isILLAAPiError } from \"@illa-public/illa-net\"\nimport { LoginPage } from \"@illa-public/sso-module\"\nimport { LoginFields } from \"@illa-public/sso-module/LoginPage/interface\"\nimport { setAuthToken } from \"@illa-public/utils\"\nimport { FC, useState } from \"react\"\nimport { SubmitHandler } from \"react-hook-form\"\nimport { useTranslation } from \"react-i18next\"\nimport { useNavigate, useSearchParams } from \"react-router-dom\"\nimport { useMessage } from \"@illa-design/react\"\nimport { fetchSignIn } from \"@/services/auth\"\n\nexport type LoginErrorMsg = Record<keyof LoginFields, string>\n\nconst UserLogin: FC = () => {\n  const { t } = useTranslation()\n  const navigate = useNavigate()\n\n  const [loading, setLoading] = useState(false)\n  const [errorMsg, setErrorMsg] = useState<LoginErrorMsg>({\n    email: \"\",\n    password: \"\",\n  })\n\n  const message = useMessage()\n  const [searchParams] = useSearchParams()\n\n  const onSubmit: SubmitHandler<LoginFields> = async (data) => {\n    setLoading(true)\n    try {\n      const response = await fetchSignIn(data)\n      const token = response.headers[\"illa-token\"]\n      if (!token) return\n      setAuthToken(token)\n      message.success({\n        content: t(\"page.user.sign_in.tips.success\"),\n      })\n\n      navigate(\n        `/${searchParams.toString() ? \"?\" + searchParams.toString() : \"\"}`,\n      )\n    } catch (e) {\n      if (isILLAAPiError(e)) {\n        switch (e?.data?.errorFlag) {\n          case ERROR_FLAG.ERROR_FLAG_PASSWORD_INVALIED:\n          case ERROR_FLAG.ERROR_FLAG_SIGN_IN_FAILED:\n            message.error({\n              content: t(\"page.user.sign_in.tips.fail_account\"),\n            })\n            break\n          default:\n            message.error({\n              content: t(\"page.user.sign_in.tips.fail\"),\n            })\n            break\n        }\n        switch (e.data.errorMessage) {\n          case \"no such user\":\n            setErrorMsg({\n              ...errorMsg,\n              email: t(\"page.user.sign_in.error_message.email.registered\"),\n            })\n            break\n          case \"invalid password\":\n            setErrorMsg({\n              ...errorMsg,\n              password: t(\"page.user.sign_in.error_message.password.incorrect\"),\n            })\n            break\n          default:\n        }\n      } else {\n        message.warning({\n          content: t(\"network_error\"),\n        })\n      }\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  return <LoginPage loading={loading} errorMsg={errorMsg} onSubmit={onSubmit} />\n}\n\nexport default UserLogin\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/InitTeamPage/index.tsx",
    "content": "import { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { FC } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Navigate } from \"react-router-dom\"\n\nconst InitTeamPage: FC = () => {\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n\n  return currentTeamInfo ? (\n    <Navigate to={`/workspace/${currentTeamInfo.identifier}/apps`} />\n  ) : (\n    <Navigate to={`/404`} />\n  )\n}\n\nInitTeamPage.displayName = \"InitTeamPage\"\nexport default InitTeamPage\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/apps/index.tsx",
    "content": "import { LayoutAutoChange } from \"@illa-public/layout-auto-change\"\nimport { FC } from \"react\"\nimport { MobileAppWorkspace } from \"./mobile\"\nimport { PCAppWorkspace } from \"./pc\"\n\nexport * from \"./pc\"\n\nconst AppWorkspaceLanding: FC = () => {\n  return (\n    <LayoutAutoChange\n      desktopPage={<PCAppWorkspace />}\n      mobilePage={<MobileAppWorkspace />}\n    />\n  )\n}\n\nexport default AppWorkspaceLanding\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/apps/mobile/index.tsx",
    "content": "import { MobileAppCardItem, TeamContentEmpty } from \"@illa-public/dashboard\"\nimport { USER_ROLE } from \"@illa-public/public-types\"\nimport { getCurrentTeamInfo, getPlanUtils } from \"@illa-public/user-data\"\nimport {\n  ACTION_ACCESS,\n  ATTRIBUTE_GROUP,\n  canAccess,\n} from \"@illa-public/user-role-utils\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { Divider, Search } from \"@illa-design/react\"\nimport { FullSectionLoading } from \"@/components/FullSectionLoading\"\nimport { MobileDashboardHeader } from \"@/page/workspace/components/Header\"\nimport { useSearch } from \"@/page/workspace/hooks\"\nimport { useAppList } from \"@/services/swr/app\"\nimport { useDividerLine } from \"../../layout/hook\"\nimport { appContainerStyle, cardContainerStyle } from \"./style\"\n\nexport const MobileAppWorkspace = () => {\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n  const canAccessApps = canAccess(\n    currentTeamInfo?.myRole ?? USER_ROLE.VIEWER,\n    ATTRIBUTE_GROUP.APP,\n    getPlanUtils(currentTeamInfo),\n    ACTION_ACCESS.VIEW,\n  )\n  const { data: appList = [], isLoading } = useAppList(canAccessApps)\n  const { t } = useTranslation()\n  const appListFilter = appList.filter((app) => app.deployed)\n\n  const [appListResult, handleChangeSearch] = useSearch(appListFilter ?? [], [\n    \"appName\",\n    \"config.description\",\n  ])\n\n  const [dividerShown, onContainerScroll] = useDividerLine()\n\n  return (\n    <div css={appContainerStyle}>\n      <MobileDashboardHeader\n        titleName={t(\"page.workspace.menu.apps\")}\n        actionGroupComponent={\n          <>\n            <Search\n              size=\"large\"\n              colorScheme=\"techPurple\"\n              onChange={handleChangeSearch}\n              placeholder={t(\"dashboard.search\")}\n              allowClear\n            />\n          </>\n        }\n      />\n      {isLoading ? (\n        <FullSectionLoading />\n      ) : appListResult.length > 0 ? (\n        <>\n          {dividerShown && <Divider direction=\"horizontal\" />}\n          <div css={cardContainerStyle} onScroll={onContainerScroll}>\n            {appListResult.map((appInfo) => (\n              <MobileAppCardItem\n                key={appInfo.appId}\n                appName={appInfo.appName}\n                description={appInfo.config.description}\n                appDeployed={appInfo.deployed}\n                appActivity={appInfo.appActivity}\n                appID={appInfo.appId}\n                publishedToMarketplace={appInfo.config.publishedToMarketplace}\n                editorInfo={appInfo.editedBy}\n                cardType=\"app\"\n              />\n            ))}\n          </div>\n        </>\n      ) : (\n        <TeamContentEmpty loading={false} showCreate={false} />\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/apps/mobile/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const cardContainerStyle = css`\n  display: grid;\n  grid-template-columns: 1;\n  grid-gap: 24px 24px;\n  overflow: auto;\n  padding: 0 16px;\n  width: 100%;\n  padding-bottom: 24px;\n`\n\nexport const appContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/apps/pc/index.tsx",
    "content": "import { PCAppCard, TeamContentEmpty } from \"@illa-public/dashboard\"\nimport { AppListContextProvider } from \"@illa-public/dashboard\"\nimport { BASIC_APP_CONFIG } from \"@illa-public/public-configs\"\nimport { AppInfoShape, USER_ROLE } from \"@illa-public/public-types\"\nimport {\n  getCurrentId,\n  getCurrentTeamInfo,\n  getCurrentUser,\n  getPlanUtils,\n} from \"@illa-public/user-data\"\nimport {\n  ACTION_ACCESS,\n  ACTION_MANAGE,\n  ATTRIBUTE_GROUP,\n  canAccess,\n  canManage,\n} from \"@illa-public/user-role-utils\"\nimport {\n  getAuthToken,\n  getILLABuilderURL,\n  sendTagEvent,\n} from \"@illa-public/utils\"\nimport { useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { mutate } from \"swr\"\nimport {\n  Button,\n  Divider,\n  PlusIcon,\n  Search,\n  useMessage,\n} from \"@illa-design/react\"\nimport { FullSectionLoading } from \"@/components/FullSectionLoading\"\nimport { DashboardHeader } from \"@/page/workspace/components/Header\"\nimport { useSearch } from \"@/page/workspace/hooks\"\nimport {\n  fetchCopyApp,\n  fetchCreateApp,\n  fetchDeleteApp,\n  fetchUpdateAppConfig,\n  useAppList,\n} from \"@/services/swr/app\"\nimport { useDividerLine } from \"../../layout/hook\"\nimport { appContainerStyle, cardContainerStyle } from \"./style\"\nimport { generateDuplicateAppName } from \"./utils\"\n\nexport const PCAppWorkspace = () => {\n  const currentTeamID = useSelector(getCurrentId)!\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n  const userInfo = useSelector(getCurrentUser)\n\n  const canAccessApps = canAccess(\n    currentTeamInfo?.myRole ?? USER_ROLE.VIEWER,\n    ATTRIBUTE_GROUP.APP,\n    getPlanUtils(currentTeamInfo),\n    ACTION_ACCESS.VIEW,\n  )\n  const { data: appList, isLoading } = useAppList(canAccessApps)\n  const { t } = useTranslation()\n  const [createLoading, setCreateLoading] = useState(false)\n  const { teamIdentifier } = useParams()\n  const message = useMessage()\n\n  const [appListResult, handleChangeSearch] = useSearch(appList ?? [], [\n    \"appName\",\n    \"config.description\",\n  ])\n\n  const [dividerShown, onContainerScroll] = useDividerLine()\n\n  const refreshAppList = () => {\n    mutate([\"/apps\", currentTeamID])\n  }\n\n  const deleteApp = (appID: string) => {\n    const options = {\n      optimisticData: (appList?: AppInfoShape[]) =>\n        appList?.filter((item) => item.appId !== appID) ?? [],\n      rollbackOnError(error: unknown) {\n        if (error instanceof Error) {\n          return error.name !== \"AbortError\"\n        }\n        return true\n      },\n    }\n    return mutate(\n      [\"/apps\", currentTeamID, canAccessApps],\n      async (appList) => {\n        const response = await fetchDeleteApp(appID, currentTeamID)\n        if (Array.isArray(appList))\n          return appList.filter((item) => item.appId !== response.data.appID)\n        return appList\n      },\n      options,\n    )\n  }\n\n  const copyApp = (appID: string) => {\n    return mutate([\"/apps\", currentTeamID, canAccessApps], async () => {\n      if (Array.isArray(appListResult)) {\n        const targetAppInfo = appListResult?.find(\n          (item) => item.appId === appID,\n        )\n        if (!targetAppInfo) return\n        const newAppName = generateDuplicateAppName(targetAppInfo.appName)\n        const response = await fetchCopyApp(appID, newAppName, currentTeamID)\n        window.open(\n          `${getILLABuilderURL()}/${teamIdentifier}/app/${\n            response.appId\n          }?token=${getAuthToken()}`,\n          \"_blank\",\n        )\n        return [response, ...appListResult]\n      }\n      return appListResult\n    })\n  }\n\n  const updateAppConfig = (\n    appID: string,\n    config: {\n      public?: boolean\n      waterMark?: boolean\n      description?: string\n      appName?: string\n    },\n  ) => {\n    const options = {\n      optimisticData: (appList?: AppInfoShape[]) => {\n        const targetAppInfo = appList?.find((item) => item.appId === appID)\n        if (!targetAppInfo) return appList ?? []\n        const newAppList = appList?.filter((item) => item.appId !== appID) ?? []\n        return [\n          {\n            ...targetAppInfo,\n            appName: config.appName ?? targetAppInfo.appName,\n            config: {\n              ...targetAppInfo.config,\n              ...config,\n            },\n          },\n          ...newAppList,\n        ]\n      },\n      rollbackOnError(error: unknown) {\n        if (error instanceof Error) {\n          return error.name !== \"AbortError\"\n        }\n        return true\n      },\n      populateCache: (\n        updatedResult: AppInfoShape,\n        appList?: AppInfoShape[],\n      ) => {\n        const filteredAppList =\n          appList?.filter((item) => item.appId !== appID) ?? []\n        return [updatedResult, ...filteredAppList]\n      },\n      revalidate: false,\n    }\n    return mutate(\n      [\"/apps\", currentTeamID, canAccessApps],\n      fetchUpdateAppConfig(appID, currentTeamID, config),\n      options,\n    )\n  }\n\n  const handleClickCreateApp = async () => {\n    setCreateLoading(true)\n    try {\n      const resp = await fetchCreateApp(\n        {\n          appName: \"Untitled app\",\n          initScheme: BASIC_APP_CONFIG,\n        },\n        currentTeamID,\n      )\n      sendTagEvent(\"create_app\", userInfo?.userID)\n      refreshAppList()\n      window.open(\n        `${getILLABuilderURL()}/${teamIdentifier}/app/${\n          resp.data.appId\n        }?token=${getAuthToken()}`,\n        \"_blank\",\n      )\n    } catch (e) {\n      message.error({ content: t(\"create_fail\") })\n    } finally {\n      setCreateLoading(false)\n    }\n  }\n\n  return (\n    <div css={appContainerStyle}>\n      <DashboardHeader\n        titleName={t(\"page.workspace.menu.apps\")}\n        actionGroupComponent={\n          <>\n            <Search\n              w=\"200px\"\n              size=\"large\"\n              colorScheme=\"techPurple\"\n              onChange={handleChangeSearch}\n              placeholder={t(\"dashboard.search\")}\n              allowClear\n            />\n            {canManage(\n              currentTeamInfo?.myRole ?? USER_ROLE.GUEST,\n              ATTRIBUTE_GROUP.APP,\n              getPlanUtils(currentTeamInfo),\n              ACTION_MANAGE.CREATE_APP,\n            ) && (\n              <Button\n                size=\"large\"\n                colorScheme=\"techPurple\"\n                leftIcon={<PlusIcon />}\n                w=\"200px\"\n                loading={createLoading}\n                onClick={handleClickCreateApp}\n              >\n                {t(\"new_dashboard.button.blank\")}\n              </Button>\n            )}\n          </>\n        }\n      />\n      {isLoading ? (\n        <FullSectionLoading />\n      ) : appListResult.length > 0 ? (\n        <AppListContextProvider\n          deleteApp={deleteApp}\n          copyApp={copyApp}\n          updateAppConfig={updateAppConfig}\n        >\n          {dividerShown && <Divider direction=\"horizontal\" />}\n\n          <div css={cardContainerStyle} onScroll={onContainerScroll}>\n            {appListResult.map((appInfo) => (\n              <PCAppCard appInfo={appInfo} key={appInfo.appId} />\n            ))}\n          </div>\n        </AppListContextProvider>\n      ) : (\n        <TeamContentEmpty\n          loading={createLoading}\n          onClickButton={handleClickCreateApp}\n          showCreate={canManage(\n            currentTeamInfo?.myRole ?? USER_ROLE.GUEST,\n            ATTRIBUTE_GROUP.APP,\n            getPlanUtils(currentTeamInfo),\n            ACTION_MANAGE.CREATE_APP,\n          )}\n        />\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/apps/pc/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const cardContainerStyle = css`\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));\n  grid-gap: 24px 24px;\n  overflow: auto;\n  padding: 0 32px;\n  padding-bottom: 32px;\n`\n\nexport const appContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/apps/pc/utils.ts",
    "content": "const APP_NAME_MAX_LENGTH = 128\nconst COPY_SUFFIX = \" Copy\"\nconst trimmedLength = APP_NAME_MAX_LENGTH - COPY_SUFFIX.length\n\nexport const generateDuplicateAppName = (appName: string = \"\") =>\n  `${(appName || \"\").slice(0, trimmedLength)}${COPY_SUFFIX}`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/ChangeLogModal/constants.ts",
    "content": "export const CHANGE_LOG_NUM = 5\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/ChangeLogModal/index.tsx",
    "content": "import { ILLAMarkdown } from \"@illa-public/illa-markdown\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport {\n  Button,\n  CloseIcon,\n  Link,\n  Modal,\n  Timeline,\n  TimelineItem,\n  getColor,\n} from \"@illa-design/react\"\nimport ChangeLogIcon from \"@/assets/page/workspace/change-log-bg.svg?react\"\nimport { CHANGE_LOG_NUM } from \"./constants\"\nimport { ChangeLogModalProps } from \"./interface\"\nimport {\n  changeBgStyle,\n  changeLogContainerStyle,\n  closeIconStyle,\n  contentStyle,\n  headerStyle,\n  itemContainerStyle,\n  itemTitleStyle,\n  lineContainerStyle,\n  linkStyle,\n  modalMaskStyle,\n  modalStyle,\n} from \"./style\"\n\nconst ChangeLogModal: FC<ChangeLogModalProps> = ({ onClose }) => {\n  const { t } = useTranslation()\n\n  const CHANGE_LOGS = Array.from(new Array(CHANGE_LOG_NUM)).map((_, index) => ({\n    content: t(`page.left.menu.changeLogs.${index + 1}.content`),\n    title: t(`page.left.menu.changeLogs.${index + 1}.title`),\n    changeLogLink: t(`page.left.menu.changeLogs.${index + 1}.changeLogLink`),\n  }))\n\n  return (\n    <Modal\n      visible\n      maskClosable={false}\n      footer={false}\n      css={modalStyle}\n      maskStyle={modalMaskStyle}\n      withoutPadding\n    >\n      <div css={changeLogContainerStyle}>\n        <div css={headerStyle}>\n          <span css={closeIconStyle} onClick={onClose}>\n            <CloseIcon size=\"12px\" />\n          </span>\n          <span css={changeBgStyle}>\n            <ChangeLogIcon width=\"100%\" height=\"100%\" />\n          </span>\n        </div>\n        <div css={contentStyle}>\n          <Timeline>\n            {Array.isArray(CHANGE_LOGS) &&\n              CHANGE_LOGS?.map(({ content, changeLogLink, title }, i) => (\n                <TimelineItem\n                  key={title}\n                  index={i}\n                  css={lineContainerStyle}\n                  dotColor={getColor(\"techPurple\", \"01\")}\n                >\n                  <div css={itemContainerStyle}>\n                    <span css={itemTitleStyle}>{title}</span>\n                    <ILLAMarkdown\n                      textString={content}\n                      textColor={getColor(\"grayBlue\", \"02\")}\n                      urlColor={getColor(\"grayBlue\", \"02\")}\n                    />\n                    <Link\n                      href={changeLogLink ?? \"\"}\n                      css={linkStyle}\n                      colorScheme=\"white\"\n                      target=\"_blank\"\n                    >\n                      <Button colorScheme={getColor(\"grayBlue\", \"02\")}>\n                        {t(\"page.left.menu.changeLogs.read_more\")}\n                      </Button>\n                    </Link>\n                  </div>\n                </TimelineItem>\n              ))}\n          </Timeline>\n        </div>\n      </div>\n    </Modal>\n  )\n}\n\nexport default ChangeLogModal\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/ChangeLogModal/interface.ts",
    "content": "export interface ChangeLog {\n  content: string\n  title: string\n  changeLogLink: string\n}\n\nexport interface ChangeLogModalProps {\n  onClose: () => void\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/ChangeLogModal/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const modalStyle = css`\n  min-width: auto;\n  width: auto;\n  ${applyMobileStyle(css`\n    width: 716rem;\n    min-width: 716rem;\n  `)}\n`\nexport const modalMaskStyle = css`\n  background-color: ${getColor(\"white\", \"05\")};\n  backdrop-filter: blur(5px);\n`\n\nexport const changeLogContainerStyle = css`\n  overflow: hidden;\n`\n\nexport const headerStyle = css`\n  position: relative;\n`\n\nexport const closeIconStyle = css`\n  position: absolute;\n  width: 24px;\n  height: 24px;\n  line-height: 10px;\n  text-align: center;\n  top: 16px;\n  right: 16px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\nexport const contentStyle = css`\n  overflow-y: auto;\n  padding: 32px;\n  max-height: 480px;\n  width: 488px;\n  ${applyMobileStyle(css`\n    width: 100%;\n  `)}\n`\nexport const lineContainerStyle = css`\n  padding: 0;\n  margin-bottom: 32px;\n  &:last-of-type {\n    margin-bottom: 0;\n  }\n`\n\nexport const itemContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n  ul,\n  ol {\n    padding-left: 16px;\n  }\n`\n\nexport const itemTitleStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 16px;\n  font-style: normal;\n  font-weight: 600;\n  line-height: 24px;\n`\n\nexport const linkStyle = css`\n  display: flex;\n  padding: 0;\n`\n\nexport const changeBgStyle = css`\n  display: flex;\n  width: 100%;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/DynamicMenu/index.tsx",
    "content": "import { DynamicMenu, MenuItemShape } from \"@illa-public/cloud-dashboard-layout\"\nimport { USER_ROLE } from \"@illa-public/public-types\"\nimport { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { useLocation, useParams } from \"react-router-dom\"\nimport ResourceIcon from \"@/assets/icon/workspace/resource.svg?react\"\nimport AppIcon from \"@/assets/icon/workspace/workspace.svg?react\"\nimport { DashBoardDynamicMenuProps } from \"./interface\"\n\nexport const DashBoardDynamicMenu: FC<DashBoardDynamicMenuProps> = (props) => {\n  const { onClickMenuItemCallback } = props\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n  const { pathname } = useLocation()\n  const { teamIdentifier } = useParams()\n  const { t } = useTranslation()\n\n  const dynamicMenuConfig: MenuItemShape[] = [\n    {\n      labelKey: \"app\",\n      labelName: t(\"page.workspace.menu.apps\"),\n      href: `/workspace/${teamIdentifier}/apps`,\n      inStation: true,\n      icon: <AppIcon />,\n      onClickCallback: onClickMenuItemCallback,\n      hidden: !teamIdentifier,\n    },\n    {\n      labelKey: \"resource\",\n      labelName: t(\"page.workspace.menu.resources\"),\n      href: `/workspace/${teamIdentifier}/resources`,\n      inStation: true,\n      icon: <ResourceIcon />,\n      hidden:\n        !teamIdentifier ||\n        ![USER_ROLE.OWNER, USER_ROLE.ADMIN, USER_ROLE.EDITOR].includes(\n          currentTeamInfo?.myRole ?? USER_ROLE.VIEWER,\n        ),\n      onClickCallback: onClickMenuItemCallback,\n    },\n  ]\n\n  const selectedKey = dynamicMenuConfig.find((item) =>\n    pathname.includes(item.href ?? \"\"),\n  )?.labelKey\n\n  return <DynamicMenu config={dynamicMenuConfig} selectedKey={selectedKey} />\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/DynamicMenu/interface.ts",
    "content": "export interface DashBoardDynamicMenuProps {\n  onClickMenuItemCallback?: () => void\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/Header/index.tsx",
    "content": "import { FC } from \"react\"\nimport { DashboardHeaderProps } from \"./interface\"\nimport {\n  mobileHeaderContainerStyle,\n  mobileInnerHeaderContainerStyle,\n} from \"./mobileStyle\"\nimport {\n  actionGroupContainerStyle,\n  headerContainerStyle,\n  innerHeaderContainerStyle,\n  titleStyle,\n} from \"./style\"\n\nexport const DashboardHeader: FC<DashboardHeaderProps> = (props) => {\n  const { titleName, actionGroupComponent } = props\n  return (\n    <header css={headerContainerStyle}>\n      <div css={innerHeaderContainerStyle}>\n        <h1 css={titleStyle}>{titleName}</h1>\n        {!!actionGroupComponent && (\n          <div css={actionGroupContainerStyle}>{actionGroupComponent}</div>\n        )}\n      </div>\n    </header>\n  )\n}\n\nexport const MobileDashboardHeader: FC<DashboardHeaderProps> = (props) => {\n  const { titleName, actionGroupComponent } = props\n\n  return (\n    <header css={mobileHeaderContainerStyle}>\n      <div css={mobileInnerHeaderContainerStyle}>\n        <h1 css={titleStyle}>{titleName}</h1>\n        {!!actionGroupComponent && (\n          <div css={actionGroupContainerStyle}>{actionGroupComponent}</div>\n        )}\n      </div>\n    </header>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/Header/interface.tsx",
    "content": "import { ReactNode } from \"react\"\n\nexport interface DashboardHeaderProps {\n  titleName: string\n  actionGroupComponent?: ReactNode\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/Header/mobileStyle.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const mobileHeaderContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  padding: 4px 16px 20px 16px;\n  align-items: center;\n`\n\nexport const mobileInnerHeaderContainerStyle = css`\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  gap: 12px;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/Header/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const headerContainerStyle = css`\n  display: flex;\n  flex-direction: column;\n  gap: 24px;\n  width: 100%;\n  padding: 40px 32px;\n  align-items: center;\n`\n\nexport const innerHeaderContainerStyle = css`\n  width: 100%;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  height: 40px;\n`\n\nexport const titleStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n  font-size: 24px;\n  font-weight: 600;\n  line-height: 32px;\n  margin: 0;\n  white-space: nowrap;\n`\n\nexport const actionGroupContainerStyle = css`\n  display: flex;\n  align-items: center;\n  gap: 8px;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/ToCloudModal/index.tsx",
    "content": "import { FC } from \"react\"\nimport { Trans, useTranslation } from \"react-i18next\"\nimport {\n  Button,\n  CloseIcon,\n  DoubtIcon,\n  Link,\n  Modal,\n  Trigger,\n  TriggerProvider,\n} from \"@illa-design/react\"\nimport DiscordIcon from \"./assets/discord-icon.svg?react\"\nimport TipIcon from \"./assets/pricing-tip.svg?react\"\nimport ModalDecorate from \"./assets/upgrad-modal-bg.svg?react\"\nimport {\n  applyCardListStyle,\n  boldStyle,\n  decorateStyle,\n  descriptionStyle,\n  doubtStyle,\n  footerStyle,\n  headerStyle,\n  iconStyle,\n  linkStyle,\n  modalCloseIconStyle,\n  modalMaskStyle,\n  modalStyle,\n  priceContentStyle,\n  priceStyle,\n  titleStyle,\n  upgradeButtonStyle,\n} from \"./style\"\n\ninterface ToCloudModalProps {\n  onClose: () => void\n}\n\nexport const ToCloudModal: FC<ToCloudModalProps> = ({ onClose }) => {\n  const { t } = useTranslation()\n\n  const FEATURE_CONFIG = [\n    {\n      label: t(\"new_dashboard.selfhost.export.feature1\"),\n      tip: t(\"new_dashboard.selfhost.export.feature_tips1\"),\n    },\n    {\n      label: t(\"new_dashboard.selfhost.export.feature2\"),\n      tip: t(\"new_dashboard.selfhost.export.feature_tips2\"),\n    },\n    {\n      label: t(\"new_dashboard.selfhost.export.feature3\"),\n      tip: t(\"new_dashboard.selfhost.export.feature_tips3\"),\n    },\n    {\n      label: t(\"new_dashboard.selfhost.export.feature4\"),\n      tip: t(\"new_dashboard.selfhost.export.feature_tips4\"),\n    },\n    {\n      label: t(\"new_dashboard.selfhost.export.feature5\"),\n      tip: t(\"new_dashboard.selfhost.export.feature_tips5\"),\n    },\n    {\n      label: t(\"new_dashboard.selfhost.export.feature6\"),\n      tip: t(\"new_dashboard.selfhost.export.feature_tips6\"),\n    },\n  ]\n\n  return (\n    <Modal\n      visible\n      _css={modalStyle}\n      withoutPadding\n      maskClosable={false}\n      footer={false}\n      onCancel={onClose}\n      maskStyle={modalMaskStyle}\n    >\n      <div css={modalCloseIconStyle} onClick={onClose}>\n        <CloseIcon size=\"12px\" />\n      </div>\n      <ModalDecorate css={decorateStyle} />\n      <div css={headerStyle}>\n        <div css={titleStyle}>{t(\"new_dashboard.selfhost.export.title\")}</div>\n        <div css={descriptionStyle}>\n          <span>\n            <Trans\n              i18nKey={\"new_dashboard.selfhost.export.desc\"}\n              t={t}\n              components={[<span key=\"discordName\" css={boldStyle} />]}\n            />\n          </span>\n        </div>\n      </div>\n      <TriggerProvider zIndex={1005}>\n        <div>\n          {FEATURE_CONFIG.map(({ label, tip }) => {\n            return (\n              <div css={applyCardListStyle} key={label}>\n                {label && <TipIcon css={iconStyle} />}\n                <span>{label}</span>\n                <Trigger\n                  trigger=\"hover\"\n                  maxW=\"300px\"\n                  colorScheme=\"techPurple\"\n                  content={tip}\n                >\n                  <span css={doubtStyle}>\n                    <DoubtIcon css={iconStyle} />\n                  </span>\n                </Trigger>\n              </div>\n            )\n          })}\n          <div css={footerStyle}>\n            <div>\n              <div css={priceStyle}>$16.7</div>\n              <div css={priceContentStyle}>\n                {t(\"billing.modal.upgrade_now_admin.pricing\")}\n              </div>\n            </div>\n            <Link\n              href=\"https://discord.com/invite/illacloud\"\n              css={linkStyle}\n              colorScheme=\"white\"\n              target=\"_blank\"\n            >\n              <Button\n                css={upgradeButtonStyle}\n                leftIcon={<DiscordIcon width=\"12px\" height=\"12px\" />}\n                colorScheme=\"techPurple\"\n              >\n                {t(\"new_dashboard.selfhost.export.button\")}\n              </Button>\n            </Link>\n          </div>\n        </div>\n      </TriggerProvider>\n    </Modal>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/ToCloudModal/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { applyMobileStyle } from \"@illa-public/utils\"\nimport { getColor } from \"@illa-design/react\"\n\nexport const modalMaskStyle = css`\n  background-color: ${getColor(\"white\", \"05\")};\n  backdrop-filter: blur(5px);\n`\n\nexport const modalStyle = css`\n  border: unset;\n  width: 486px;\n  min-width: 486px;\n  background: ${getColor(\"white\", \"01\")};\n  border: 1px solid ${getColor(\"grayBlue\", \"08\")};\n  box-shadow: 0 4px 16px rgb(0 0 0 / 8%);\n  border-radius: 8px;\n  overflow: hidden;\n\n  ${applyMobileStyle(css`\n    width: 358px;\n    min-width: 358px;\n    border-radius: 8px;\n  `)}\n`\n\nexport const modalCloseIconStyle = css`\n  position: absolute;\n  width: 24px;\n  height: 24px;\n  line-height: 10px;\n  text-align: center;\n  top: 18px;\n  right: 17px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const decorateStyle = css`\n  width: 100%;\n\n  ${applyMobileStyle(css`\n    height: 202px;\n  `)};\n`\n\nexport const headerStyle = css`\n  padding: 16px;\n`\n\nexport const titleStyle = css`\n  font-weight: 600;\n  font-size: 18px;\n  line-height: 22px;\n  margin-bottom: 8px;\n\n  ${applyMobileStyle(css`\n    font-size: 18px;\n    line-height: 22px;\n    margin-bottom: 8px;\n  `)};\n`\n\nexport const descriptionStyle = css`\n  font-weight: 400;\n  font-size: 14px;\n  line-height: 17px;\n  color: ${getColor(\"grayBlue\", \"03\")};\n\n  ${applyMobileStyle(css`\n    font-size: 14px;\n    line-height: 17px;\n  `)};\n`\n\nexport const boldStyle = css`\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const footerStyle = css`\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  padding: 16px;\n`\n\nexport const upgradeButtonStyle = css`\n  align-self: center;\n`\n\nexport const priceContentStyle = css`\n  font-size: 12px;\n  line-height: 20px;\n  color: ${getColor(\"grayBlue\", \"03\")};\n\n  ${applyMobileStyle(css`\n    font-size: 12px;\n    line-height: 20px;\n  `)};\n`\n\nexport const priceStyle = css`\n  font-weight: 500;\n  font-size: 14px;\n  line-height: 22px;\n  color: ${getColor(\"grayBlue\", \"02\")};\n`\n\nexport const applyCardListStyle = css`\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  gap: 8px;\n  font-weight: 400;\n  font-size: 14px;\n  line-height: 24px;\n  text-align: start;\n  padding: 4px 24px;\n\n  ${applyMobileStyle(css`\n    gap: 8px;\n    font-size: 14px;\n    line-height: 24px;\n  `)};\n`\n\nexport const doubtStyle = css`\n  cursor: pointer;\n  width: 16px;\n  height: 16px;\n  display: flex;\n  align-items: center;\n\n  &:hover .tips {\n    display: block;\n  }\n\n  ${applyMobileStyle(css`\n    width: 16px;\n    height: 16px;\n  `)};\n`\n\nexport const iconStyle = css`\n  height: 16px;\n  width: 16px;\n  flex-shrink: 0;\n\n  ${applyMobileStyle(css`\n    width: 16px;\n    height: 16px;\n  `)};\n`\n\nexport const linkStyle = css`\n  display: flex;\n  padding: 0;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/UpgradeTip/index.tsx",
    "content": "import { UpgradeIcon } from \"@illa-public/icon\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { Button } from \"@illa-design/react\"\nimport {\n  customUpgradeIconStyle,\n  linkStyle,\n  tipsTextStyle,\n  upgradeTipContainerStyle,\n} from \"./style\"\nimport CustomUpgradeIcon from \"./upgradeIcon.svg?react\"\n\ninterface UpgradeTipProps {\n  openToCloudModal: () => void\n}\n\nexport const UpgradeTip: FC<UpgradeTipProps> = ({ openToCloudModal }) => {\n  const { t } = useTranslation()\n  return (\n    <div css={upgradeTipContainerStyle}>\n      <p css={tipsTextStyle}>{t(\"billing.homepage.get_access_to_advanc\")}</p>\n      <CustomUpgradeIcon css={customUpgradeIconStyle} />\n      <div onClick={openToCloudModal} css={linkStyle}>\n        <Button colorScheme=\"techPurple\" leftIcon={<UpgradeIcon />} fullWidth>\n          {t(\"billing.homepage.upgrade\")}\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/components/UpgradeTip/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const upgradeTipContainerStyle = css`\n  width: 100%;\n  padding: 16px;\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n  border-radius: 8px;\n  background-color: #f4efff;\n  position: relative;\n`\n\nexport const tipsTextStyle = css`\n  margin: 0;\n  font-size: 14px;\n  color: #403673;\n  font-weight: 500;\n  line-height: 20px;\n  width: 144px;\n`\n\nexport const customUpgradeIconStyle = css`\n  position: absolute;\n  top: 8px;\n  right: 8px;\n`\n\nexport const linkStyle = css`\n  line-height: 1;\n  font-size: 14px;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/hooks.ts",
    "content": "import Fuse from \"fuse.js\"\nimport { debounce } from \"lodash-es\"\nimport { useRef, useState } from \"react\"\n\nexport function useSearch<T>(needSearchData: T[], buildKeys: string[]) {\n  const [searchKeyWords, setSearchKeywords] = useState(\"\")\n  const handleChangeSearch = useRef(() =>\n    debounce((value: string) => {\n      setSearchKeywords(value)\n    }, 160),\n  )\n\n  const searchIndex = Fuse.createIndex(buildKeys, needSearchData)\n\n  const fuse = new Fuse(\n    needSearchData,\n    {\n      keys: buildKeys,\n    },\n    searchIndex,\n  )\n\n  const result = searchKeyWords\n    ? fuse.search(searchKeyWords).map((item) => item.item)\n    : needSearchData\n\n  const onSearch = handleChangeSearch.current()\n\n  return [result, onSearch] as [T[], (value: string) => void]\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/index.tsx",
    "content": "import { LayoutAutoChange } from \"@illa-public/layout-auto-change\"\nimport { FC, useState } from \"react\"\nimport ChangeLogModal from \"./components/ChangeLogModal\"\nimport { ToCloudModal } from \"./components/ToCloudModal\"\nimport { MobileDashBoardLayout } from \"./layout/mobile\"\nimport { PCDashBoardLayout } from \"./layout/pc/\"\n\nconst Workspace: FC = () => {\n  const [changeLogVisible, setChangeLogVisible] = useState<boolean>(false)\n  const [toCloudModalVisible, setToCloudModalVisible] = useState<boolean>(false)\n\n  const onOpenChangeLogModal = () => {\n    setChangeLogVisible(true)\n  }\n\n  const openToCloudModal = () => {\n    setToCloudModalVisible(true)\n  }\n\n  return (\n    <>\n      <LayoutAutoChange\n        desktopPage={\n          <PCDashBoardLayout\n            onOpenChangeLogModal={onOpenChangeLogModal}\n            openToCloudModal={openToCloudModal}\n          />\n        }\n        mobilePage={\n          <MobileDashBoardLayout\n            onOpenChangeLogModal={onOpenChangeLogModal}\n            openToCloudModal={openToCloudModal}\n          />\n        }\n      />\n      {changeLogVisible && (\n        <ChangeLogModal onClose={() => setChangeLogVisible(false)} />\n      )}\n      {toCloudModalVisible && (\n        <ToCloudModal onClose={() => setToCloudModalVisible(false)} />\n      )}\n    </>\n  )\n}\n\nWorkspace.displayName = \"Workspace\"\n\nexport default Workspace\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/layout/hook.tsx",
    "content": "import { UIEvent, useState } from \"react\"\n\nexport const useDividerLine = (): [boolean, (e: UIEvent) => void] => {\n  const [dividerShow, setDividerShow] = useState(false)\n\n  const onContainerScroll = (e: UIEvent) => {\n    const target = e.target as HTMLDivElement\n    if (target.scrollTop >= 24) {\n      setDividerShow(true)\n    } else {\n      setDividerShow(false)\n    }\n  }\n  return [dividerShow, onContainerScroll]\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/layout/interface.ts",
    "content": "export interface WorkspaceLayoutProps {\n  onOpenChangeLogModal: () => void\n  openToCloudModal: () => void\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/layout/mobile/index.tsx",
    "content": "import {\n  BottomList,\n  MobileCloudDashboardLayout,\n} from \"@illa-public/cloud-dashboard-layout\"\nimport { getCurrentUserID } from \"@illa-public/user-data\"\nimport { FC, useState } from \"react\"\nimport { useSelector } from \"react-redux\"\nimport { Outlet } from \"react-router-dom\"\nimport { DashBoardDynamicMenu } from \"@/page/workspace/components/DynamicMenu\"\nimport { UpgradeTip } from \"@/page/workspace/components/UpgradeTip\"\nimport { WorkspaceLayoutProps } from \"../interface\"\n\nexport const MobileDashBoardLayout: FC<WorkspaceLayoutProps> = ({\n  onOpenChangeLogModal,\n  openToCloudModal,\n}) => {\n  const isLogin = useSelector(getCurrentUserID)\n  const [drawerVisible, setDrawerVisible] = useState(false)\n\n  const handleClickMenuItem = (key: string) => {\n    setDrawerVisible(false)\n    if (key === \"change-log\") {\n      onOpenChangeLogModal()\n    }\n  }\n\n  return (\n    <MobileCloudDashboardLayout\n      setDrawerVisible={setDrawerVisible}\n      drawerVisible={drawerVisible}\n      tipsComponent={<UpgradeTip openToCloudModal={openToCloudModal} />}\n      bottomComponent={\n        <BottomList onClickMenuItemCallback={handleClickMenuItem} />\n      }\n      dynamicMenu={\n        <div>\n          <DashBoardDynamicMenu\n            onClickMenuItemCallback={() => {\n              setDrawerVisible(false)\n            }}\n          />\n        </div>\n      }\n    >\n      {isLogin && <Outlet />}\n    </MobileCloudDashboardLayout>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/layout/pc/index.tsx",
    "content": "import { PCCloudDashBoardLayout } from \"@illa-public/cloud-dashboard-layout\"\nimport { BottomList } from \"@illa-public/cloud-dashboard-layout/components/BottomList\"\nimport { USER_ROLE } from \"@illa-public/public-types\"\nimport {\n  currentUserActions,\n  getCurrentTeamInfo,\n  getCurrentUserID,\n  getIsTutorialViewed,\n  getPlanUtils,\n} from \"@illa-public/user-data\"\nimport {\n  ACTION_MANAGE,\n  ATTRIBUTE_GROUP,\n  canManage,\n} from \"@illa-public/user-role-utils\"\nimport { getAuthToken, getILLABuilderURL } from \"@illa-public/utils\"\nimport { FC, Suspense, useEffect, useRef } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useDispatch, useSelector } from \"react-redux\"\nimport { Outlet, useParams } from \"react-router-dom\"\nimport { useModal } from \"@illa-design/react\"\nimport { FullSectionLoading } from \"@/components/FullSectionLoading\"\nimport { DashBoardDynamicMenu } from \"@/page/workspace/components/DynamicMenu\"\nimport { UpgradeTip } from \"@/page/workspace/components/UpgradeTip\"\nimport { updateTutorialViewed } from \"@/services/user\"\nimport { WorkspaceLayoutProps } from \"../interface\"\n\nexport const PCDashBoardLayout: FC<WorkspaceLayoutProps> = ({\n  onOpenChangeLogModal,\n  openToCloudModal,\n}) => {\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n  const isLogin = useSelector(getCurrentUserID)\n  const currentUserRole = currentTeamInfo?.myRole ?? USER_ROLE.VIEWER\n  const dispatch = useDispatch()\n  const isTutorialViewed = useSelector(getIsTutorialViewed)\n  const teamPlan = getPlanUtils(currentTeamInfo)\n  const modal = useModal()\n  const { t } = useTranslation()\n  const guideOpened = useRef(false)\n  const { teamIdentifier } = useParams()\n\n  const canEditApp = canManage(\n    currentUserRole,\n    ATTRIBUTE_GROUP.APP,\n    teamPlan,\n    ACTION_MANAGE.EDIT_APP,\n  )\n\n  const handleClickMenuItem = (key: string) => {\n    if (key === \"change-log\") {\n      onOpenChangeLogModal()\n    }\n  }\n\n  useEffect(() => {\n    if (\n      !isTutorialViewed &&\n      canEditApp &&\n      !guideOpened.current &&\n      teamIdentifier\n    ) {\n      guideOpened.current = true\n\n      modal.show({\n        id: \"openGuide\",\n        title: t(\"tutorial.modal.tutorial.first_time.title\"),\n        children: t(\"tutorial.modal.tutorial.first_time.description\"),\n        cancelText: t(\"tutorial.modal.tutorial.first_time.cancel\"),\n        okText: t(\"tutorial.modal.tutorial.first_time.take\"),\n        okButtonProps: {\n          colorScheme: \"techPurple\",\n        },\n        onOk: () => {\n          window.open(\n            `${getILLABuilderURL()}/${teamIdentifier}/guide?token=${getAuthToken()}`,\n          )\n        },\n        afterOpen: () => {\n          dispatch(currentUserActions.updateUserIsTutorialViewedReducer(true))\n          try {\n            updateTutorialViewed(true)\n          } catch (_ignore) {}\n        },\n      })\n    }\n  }, [canEditApp, dispatch, isTutorialViewed, modal, t, teamIdentifier])\n\n  return (\n    <PCCloudDashBoardLayout\n      dynamicMenu={\n        <div>\n          <DashBoardDynamicMenu />\n        </div>\n      }\n      tipsComponent={<UpgradeTip openToCloudModal={openToCloudModal} />}\n      bottomComponent={\n        <BottomList onClickMenuItemCallback={handleClickMenuItem} />\n      }\n    >\n      {isLogin && (\n        <Suspense fallback={<FullSectionLoading />}>\n          <Outlet />\n        </Suspense>\n      )}\n    </PCCloudDashBoardLayout>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/layout/style.ts",
    "content": "import { css } from \"@emotion/react\"\nimport { globalColor, illaPrefix } from \"@illa-design/react\"\n\nexport const layoutWrapperStyle = css`\n  background: #fafafa;\n  width: 100%;\n  height: 100%;\n  display: flex;\n`\n\nexport const leftAsideWrapperStyle = css`\n  padding: 56px 0 37px;\n  width: 240px;\n  position: relative;\n  flex: none;\n  display: flex;\n  flex-direction: column;\n  overflow: auto;\n`\n\nexport const rightAsideWrapperStyle = css`\n  position: relative;\n  background: ${globalColor(`--${illaPrefix}-white-01`)};\n  box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.06);\n  border-radius: 16px;\n  padding: 0 32px;\n  width: 100%;\n  height: 100%;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/resources/index.tsx",
    "content": "import { LayoutAutoChange } from \"@illa-public/layout-auto-change\"\nimport { FC } from \"react\"\nimport { MobileResourcesWorkspace } from \"./mobile\"\nimport { PCResourcesWorkspace } from \"./pc\"\n\nexport * from \"./pc\"\n\nconst ResourceWorkspaceLanding: FC = () => {\n  return (\n    <LayoutAutoChange\n      desktopPage={<PCResourcesWorkspace />}\n      mobilePage={<MobileResourcesWorkspace />}\n    />\n  )\n}\n\nexport default ResourceWorkspaceLanding\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/resources/mobile/index.tsx",
    "content": "import { ResourceCard, TeamContentEmpty } from \"@illa-public/dashboard\"\nimport { USER_ROLE } from \"@illa-public/public-types\"\nimport { getCurrentTeamInfo, getPlanUtils } from \"@illa-public/user-data\"\nimport {\n  ACTION_ACCESS,\n  ATTRIBUTE_GROUP,\n  canAccess,\n} from \"@illa-public/user-role-utils\"\nimport { FC } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { Divider, Search } from \"@illa-design/react\"\nimport { FullSectionLoading } from \"@/components/FullSectionLoading\"\nimport { MobileDashboardHeader } from \"@/page/workspace/components/Header\"\nimport { useSearch } from \"@/page/workspace/hooks\"\nimport { useResourceList } from \"@/services/swr/resource\"\nimport { useDividerLine } from \"../../layout/hook\"\nimport { getDBName } from \"../utils\"\nimport { cardContainerStyle, resourceContainerStyle } from \"./style\"\n\nexport const MobileResourcesWorkspace: FC = () => {\n  const { t } = useTranslation()\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n\n  const canAccessResourceList = canAccess(\n    currentTeamInfo?.myRole ?? USER_ROLE.VIEWER,\n    ATTRIBUTE_GROUP.RESOURCE,\n    getPlanUtils(currentTeamInfo),\n    ACTION_ACCESS.VIEW,\n  )\n  const { data, isLoading } = useResourceList(canAccessResourceList)\n  const [dividerShown, onContainerScroll] = useDividerLine()\n\n  const [resourceList, handleChangeSearch] = useSearch(data ?? [], [\n    \"resourceName\",\n  ])\n\n  return (\n    <div css={resourceContainerStyle}>\n      <MobileDashboardHeader\n        titleName={t(\"page.workspace.menu.resources\")}\n        actionGroupComponent={\n          <Search\n            w=\"100%\"\n            size=\"large\"\n            colorScheme=\"techPurple\"\n            onChange={handleChangeSearch}\n            placeholder={t(\"dashboard.search\")}\n            allowClear\n          />\n        }\n      />\n      {isLoading ? (\n        <FullSectionLoading />\n      ) : resourceList.length > 0 ? (\n        <>\n          {dividerShown && <Divider direction=\"horizontal\" />}\n          <div css={cardContainerStyle} onScroll={onContainerScroll}>\n            {resourceList?.map((resourceInfo) => (\n              <ResourceCard\n                key={resourceInfo.resourceID}\n                resourceType={resourceInfo.resourceType}\n                resourceName={resourceInfo.resourceName}\n                resourceID={resourceInfo.resourceID}\n                dbName={getDBName(resourceInfo)}\n              />\n            ))}\n          </div>\n        </>\n      ) : (\n        <TeamContentEmpty loading={false} showCreate={false} />\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/resources/mobile/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const resourceContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n`\n\nexport const cardContainerStyle = css`\n  display: grid;\n  grid-template-columns: 1;\n  grid-gap: 24px 24px;\n  overflow: auto;\n  padding: 0 16px;\n  padding-bottom: 24px;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/resources/pc/index.tsx",
    "content": "import { ResourceCard, TeamContentEmpty } from \"@illa-public/dashboard\"\nimport { USER_ROLE } from \"@illa-public/public-types\"\nimport { ResourceTypeSelector } from \"@illa-public/resource-generator\"\nimport {\n  getCurrentId,\n  getCurrentTeamInfo,\n  getPlanUtils,\n} from \"@illa-public/user-data\"\nimport {\n  ACTION_ACCESS,\n  ATTRIBUTE_GROUP,\n  canAccess,\n} from \"@illa-public/user-role-utils\"\nimport { getAuthToken, getILLABuilderURL } from \"@illa-public/utils\"\nimport { FC, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport { useSelector } from \"react-redux\"\nimport { useParams } from \"react-router-dom\"\nimport { mutate } from \"swr\"\nimport { Button, Divider, Modal, PlusIcon, Search } from \"@illa-design/react\"\nimport { FullSectionLoading } from \"@/components/FullSectionLoading\"\nimport { DashboardHeader } from \"@/page/workspace/components/Header\"\nimport { useSearch } from \"@/page/workspace/hooks\"\nimport { fetchDeleteResource, useResourceList } from \"@/services/swr/resource\"\nimport { useDividerLine } from \"../../layout/hook\"\nimport { getDBName } from \"../utils\"\nimport { cardContainerStyle, resourceContainerStyle } from \"./style\"\n\nexport const PCResourcesWorkspace: FC = () => {\n  const { t } = useTranslation()\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n\n  const canAccessResourceList = canAccess(\n    currentTeamInfo?.myRole ?? USER_ROLE.VIEWER,\n    ATTRIBUTE_GROUP.RESOURCE,\n    getPlanUtils(currentTeamInfo),\n    ACTION_ACCESS.VIEW,\n  )\n  const { data: resourceList = [], isLoading } = useResourceList(\n    canAccessResourceList,\n  )\n  const { teamIdentifier } = useParams()\n  const currentTeamID = useSelector(getCurrentId)!\n\n  const [resourceListResult, handleChangeSearch] = useSearch(\n    resourceList ?? [],\n    [\"resourceName\"],\n  )\n\n  const [dividerShown, onContainerScroll] = useDividerLine()\n\n  const [resourceSelectorVisible, setResourceSelectorVisible] = useState(false)\n\n  const onSelectResourceType = (resourceType: string) => {\n    window.open(\n      `${getILLABuilderURL()}/${teamIdentifier}/resource/new/${resourceType}?token=${getAuthToken()}`,\n    )\n  }\n\n  const onResourceDelete = (resourceID: string) => {\n    const newResourceList = resourceList.filter(\n      (item) => item.resourceID !== resourceID,\n    )\n    const options = {\n      optimisticData: newResourceList,\n      rollbackOnError(error: unknown) {\n        if (error instanceof Error) {\n          return error.name !== \"AbortError\"\n        }\n        return true\n      },\n    }\n    return mutate(\n      [\"/resources\", currentTeamID, canAccessResourceList],\n      async (resourceList) => {\n        const response = await fetchDeleteResource(resourceID, currentTeamID)\n        if (Array.isArray(resourceList))\n          return resourceList.filter(\n            (item) => item.resourceID !== response.data.resourceID,\n          )\n        return []\n      },\n      options,\n    )\n  }\n\n  return (\n    <div css={resourceContainerStyle}>\n      <DashboardHeader\n        titleName={t(\"page.workspace.menu.resources\")}\n        actionGroupComponent={\n          <>\n            <Search\n              w=\"200px\"\n              size=\"large\"\n              colorScheme=\"techPurple\"\n              onChange={handleChangeSearch}\n              placeholder={t(\"dashboard.search\")}\n              allowClear\n            />\n            <Button\n              size=\"large\"\n              colorScheme=\"techPurple\"\n              leftIcon={<PlusIcon />}\n              w=\"200px\"\n              onClick={() => setResourceSelectorVisible(true)}\n            >\n              {t(\"new_dashboard.button.blank\")}\n            </Button>\n          </>\n        }\n      />\n      {isLoading ? (\n        <FullSectionLoading />\n      ) : resourceListResult.length > 0 ? (\n        <>\n          {dividerShown && <Divider direction=\"horizontal\" />}\n          <div css={cardContainerStyle} onScroll={onContainerScroll}>\n            {resourceListResult?.map((resourceInfo) => (\n              <ResourceCard\n                key={resourceInfo.resourceID}\n                resourceType={resourceInfo.resourceType}\n                resourceName={resourceInfo.resourceName}\n                resourceID={resourceInfo.resourceID}\n                onDeleteResource={onResourceDelete}\n                onEditResource={() => {\n                  window.open(\n                    `${getILLABuilderURL()}/${teamIdentifier}/resource/edit/${\n                      resourceInfo.resourceID\n                    }?token=${getAuthToken()}`,\n                  )\n                }}\n                dbName={getDBName(resourceInfo)}\n              />\n            ))}\n          </div>\n        </>\n      ) : (\n        <TeamContentEmpty\n          loading={false}\n          onClickButton={() => setResourceSelectorVisible(true)}\n          showCreate\n        />\n      )}\n      {resourceSelectorVisible && (\n        <Modal\n          visible={resourceSelectorVisible}\n          w=\"1080px\"\n          footer={false}\n          closable\n          maskClosable\n          withoutLine\n          withoutPadding\n          title={t(\"editor.action.form.title.select\")}\n          onCancel={() => setResourceSelectorVisible(false)}\n        >\n          <ResourceTypeSelector onSelect={onSelectResourceType} />\n        </Modal>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/resources/pc/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nexport const resourceContainerStyle = css`\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n`\n\nexport const cardContainerStyle = css`\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));\n  grid-gap: 24px 24px;\n  overflow: auto;\n  padding: 0 32px;\n  padding-bottom: 32px;\n`\n"
  },
  {
    "path": "apps/cloud/src/page/workspace/resources/utils.ts",
    "content": "import {\n  AppWriteResource,\n  MicrosoftSqlResource,\n  MongoDbConfig,\n  MongoDbGuiConfigContent,\n  MongoDbResource,\n  MysqlLikeResource,\n  NeonResource,\n  OracleResource,\n  RedisResource,\n  Resource,\n  ResourceContent,\n  SnowflakeAuthenticationType,\n  SnowflakeResource,\n} from \"@illa-public/public-types\"\n\nexport const getDBName = (resource: Resource<ResourceContent>) => {\n  let dbName: string | undefined = undefined\n  switch (resource.resourceType) {\n    // default Null\n    case \"firebase\":\n    case \"smtp\":\n    case \"restapi\":\n    case \"elasticsearch\":\n    case \"dynamodb\":\n    case \"s3\":\n    case \"huggingface\":\n    case \"hfendpoint\":\n    case \"couchdb\":\n    case \"googlesheets\":\n    case \"airtable\":\n      break\n    // mysql like\n    case \"clickhouse\":\n    case \"supabasedb\":\n    case \"postgresql\":\n    case \"hydra\":\n    case \"mysql\":\n    case \"tidb\":\n    case \"mariadb\":\n      dbName = (resource as Resource<MysqlLikeResource>).content.databaseName\n      break\n    case \"neon\":\n      dbName = (resource as Resource<NeonResource>).content.databaseName\n      break\n    case \"redis\":\n    case \"upstash\":\n      dbName = (\n        resource as Resource<RedisResource>\n      ).content.databaseIndex.toString()\n      break\n    case \"mssql\":\n      dbName = (resource as Resource<MicrosoftSqlResource>).content.databaseName\n      break\n    case \"mongodb\":\n      const mongoRes = resource as Resource<MongoDbResource<MongoDbConfig>>\n      if (mongoRes.content.configType == \"gui\") {\n        dbName = (mongoRes.content.configContent as MongoDbGuiConfigContent)\n          .databaseName\n      }\n      break\n    case \"snowflake\":\n      dbName = (\n        resource.content as SnowflakeResource<SnowflakeAuthenticationType>\n      ).database\n      break\n    case \"appwrite\":\n      dbName = (resource.content as AppWriteResource).databaseID\n      break\n    case \"oracle\":\n    case \"oracle9i\":\n      dbName = (resource.content as OracleResource).name\n      break\n  }\n  return dbName\n}\n"
  },
  {
    "path": "apps/cloud/src/router/index.tsx",
    "content": "import { isCloudVersion } from \"@illa-public/utils\"\nimport { createBrowserRouter } from \"react-router-dom\"\nimport { ILLARoutesObject } from \"@/router/interface\"\nimport { routerConfig } from \"@/router/routerConfig\"\nimport { needAuthLoader } from \"./loader/authLoader\"\n\nconst wrappedRouter = (routesConfig: ILLARoutesObject[]) => {\n  return routesConfig.map((route) => {\n    const { element, children, needLogin, ...otherRouterParams } = route\n    const newRouteItem: ILLARoutesObject = {\n      element,\n      ...otherRouterParams,\n    }\n\n    if (needLogin) {\n      newRouteItem.loader = needAuthLoader\n    }\n\n    if (Array.isArray(children) && children.length) {\n      newRouteItem.children = wrappedRouter(children)\n    }\n    return newRouteItem\n  })\n}\n\nexport const ILLARoute = createBrowserRouter(wrappedRouter(routerConfig), {\n  basename: import.meta.env.PROD && !isCloudVersion ? \"/cloud\" : \"/\",\n})\n"
  },
  {
    "path": "apps/cloud/src/router/interface.ts",
    "content": "import { RouteObject } from \"react-router-dom\"\n\nexport type ILLARoutesObject = RouteObject & {\n  /**\n   * @description child route\n   */\n  children?: ILLARoutesObject[]\n  /**\n   * @description need login\n   */\n  needLogin?: boolean\n}\n"
  },
  {
    "path": "apps/cloud/src/router/lazyLoad/SettingLazyLoad/index.tsx",
    "content": "import { FC, LazyExoticComponent, Suspense } from \"react\"\nimport { FullPageLoading } from \"@/components/FullPageLoading\"\n\nexport const SettingLazyLoad: FC<{ Comp: LazyExoticComponent<any> }> = ({\n  Comp,\n}) => {\n  return (\n    <Suspense fallback={<FullPageLoading />}>\n      <Comp />\n    </Suspense>\n  )\n}\n\nSettingLazyLoad.displayName = \"AuthLayLoad\"\n"
  },
  {
    "path": "apps/cloud/src/router/loader/accessUtils.ts",
    "content": "import { TeamInfo, USER_ROLE } from \"@illa-public/public-types\"\nimport { isBiggerThanTargetRole } from \"@illa-public/user-role-utils\"\n\nexport const canMemberAccess = (teamInfo?: TeamInfo) => {\n  if (!teamInfo) return false\n  const currentUserRole = teamInfo?.myRole\n  const allowEditorManageTeamMember =\n    teamInfo?.permission?.allowEditorManageTeamMember\n  const allowViewerManageTeamMember =\n    teamInfo?.permission?.allowViewerManageTeamMember\n  if (allowViewerManageTeamMember && allowEditorManageTeamMember) {\n    return isBiggerThanTargetRole(USER_ROLE.VIEWER, currentUserRole)\n  } else {\n    return [USER_ROLE.OWNER, USER_ROLE.ADMIN].includes(currentUserRole)\n  }\n}\n"
  },
  {
    "path": "apps/cloud/src/router/loader/authLoader.ts",
    "content": "import {\n  currentUserActions,\n  getCurrentUser,\n  getTeamItems,\n  teamActions,\n} from \"@illa-public/user-data\"\nimport { getAuthToken, sendConfigEvent } from \"@illa-public/utils\"\nimport { LoaderFunctionArgs, redirect } from \"react-router-dom\"\nimport { fetchCurrentUserTeamsInfo } from \"@/services/team\"\nimport { fetchUserInfo } from \"@/services/user\"\nimport { store } from \"@/store\"\nimport { getLocalCurrentTeamID } from \"@/utils/auth\"\n\nexport const getUserInfoLoader = async () => {\n  const userInfo = getCurrentUser(store.getState())\n  if (!userInfo?.userID) {\n    const token = getAuthToken()\n    if (!token) {\n      return false\n    } else {\n      try {\n        const { data } = await fetchUserInfo()\n        sendConfigEvent(data?.userID)\n        const reportedUserInfo: Record<string, any> = {}\n        Object.entries(userInfo).forEach(([key, value]) => {\n          reportedUserInfo[`illa_${key}`] = value\n        })\n\n        store.dispatch(currentUserActions.updateCurrentUserReducer(data))\n        return true\n      } catch (e) {\n        return false\n      }\n    }\n  }\n  return true\n}\n\nexport const getTeamsInfoLoader = async () => {\n  const userListInDisk = getTeamItems(store.getState())\n  if (userListInDisk) {\n    return userListInDisk\n  }\n  try {\n    const response = await fetchCurrentUserTeamsInfo()\n    store.dispatch(teamActions.updateTeamItemsReducer(response.data ?? []))\n    return response.data ?? []\n  } catch (e) {\n    store.dispatch(teamActions.updateTeamItemsReducer([]))\n    return []\n  }\n}\n\nexport const needAuthLoader = async (args: LoaderFunctionArgs) => {\n  const { params } = args\n  const isLogin = await getUserInfoLoader()\n  if (isLogin) {\n    const { teamIdentifier } = params\n    const teamList = await getTeamsInfoLoader()\n    if (teamIdentifier) {\n      const team = teamList.find((team) => team.identifier === teamIdentifier)\n      if (!team) {\n        return redirect(\"/404\")\n      }\n      store.dispatch(teamActions.updateCurrentIdReducer(team.id))\n    } else {\n      let currentTeamID = getLocalCurrentTeamID()\n      const currentTeam = teamList.find((team) => team.id === currentTeamID)\n      if (!currentTeam) {\n        if (teamList.length > 0) {\n          store.dispatch(teamActions.updateCurrentIdReducer(teamList[0].id))\n        }\n      } else {\n        store.dispatch(teamActions.updateCurrentIdReducer(currentTeam.id))\n      }\n    }\n  } else {\n    return redirect(\"/login\")\n  }\n  return null\n}\n"
  },
  {
    "path": "apps/cloud/src/router/loader/rootLoader.ts",
    "content": "import { getAuthToken } from \"@illa-public/utils\"\nimport { LoaderFunctionArgs, redirect } from \"react-router-dom\"\nimport { getUserInfoLoader } from \"./authLoader\"\n\nexport const rootLoader = async (args: LoaderFunctionArgs) => {\n  const { request } = args\n  const url = new URL(request.url)\n  const paramsRedirectURL = url.searchParams.get(\"redirectURL\")\n  const isLogin = await getUserInfoLoader()\n  if (isLogin) {\n    const authToken = getAuthToken()!\n    if (paramsRedirectURL) {\n      const targetURL = new URL(decodeURIComponent(paramsRedirectURL))\n      targetURL.searchParams.set(\"token\", authToken)\n      return redirect(targetURL.toString())\n    } else {\n      return redirect(\"/workspace\")\n    }\n  } else {\n    return redirect(`/login${url.search ?? \"\"}`)\n  }\n}\n"
  },
  {
    "path": "apps/cloud/src/router/routerConfig.tsx",
    "content": "import { PCDashboardLoading } from \"@illa-public/cloud-dashboard-layout\"\nimport { Suspense, lazy } from \"react\"\nimport { Navigate } from \"react-router-dom\"\nimport { FullPageLoading } from \"@/components/FullPageLoading\"\nimport { Status403 } from \"@/page/status/403\"\nimport { Status404 } from \"@/page/status/404\"\nimport { Status500 } from \"@/page/status/500\"\nimport { ILLARoutesObject } from \"@/router/interface\"\nimport { SettingLazyLoad } from \"@/router/lazyLoad/SettingLazyLoad\"\nimport { rootLoader } from \"./loader/rootLoader\"\n\nconst WorkSpaceLanding = lazy(() => import(\"@/page/workspace\"))\nconst InitWorkSpaceLanding = lazy(() => import(\"@/page/workspace/InitTeamPage\"))\nconst AppWorkSpaceLanding = lazy(() => import(\"@/page/workspace/apps\"))\nconst ResourceWorkSpaceLanding = lazy(\n  () => import(\"@/page/workspace/resources\"),\n)\n\nconst SettingLanding = lazy(() => import(\"@/page/setting/landing\"))\nconst PersonalSetting = lazy(() => import(\"@/page/setting/account/personal\"))\nconst LanguageSetting = lazy(() => import(\"@/page/setting/account/language\"))\nconst PasswordSettingPage = lazy(\n  () => import(\"@/page/setting/account/password\"),\n)\nconst LoginPage = lazy(() => import(\"@/page/user/login\"))\n\nexport const routerConfig: ILLARoutesObject[] = [\n  {\n    index: true,\n    loader: rootLoader,\n  },\n  {\n    path: \"/login\",\n    element: (\n      <Suspense fallback={<FullPageLoading />}>\n        <LoginPage />\n      </Suspense>\n    ),\n  },\n  {\n    path: \"/workspace\",\n    element: (\n      <Suspense fallback={<PCDashboardLoading />}>\n        <WorkSpaceLanding />\n      </Suspense>\n    ),\n    errorElement: <Status500 />,\n    needLogin: true,\n    children: [\n      {\n        index: true,\n        element: <InitWorkSpaceLanding />,\n      },\n      {\n        path: \":teamIdentifier\",\n        children: [\n          {\n            index: true,\n            element: <Navigate to=\"./apps\" replace />,\n          },\n          {\n            path: \"apps\",\n            element: <AppWorkSpaceLanding />,\n          },\n          {\n            path: \"resources\",\n            element: <ResourceWorkSpaceLanding />,\n          },\n        ],\n      },\n    ],\n  },\n  {\n    path: \"/setting\",\n    element: <SettingLazyLoad Comp={lazy(() => import(\"@/page/setting\"))} />,\n    errorElement: <Status500 />,\n    needLogin: true,\n    children: [\n      {\n        index: true,\n        element: <SettingLanding />,\n      },\n      {\n        path: \"account\",\n        element: <PersonalSetting />,\n      },\n      {\n        path: \"language\",\n        element: <LanguageSetting />,\n      },\n      {\n        path: \"password\",\n        element: <PasswordSettingPage />,\n      },\n    ] as ILLARoutesObject[],\n  },\n  {\n    path: \"/403\",\n    element: <Status403 />,\n  },\n  {\n    path: \"/404\",\n    element: <Status404 />,\n  },\n  {\n    path: \"/500\",\n    element: <Status500 />,\n  },\n  {\n    path: \"/*\",\n    element: <Status404 />,\n  },\n]\n"
  },
  {
    "path": "apps/cloud/src/services/auth.ts",
    "content": "import {\n  authCloudRequest,\n  notNeedAuthCloudRequest,\n} from \"@illa-public/illa-net\"\nimport { CurrentUserInfo } from \"@illa-public/public-types\"\n\ninterface SignInRequestBody {\n  email: string\n  password: string\n}\nexport const fetchSignIn = (data?: SignInRequestBody) => {\n  return notNeedAuthCloudRequest<CurrentUserInfo>({\n    url: \"/auth/signin\",\n    method: \"POST\",\n    data,\n  })\n}\n\nexport const fetchLogout = async (token: string) => {\n  return await authCloudRequest({\n    method: \"POST\",\n    url: \"/users/logout\",\n    headers: {\n      Authorization: token,\n    },\n  })\n}\n"
  },
  {
    "path": "apps/cloud/src/services/swr/app.ts",
    "content": "import { builderRequest } from \"@illa-public/illa-net\"\nimport { AppInfoShape, ComponentTreeNode } from \"@illa-public/public-types\"\nimport { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { useSelector } from \"react-redux\"\nimport useSWR from \"swr\"\n\nexport const useAppList = (canAccessApps: boolean) => {\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n\n  return useSWR(\n    [\"/apps\", currentTeamInfo?.id, canAccessApps],\n    ([url, teamID]) =>\n      canAccessApps\n        ? builderRequest<AppInfoShape[]>(\n            {\n              url,\n              method: \"GET\",\n            },\n            { teamID },\n          ).then((res) => res.data)\n        : [],\n  )\n}\n\nexport const fetchDeleteApp = (appID: string, teamID: string) => {\n  return builderRequest<{ appID: string }>(\n    {\n      url: `/apps/${appID}`,\n      method: \"DELETE\",\n    },\n    { teamID },\n  )\n}\n\nexport const fetchCopyApp = (appID: string, name: string, teamID: string) => {\n  return builderRequest<AppInfoShape>(\n    {\n      url: `/apps/${appID}/duplication`,\n      method: \"POST\",\n      data: {\n        appName: name,\n      },\n    },\n    {\n      teamID,\n    },\n  ).then((res) => res.data)\n}\n\nexport const fetchUpdateAppConfig = async (\n  appID: string,\n  teamID: string,\n  config: {\n    public?: boolean\n    waterMark?: boolean\n    description?: string\n    appName?: string\n  },\n) => {\n  return builderRequest<AppInfoShape>(\n    {\n      method: \"PATCH\",\n      url: `/apps/${appID}/config`,\n      data: config,\n    },\n    {\n      teamID,\n    },\n  ).then((res) => res.data)\n}\n\ninterface IAppCreateRequestData {\n  appName: string\n  initScheme: ComponentTreeNode\n}\n\nexport const fetchCreateApp = (data: IAppCreateRequestData, teamID: string) => {\n  return builderRequest<AppInfoShape>(\n    {\n      url: \"/apps\",\n      method: \"POST\",\n      data,\n    },\n    { teamID },\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/services/swr/resource.ts",
    "content": "import { builderRequest } from \"@illa-public/illa-net\"\nimport { Resource, ResourceContent } from \"@illa-public/public-types\"\nimport { getCurrentTeamInfo } from \"@illa-public/user-data\"\nimport { useSelector } from \"react-redux\"\nimport useSWR from \"swr\"\n\nexport const useResourceList = (canAccessResourceList: boolean) => {\n  const currentTeamInfo = useSelector(getCurrentTeamInfo)\n\n  return useSWR(\n    [\"/resources\", currentTeamInfo?.id, canAccessResourceList],\n    ([url, teamID]) =>\n      canAccessResourceList\n        ? builderRequest<Resource<ResourceContent>[]>(\n            {\n              url: url,\n              method: \"GET\",\n            },\n            { teamID },\n          ).then((res) => res.data)\n        : [],\n  )\n}\n\nexport const fetchDeleteResource = async (\n  resourceID: string,\n  teamID: string,\n) => {\n  return builderRequest<Resource<ResourceContent>>(\n    {\n      url: `/resources/${resourceID}`,\n      method: \"DELETE\",\n    },\n    {\n      teamID,\n    },\n  )\n}\n"
  },
  {
    "path": "apps/cloud/src/services/team.ts",
    "content": "import { authCloudRequest } from \"@illa-public/illa-net\"\nimport { TeamInfo } from \"@illa-public/public-types\"\n\nexport const fetchCurrentUserTeamsInfo = () => {\n  return authCloudRequest<TeamInfo[]>({\n    url: \"/teams/my\",\n    method: \"GET\",\n  })\n}\n"
  },
  {
    "path": "apps/cloud/src/services/user.ts",
    "content": "import { authCloudRequest } from \"@illa-public/illa-net\"\nimport { CurrentUserInfo } from \"@illa-public/public-types\"\n\ninterface updateUserPasswordRequestData {\n  currentPassword: string\n  newPassword: string\n}\n\nexport const fetchUpdateUserPassword = (\n  data: updateUserPasswordRequestData,\n) => {\n  return authCloudRequest({\n    url: \"/users/password\",\n    method: \"PATCH\",\n    data,\n  })\n}\n\nexport const fetchUpdateUserLanguage = (language: string) => {\n  return authCloudRequest({\n    url: \"/users/language\",\n    method: \"PATCH\",\n    data: {\n      language,\n    },\n  })\n}\n\nexport const fetchUpdateNickName = (nickname: string) => {\n  return authCloudRequest({\n    url: \"/users/nickname\",\n    method: \"PATCH\",\n    data: {\n      nickname,\n    },\n  })\n}\n\nexport const fetchUserInfo = async () => {\n  return await authCloudRequest<CurrentUserInfo>({\n    url: \"/users\",\n    method: \"GET\",\n  })\n}\n\nexport const updateTutorialViewed = async (isTutorialViewed: boolean) => {\n  await authCloudRequest({\n    url: \"/users/tutorialViewed\",\n    method: \"PATCH\",\n    data: {\n      isTutorialViewed,\n    },\n  })\n}\n"
  },
  {
    "path": "apps/cloud/src/store.ts",
    "content": "import { currentUserReducer, teamReducer } from \"@illa-public/user-data\"\nimport { configureStore } from \"@reduxjs/toolkit\"\n\nexport const store = configureStore({\n  reducer: {\n    currentUser: currentUserReducer,\n    team: teamReducer,\n  },\n})\n\nexport type ILLARootState = ReturnType<typeof store.getState>\n"
  },
  {
    "path": "apps/cloud/src/style.ts",
    "content": "import { css } from \"@emotion/react\"\n\nconst FONT_SIZE = (100 / 780) * 100\nexport const MOBILE_MIN_WIDTH = 320\nexport const MOBILE_MAX_WIDTH = 780\n\nexport const globalStyles = css`\n  html {\n    // when vw doesn't work\n    font-size: 41px;\n    // vw works\n    font-size: ${FONT_SIZE}vw;\n    @media screen and (orientation: landscape) {\n      font-size: ${FONT_SIZE}vh;\n    }\n    @media screen and (max-width: 320px) {\n      font-size: 41px;\n    }\n    @media screen and (min-width: 780px) {\n      font-size: 16px;\n    }\n    --dvh: 1dvh;\n    height: 100%;\n  }\n\n  body {\n    min-width: 320px;\n    margin: 0;\n    padding: 0;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n    font-family:\n      Inter,\n      -apple-system,\n      BlinkMacSystemFont,\n      PingFang SC,\n      Microsoft YaHei,\n      Helvetica Neue,\n      Helvetica,\n      Arial,\n      sans-serif;\n    height: 100%;\n  }\n\n  a {\n    color: inherit;\n    text-decoration: none;\n  }\n\n  * {\n    outline: none !important;\n    box-sizing: border-box;\n  }\n  #root {\n    height: 100%;\n  }\n`\n\nexport const rowCenter = css`\n  display: flex;\n  flex-direction: row;\n  justify-content: center;\n  align-items: center;\n`\n\nexport const columnCenter = css`\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n`\n\nexport const pointerStyle = css`\n  cursor: pointer;\n`\n\nexport const messageStyle = css`\n  @media screen and (max-width: ${MOBILE_MAX_WIDTH}px) {\n    border-radius: 16rem;\n  }\n`\n"
  },
  {
    "path": "apps/cloud/src/types/environment.d.ts",
    "content": "declare global {\n  namespace NodeJS {\n    interface ProcessEnv {\n      readonly ILLA_API_BASE_URL: string\n      readonly ILLA_INSTANCE_ID: string\n      readonly ILLA_SENTRY_ENV: string\n      readonly ILLA_SENTRY_SERVER_API: string\n      readonly ILLA_APP_VERSION: string\n      readonly ILLA_APP_ENV: string\n      readonly ILLA_BUILDER_URL: string\n      readonly ILLA_MARKET_URL: string\n      readonly ILLA_CLOUD_URL: string\n      readonly ILLA_INSTANCE_ID: string\n      readonly ILLA_SENTRY_SERVER_API: string\n      readonly ILLA_MIXPANEL_KEY: string\n    }\n  }\n}\n\nexport {}\n"
  },
  {
    "path": "apps/cloud/src/types/global.d.ts",
    "content": "interface Window {\n  customDomain?: string\n}\n"
  },
  {
    "path": "apps/cloud/src/types/react.d.ts",
    "content": "import \"react\"\n\ndeclare module \"react\" {\n  interface InputHTMLAttributes<T> extends HTMLAttributes<T> {\n    webkitdirectory?: string\n  }\n}\n"
  },
  {
    "path": "apps/cloud/src/utils/auth/index.ts",
    "content": "import {\n  ILLAPublicStorage,\n  getAuthToken,\n  getILLACloudURL,\n} from \"@illa-public/utils\"\nimport { fetchLogout } from \"@/services/auth\"\nimport { ILLACloudStorage } from \"@/utils/storage\"\n\nconst CURRENT_TEAM_ID_KEY = \"currentTeamID\"\n\nexport const setLocalCurrentTeamID = (teamID: string) => {\n  ILLACloudStorage.setLocalStorage(CURRENT_TEAM_ID_KEY, teamID)\n}\n\nexport const getLocalCurrentTeamID = () => {\n  return ILLACloudStorage.getLocalStorage(CURRENT_TEAM_ID_KEY)\n}\n\nexport const removeLocalTeam = () => {\n  return ILLACloudStorage.removeLocalStorage(\"teamIdentifier\")\n}\n\nexport const onClickLogout = async () => {\n  const ILLAToken = getAuthToken()\n  ILLAPublicStorage.clearLocalStorage()\n  if (!ILLAToken) {\n    window.location.href = `${getILLACloudURL()}/login`\n    return\n  }\n  try {\n    await fetchLogout(ILLAToken)\n  } catch (e) {\n  } finally {\n    window.location.href = `${getILLACloudURL()}/login`\n  }\n}\n"
  },
  {
    "path": "apps/cloud/src/utils/copy.ts",
    "content": "import { COPY_STATUS, copyToClipboard } from \"@illa-public/utils\"\nimport { createMessage } from \"@illa-design/react\"\nimport i18n from \"../i18n\"\n\nconst message = createMessage()\nexport const copy = (value: string) => {\n  const copyResult = copyToClipboard(value)\n  switch (copyResult) {\n    case COPY_STATUS.EMPTY: {\n      message.warning({\n        content: i18n.t(\"empty_copied_tips\"),\n      })\n\n      break\n    }\n    case COPY_STATUS.SUCCESS: {\n      message.success({\n        content: i18n.t(\"copied\"),\n      })\n      break\n    }\n    default: {\n      message.error({\n        content: i18n.t(\"failed_to_copy\"),\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "apps/cloud/src/utils/dayjs.ts",
    "content": "/* eslint-disable import/no-named-as-default-member */\nimport dayjs from \"dayjs\"\nimport localeData from \"dayjs/plugin/localeData\"\nimport LocalizedFormat from \"dayjs/plugin/localizedFormat\"\nimport relativeTime from \"dayjs/plugin/relativeTime\"\nimport updateLocale from \"dayjs/plugin/updateLocale\"\nimport utc from \"dayjs/plugin/utc\"\nimport i18n, { formatLanguage } from \"@/i18n\"\n\ndayjs.extend(LocalizedFormat)\ndayjs.extend(relativeTime)\ndayjs.extend(utc)\ndayjs.extend(localeData)\ndayjs.extend(updateLocale)\n\nconst PER_SECOND = 1000\nconst PER_MINUTE = PER_SECOND * 60\nconst PER_HOUR = PER_MINUTE * 60\nconst PER_DAY = PER_HOUR * 24\n\nasync function initDayjs() {\n  const local = localStorage.getItem(\"i18nextLng\") || \"en-US\"\n  const language = formatLanguage(local)\n  switch (language) {\n    case \"zh-CN\":\n      await import(\"dayjs/locale/zh-cn\")\n      dayjs.locale(\"zh-cn\")\n      break\n    case \"en-US\":\n    default:\n      await import(\"dayjs/locale/en\")\n      dayjs.locale(\"en-us\")\n      break\n  }\n}\n\ninitDayjs()\n\nexport const fromNow = (date: string) => {\n  if (!date) return \"\"\n  const now = dayjs()\n  const diff = now.diff(date)\n  const { t } = i18n\n  if (diff / PER_MINUTE < 1) {\n    return t(\"homepage.builder_card.edited_justnow\")\n  }\n  if (diff / PER_MINUTE === 1) {\n    return t(\"homepage.builder_card.edited_1min\")\n  }\n  if (diff / PER_MINUTE <= 60) {\n    return t(\"homepage.builder_card.edited_mins\", {\n      n: Math.floor(diff / PER_MINUTE),\n    })\n  }\n  if (diff / PER_HOUR === 1) {\n    return t(\"homepage.builder_card.edited_1hour\")\n  }\n  if (diff / PER_HOUR <= 24) {\n    return t(\"homepage.builder_card.edited_hours\", {\n      n: Math.floor(diff / PER_HOUR),\n    })\n  }\n  if (diff / PER_DAY === 1) {\n    return t(\"homepage.builder_card.edited_1day\")\n  }\n  if (diff / PER_DAY > 1) {\n    return t(\"homepage.builder_card.edited_days\", {\n      n: Math.floor(diff / PER_DAY),\n    })\n  }\n\n  return \"\"\n}\n"
  },
  {
    "path": "apps/cloud/src/utils/storage/index.ts",
    "content": "import ILLAStorage from \"@illa-public/illa-storage\"\n\nexport const ILLACloudStorage = new ILLAStorage(\"ILLACloud@0.0.0\", 5)\n"
  },
  {
    "path": "apps/cloud/src/vite-env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n\ninterface ImportMetaEnv {\n  readonly ILLA_API_BASE_URL: string\n  readonly ILLA_BUILDER_URL: string\n  readonly ILLA_MARKET_URL: string\n  readonly ILLA_CLOUD_URL: string\n  readonly ILLA_INSTANCE_ID: string\n  readonly ILLA_SENTRY_SERVER_API: string\n  readonly ILLA_MIXPANEL_KEY: string\n  readonly ILLA_APP_ENV: string\n  readonly ILLA_APP_VERSION: string\n}\n\ninterface ImportMeta {\n  readonly env: ImportMetaEnv\n}\n"
  },
  {
    "path": "apps/cloud/tsconfig.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/tsconfig\",\n  \"extends\": \"tsconfig/react.json\",\n  \"compilerOptions\": {\n    \"baseUrl\": \"./src\",\n    \"paths\": {\n      \"@/*\": [\"./*\"],\n      \"@assets/*\": [\"./src/assets/*\"]\n    },\n    \"types\": [\n      \"vite/client\",\n      \"vite-plugin-svgr/client\",\n      \"node\",\n      \"@illa-design/table/src/react-table.d.ts\",\n      \"@types/gtag.js\"\n    ]\n  },\n  \"include\": [\n    \"./src/**/*.tsx\",\n    \"./src/**/*.ts\",\n    \"./src/assets/animationForLottie/*.json\"\n  ],\n  \"references\": [\n    {\n      \"path\": \"./tsconfig.node.json\"\n    }\n  ]\n}\n"
  },
  {
    "path": "apps/cloud/tsconfig.node.json",
    "content": "{\n  \"compilerOptions\": {\n    \"composite\": true,\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Node\",\n    \"allowSyntheticDefaultImports\": true,\n    \"resolveJsonModule\": true\n  },\n  \"include\": [\"vite.config.ts\", \"package.json\"]\n}\n"
  },
  {
    "path": "apps/cloud/vite.config.ts",
    "content": "import basicSsl from \"@vitejs/plugin-basic-ssl\"\nimport react from \"@vitejs/plugin-react-swc\"\nimport { resolve } from \"path\"\nimport copy from \"rollup-plugin-copy\"\nimport { visualizer } from \"rollup-plugin-visualizer\"\nimport { PluginOption, defineConfig, loadEnv } from \"vite\"\nimport { checker } from \"vite-plugin-checker\"\nimport svgr from \"vite-plugin-svgr\"\nimport packageConfig from \"./package.json\"\n\nconst I18N_SOURCE_PATH = resolve(\n  __dirname,\n  \"../../packages/illa-public-component\",\n  \"locales/*.json\",\n)\nconst I18N_TARGET_PATH = resolve(__dirname, \"public/locales\")\n\nconst getUsedEnv = (env: Record<string, string>) => {\n  const usedEnv: Record<string, string> = {}\n  Object.keys(env).forEach((key) => {\n    if (key.startsWith(\"ILLA_\")) {\n      let value = env[key]\n      usedEnv[`import.meta.env.${key}`] = JSON.stringify(value)\n      usedEnv[`process.env.${key}`] = JSON.stringify(value)\n    }\n  })\n  usedEnv[`import.meta.env.ILLA_APP_VERSION`] = JSON.stringify(\n    packageConfig.version,\n  )\n  usedEnv[`process.env.ILLA_APP_VERSION`] = JSON.stringify(\n    packageConfig.version,\n  )\n  return usedEnv\n}\n\nconst VITE_PLUGINS = [\n  copy({\n    targets: [\n      {\n        src: [I18N_SOURCE_PATH, \"!**/package.json\"],\n        dest: I18N_TARGET_PATH,\n      },\n    ],\n    hook: \"buildStart\",\n  }),\n  react({\n    jsxImportSource: \"@emotion/react\",\n  }),\n  svgr(),\n  checker({\n    typescript: true,\n    eslint: {\n      lintCommand: 'eslint \"./src/**/**.{ts,tsx}\" --config \".eslintrc.cjs\"',\n      dev: {\n        logLevel: [\"error\", \"warning\"],\n      },\n    },\n  }),\n  visualizer() as unknown as PluginOption,\n]\n\n// https://vitejs.dev/config/\nexport default defineConfig(async (configEnv) => {\n  const { command } = configEnv\n  const env = loadEnv(configEnv.mode, process.cwd(), \"\")\n  const useHttps = env.ILLA_USE_HTTPS === \"true\"\n  const isBuildSelfHost =\n    env.ILLA_INSTANCE_ID === \"SELF_HOST_CLOUD\" && command === \"build\"\n  if (useHttps && command === \"serve\") {\n    VITE_PLUGINS.push(basicSsl())\n  }\n  return {\n    base: isBuildSelfHost ? \"/cloud\" : \"/\",\n    plugins: VITE_PLUGINS,\n    resolve: {\n      alias: {\n        \"@\": resolve(__dirname, \"src\"),\n      },\n    },\n    envPrefix: [\"ILLA_\"],\n    define: getUsedEnv(env),\n    build: {\n      sourcemap: true,\n      reportCompressedSize: false,\n      rollupOptions: {\n        output: {\n          manualChunks: {\n            react: [\"react\", \"react-dom\", \"react-router-dom\"],\n            \"@emotion\": [\"@emotion/react\"],\n            \"@illa-design\": [\"@illa-design/react\"],\n            \"lodash-lib\": [\"lodash-es\"],\n          },\n        },\n      },\n    },\n    server: {\n      https: useHttps,\n    },\n  }\n})\n"
  },
  {
    "path": "apps/playwright/.gitignore",
    "content": "node_modules/\n/test-results/\n/playwright-report/\n/playwright/.cache/\n/test-results/\n/playwright-report/\n/playwright/.cache/\n.env.local\n.env.*.local\n/.auth"
  },
  {
    "path": "apps/playwright/package.json",
    "content": "{\n  \"name\": \"playwright\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"playwright test\",\n    \"test:development\": \"cross-env ILLA_APP_ENV=development playwright test\",\n    \"test:auth\": \"cross-env ILLA_APP_ENV=development playwright test auth.setup.ts\",\n    \"codegen\": \"node ./script/codeGen.js\",\n    \"init:env\": \"node ./script/initEnv.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"@illa-public/illa-net\": \"workspace:*\"\n  },\n  \"devDependencies\": {\n    \"@playwright/test\": \"^1.38.1\",\n    \"@types/node\": \"^18.14.4\",\n    \"cross-env\": \"^7.0.3\",\n    \"dotenv\": \"^16.3.1\"\n  }\n}\n"
  },
  {
    "path": "apps/playwright/playwright.config.ts",
    "content": "import { defineConfig, devices } from \"@playwright/test\"\nimport * as dotenv from \"dotenv\"\n\nconst modeExt = process.env.ILLA_APP_ENV || \"development\"\ndotenv.config({ path: \".env\" })\ndotenv.config({ path: \".env.local\", override: true })\ndotenv.config({ path: `.env.${modeExt}.local`, override: true })\n\n/**\n * Read environment variables from file.\n * https://github.com/motdotla/dotenv\n */\n// require('dotenv').config();\n\n/**\n * See https://playwright.dev/docs/test-configuration.\n */\nexport default defineConfig({\n  testDir: \"./tests\",\n  /* Run tests in files in parallel */\n  fullyParallel: true,\n  /* Fail the build on CI if you accidentally left test.only in the source code. */\n  forbidOnly: !!process.env.CI,\n  /* Retry on CI only */\n  retries: process.env.CI ? 2 : 0,\n  /* Opt out of parallel tests on CI. */\n  workers: process.env.CI ? 1 : undefined,\n  /* Reporter to use. See https://playwright.dev/docs/test-reporters */\n  reporter: \"html\",\n  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */\n  use: {\n    /* Base URL to use in actions like `await page.goto('/')`. */\n    baseURL: process.env.ILLA_BUILDER_URL,\n\n    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */\n    trace: \"on-first-retry\",\n  },\n\n  /* Configure projects for major browsers */\n  projects: [\n    {\n      name: \"setup\",\n      testMatch: /.*\\.setup\\.ts/,\n      use: {\n        contextOptions: {\n          ignoreHTTPSErrors: true,\n        },\n      },\n    },\n    {\n      name: \"chromium\",\n      use: {\n        ...devices[\"Desktop Chrome\"],\n        storageState: \".auth/user.json\",\n        contextOptions: {\n          ignoreHTTPSErrors: true,\n        },\n      },\n      dependencies: [\"setup\"],\n    },\n  ],\n})\n"
  },
  {
    "path": "apps/playwright/script/codeGen.js",
    "content": "const path = require(\"path\")\nconst childProcess = require(\"child_process\");\nconst dotenv = require(\"dotenv\")\n\n\nconst ENV_LOCAL_FILE_PATH = path.resolve(__dirname, \"..\", \".env.local\")\nconst ENV_DEV_LOCAL_FILE_PATH = path.resolve(__dirname, \"..\", \".env.development.local\")\n\ndotenv.config({ path: ENV_LOCAL_FILE_PATH, override: true })\ndotenv.config({ path: ENV_DEV_LOCAL_FILE_PATH, override: true })\n\n\nchildProcess.execSync(`pnpm playwright codegen  ${process.env.ILLA_BUILDER_URL}/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps --load-storage=.auth/user.json --ignore-https-errors`)"
  },
  {
    "path": "apps/playwright/script/initEnv.js",
    "content": "const fs = require(\"fs\")\nconst path = require(\"path\")\nconst dotenv = require(\"dotenv\")\n\nconst ENV_PREFIX = \"ILLA_\"\n\nconst ENV_LOCAL_FILE_PATH = path.resolve(__dirname, \"..\", \".env.local\")\nconst ENV_DEV_LOCAL_FILE_PATH = path.resolve(__dirname, \"..\", \".env.development.local\")\n\ndotenv.config({ path: ENV_LOCAL_FILE_PATH, override: true })\ndotenv.config({ path: ENV_DEV_LOCAL_FILE_PATH, override: true })\n\nfetch(\"https://vnfxllrjvmzlialmdqrd.supabase.co/rest/v1/CI_INFO?select=*\", {\n  headers: {\n    apikey: process.env.ILLA_SUPABASE_KEY,\n    Authorization: `Bearer ${process.env.ILLA_SUPABASE_KEY}`\n  }\n}).then(res => res.json()).then(res => {\n  const envInfo = res[0].resource\n  let writeContent = \"\"\n  Object.keys(envInfo).forEach(resourceType => {\n    const resourceInfo = envInfo[resourceType]\n    Object.keys(resourceInfo).forEach(resourceKey => {\n      const resourcePrefix = resourceType.toUpperCase()\n      const envKey = `${ENV_PREFIX}${resourcePrefix}_${resourceKey.toUpperCase()}`\n      const envValue = resourceInfo[resourceKey]\n      if ((typeof envValue === \"string\" || typeof envValue === \"number\") && resourceKey !== \"resourceType\")\n        writeContent += `${envKey}=${envValue}\\n`\n    })\n  })\n  fs.writeFileSync(ENV_LOCAL_FILE_PATH, writeContent)\n})"
  },
  {
    "path": "apps/playwright/tests/Resources/SMTP.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"SMTP create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"SmtpIconSMTP\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByPlaceholder(\"Hostname\").click()\n    await page.getByPlaceholder(\"Hostname\").fill(process.env.ILLA_SMTP_HOST)\n    await page.getByPlaceholder(\"Username\").click()\n    await page.getByPlaceholder(\"Username\").fill(process.env.ILLA_SMTP_USERNAME)\n    await page.getByPlaceholder(\"Password\").click()\n    await page.getByPlaceholder(\"Password\").fill(process.env.ILLA_SMTP_PASSWORD)\n    await page.getByPlaceholder(\"25\").click()\n    await page.getByPlaceholder(\"25\").fill(process.env.ILLA_SMTP_PORT)\n    await page.getByText(\"PreviousIconBackTest ConnectionSave Resource\").click()\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/appwrite.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"Appwrite create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"AppwriteIconAppwrite\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByPlaceholder(\"HOSTNAME OR IP\").click()\n    await page\n      .getByPlaceholder(\"HOSTNAME OR IP\")\n      .fill(process.env.ILLA_APPWRITE_HOST)\n    await page.getByPlaceholder(\"Database ID\").click()\n    await page\n      .getByPlaceholder(\"Database ID\")\n      .fill(process.env.ILLA_APPWRITE_DATABASEID)\n    await page.getByPlaceholder(\"Project ID\").click()\n    await page\n      .getByPlaceholder(\"Project ID\")\n      .fill(process.env.ILLA_APPWRITE_PROJECTID)\n    await page.getByPlaceholder(\"••••••••••••••••••••\").click()\n    await page\n      .getByPlaceholder(\"••••••••••••••••••••\")\n      .fill(process.env.ILLA_APPWRITE_APIKEY)\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/couchDB.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"CouchDB create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"CouchDBIconCouchDB\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByRole(\"textbox\").nth(1).click()\n    await page.getByRole(\"textbox\").nth(1).fill(process.env.ILLA_COUCHDB_HOST)\n    await page.getByPlaceholder(\"5984\").click()\n    await page.getByPlaceholder(\"5984\").fill(process.env.ILLA_COUCHDB_PORT)\n    await page.getByRole(\"textbox\").nth(3).click()\n    await page\n      .getByRole(\"textbox\")\n      .nth(3)\n      .fill(process.env.ILLA_COUCHDB_USERNAME)\n    await page.locator('input[type=\"password\"]').click()\n    await page\n      .locator('input[type=\"password\"]')\n      .fill(process.env.ILLA_COUCHDB_PASSWORD)\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/elasticSearch.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"ElasticSearch create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"ElasticIconElastic Search\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByRole(\"textbox\").nth(1).click()\n    await page\n      .getByRole(\"textbox\")\n      .nth(1)\n      .fill(process.env.ILLA_ELASTICSEARCH_HOST)\n    await page\n      .locator(\"div\")\n      .filter({ hasText: /^\\*PortUpIconDownIcon$/ })\n      .getByRole(\"textbox\")\n      .click()\n    await page\n      .locator(\"div\")\n      .filter({ hasText: /^\\*PortUpIconDownIcon$/ })\n      .getByRole(\"textbox\")\n      .fill(process.env.ILLA_ELASTICSEARCH_PORT)\n    await page.getByRole(\"textbox\").nth(3).click()\n    await page\n      .getByRole(\"textbox\")\n      .nth(3)\n      .fill(process.env.ILLA_ELASTICSEARCH_USERNAME)\n    await page.locator('input[type=\"password\"]').click()\n    await page\n      .locator('input[type=\"password\"]')\n      .fill(process.env.ILLA_ELASTICSEARCH_PASSWORD)\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/firebase.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"FireBase create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"FirebaseIconFirebase\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByRole(\"textbox\").nth(1).click()\n    await page\n      .getByRole(\"textbox\")\n      .nth(1)\n      .fill(process.env.ILLA_FIREBASE_DATABASEURL)\n    await page.getByRole(\"textbox\").nth(2).click()\n    await page\n      .getByRole(\"textbox\")\n      .nth(2)\n      .fill(process.env.ILLA_FIREBASE_PROJECTID)\n    await page\n      .getByPlaceholder(\n        '{\\n  \"type\": \"service_account\",\\n  \"project_id\": \"projectId\",\\n  \"private_key_id\": \"privateKeyId\",\\n  \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nprivateKey\\n-----END PRIVATE KEY-----\",\\n  \"client_email\": \"clientEmail\",\\n  \"client_id\": \"100000000000000000000\",\\n  \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\\n  \"token_uri\": \"https://oauth2.googleapis.com/token\",\\n  \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",\\n  \"client_x509_cert_url\": \"clientx509CertUrl\"\\n}',\n      )\n      .click()\n    await page\n      .getByPlaceholder(\n        '{\\n  \"type\": \"service_account\",\\n  \"project_id\": \"projectId\",\\n  \"private_key_id\": \"privateKeyId\",\\n  \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nprivateKey\\n-----END PRIVATE KEY-----\",\\n  \"client_email\": \"clientEmail\",\\n  \"client_id\": \"100000000000000000000\",\\n  \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\\n  \"token_uri\": \"https://oauth2.googleapis.com/token\",\\n  \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",\\n  \"client_x509_cert_url\": \"clientx509CertUrl\"\\n}',\n      )\n      .fill(process.env.ILLA_FIREBASE_PRIVATEKEY)\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/googleSheets.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"GoogleSheets create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"GoogleSheetIconGoogle Sheets\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page\n      .getByPlaceholder(\n        '{\\r\\n  \"type\": \"service_account\",\\r\\n  \"project_id\": \"projectId\",\\r\\n  \"private_key_id\": \"privateKeyId\",\\r\\n  \"private_key\": \"-----BEGIN PRIVATE KEY-----\\r\\nprivateKey\\r\\n-----END PRIVATE KEY-----\",\\r\\n  \"client_email\": \"clientEmail\",\\r\\n  \"client_id\": \"100000000000000000000\",\\r\\n  \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\\r\\n  \"token_uri\": \"https://oauth2.googleapis.com/token\",\\r\\n  \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",\\r\\n  \"client_x509_cert_url\": \"clientx509CertUrl\"\\r\\n}',\n      )\n      .click()\n    await page\n      .getByPlaceholder(\n        '{\\r\\n  \"type\": \"service_account\",\\r\\n  \"project_id\": \"projectId\",\\r\\n  \"private_key_id\": \"privateKeyId\",\\r\\n  \"private_key\": \"-----BEGIN PRIVATE KEY-----\\r\\nprivateKey\\r\\n-----END PRIVATE KEY-----\",\\r\\n  \"client_email\": \"clientEmail\",\\r\\n  \"client_id\": \"100000000000000000000\",\\r\\n  \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\\r\\n  \"token_uri\": \"https://oauth2.googleapis.com/token\",\\r\\n  \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",\\r\\n  \"client_x509_cert_url\": \"clientx509CertUrl\"\\r\\n}',\n      )\n      .fill(process.env.ILLA_GOOGLESHEETS_PRIVATEKEY)\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/huggingFaceAPI.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"HuggingFaceAPI create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"HuggingFaceIconHugging FaceInference API\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.locator('input[type=\"password\"]').click()\n    await page\n      .locator('input[type=\"password\"]')\n      .fill(process.env.ILLA_HUGGINGFACE_TOKEN)\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/mariaDB.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"MariaDB create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"MariaDbIconMariaDB\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByPlaceholder(\"Hostname\").click()\n    await page.getByPlaceholder(\"Hostname\").fill(process.env.ILLA_MARIADB_HOST)\n    await page.getByPlaceholder(\"3306\").click()\n    await page.getByPlaceholder(\"3306\").fill(process.env.ILLA_MARIADB_PORT)\n    await page.getByPlaceholder(\"acme_production\").click()\n    await page\n      .getByPlaceholder(\"acme_production\")\n      .fill(process.env.ILLA_MARIADB_DATABASENAME)\n    await page.getByPlaceholder(\"Password\").click()\n    await page\n      .getByPlaceholder(\"Password\")\n      .fill(process.env.ILLA_MARIADB_DATABASEPASSWORD)\n    await page.getByPlaceholder(\"Username\").click()\n    await page\n      .getByPlaceholder(\"Username\")\n      .fill(process.env.ILLA_MARIADB_DATABASEUSERNAME)\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/microsoftSQL.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"MicrosoftSQL create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"MicrosoftSqlIconMicrosoft SQL\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByPlaceholder(\"Hostname\").click()\n    await page.getByPlaceholder(\"Hostname\").fill(process.env.ILLA_MSSQL_HOST)\n    await page.getByPlaceholder(\"1433\").click()\n    await page.getByPlaceholder(\"1433\").fill(process.env.ILLA_MSSQL_PORT)\n    await page.getByPlaceholder(\"Password\").click()\n    await page\n      .getByPlaceholder(\"Password\")\n      .fill(process.env.ILLA_MSSQL_PASSWORD)\n    await page.getByPlaceholder(\"Username\").click()\n    await page\n      .getByPlaceholder(\"Username\")\n      .fill(process.env.ILLA_MSSQL_USERNAME)\n    await page.getByPlaceholder(\"Database name\").click()\n    await page\n      .getByPlaceholder(\"Database name\")\n      .fill(process.env.ILLA_MSSQL_DATABASENAME)\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/mysql.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"MySQL create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"MySqlIconMySQL\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test mysql\")\n    await page.getByPlaceholder(\"Hostname\").click()\n    await page.getByPlaceholder(\"Hostname\").fill(process.env.ILLA_MYSQL_HOST)\n    await page.getByPlaceholder(\"3306\").click()\n    await page.getByPlaceholder(\"3306\").fill(process.env.ILLA_MYSQL_PORT)\n    await page.getByPlaceholder(\"acme_production\").click()\n    await page\n      .getByPlaceholder(\"acme_production\")\n      .fill(process.env.ILLA_MYSQL_DATABASENAME)\n    await page.getByPlaceholder(\"Username\").click()\n    await page\n      .getByPlaceholder(\"Username\")\n      .fill(process.env.ILLA_MYSQL_DATABASEUSERNAME)\n    await page.getByPlaceholder(\"Password\").click()\n    await page\n      .getByPlaceholder(\"Password\")\n      .fill(process.env.ILLA_MYSQL_DATABASEPASSWORD)\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/neon.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"Neon create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"NeonIconNeon\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByPlaceholder(\"Hostname\").click()\n    await page.getByPlaceholder(\"Hostname\").fill(process.env.ILLA_NEON_HOST)\n    await page.getByPlaceholder(\"acme_production\").click()\n    await page\n      .getByPlaceholder(\"acme_production\")\n      .fill(process.env.ILLA_NEON_DATABASENAME)\n    await page.getByPlaceholder(\"Username\").click()\n    await page\n      .getByPlaceholder(\"Username\")\n      .fill(process.env.ILLA_NEON_DATABASEUSERNAME)\n    await page.getByPlaceholder(\"Password\").click()\n    await page\n      .getByPlaceholder(\"Password\")\n      .fill(process.env.ILLA_NEON_DATABASEPASSWORD)\n    await page\n      .locator(\"div\")\n      .filter({ hasText: /^\\*Hostname\\/PortUpIconDownIcon$/ })\n      .getByRole(\"textbox\")\n      .nth(1)\n      .fill(\"5432\")\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/oracleDB.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"OracleDB create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"OracleDBIconOracle DB\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByPlaceholder(\"Hostname\").click()\n    await page.getByPlaceholder(\"Hostname\").fill(process.env.ILLA_ORACLE_HOST)\n    await page.getByPlaceholder(\"1521\").click()\n    await page.getByPlaceholder(\"1521\").fill(process.env.ILLA_ORACLE_PORT)\n    await page.locator(\"label\").filter({ hasText: \"SID\" }).click()\n    await page.getByPlaceholder(\"oracle\").click()\n    await page.getByPlaceholder(\"oracle\").fill(process.env.ILLA_ORACLE_USERNAME)\n    await page.getByPlaceholder(\"••••••••\").click()\n    await page\n      .getByPlaceholder(\"••••••••\")\n      .fill(process.env.ILLA_ORACLE_PASSWORD)\n    await page.getByPlaceholder(\"default\").click()\n    await page.getByPlaceholder(\"default\").fill(process.env.ILLA_ORACLE_NAME)\n    await page\n      .locator(\"div\")\n      .filter({ hasText: /^Use SSL when available$/ })\n      .getByRole(\"button\")\n      .click()\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/postgreSQL.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"PostgreSQL create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"PostgreSqlIconPostgreSQL\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test12345\")\n    await page\n      .getByPlaceholder(\"Hostname\")\n      .fill(process.env.ILLA_POSTGRESQL_HOST!)\n    await page.getByPlaceholder(\"5432\").fill(process.env.ILLA_POSTGRESQL_PORT)\n    await page\n      .getByPlaceholder(\"acme_production\")\n      .fill(process.env.ILLA_POSTGRESQL_DATABASENAME)\n    await page\n      .getByPlaceholder(\"Username\")\n      .fill(process.env.ILLA_POSTGRESQL_DATABASEUSERNAME)\n    await page\n      .getByPlaceholder(\"Password\")\n      .fill(process.env.ILLA_POSTGRESQL_DATABASEPASSWORD)\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/redis.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"Redis create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"RedisIconRedis\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByPlaceholder(\"Hostname\").click()\n    await page.getByPlaceholder(\"Hostname\").fill(process.env.ILLA_REDIS_HOST)\n    await page.getByPlaceholder(\"6379\").click()\n    await page.getByPlaceholder(\"6379\").fill(process.env.ILLA_REDIS_PORT)\n    await page.getByPlaceholder(\"Username\").click()\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/restAPI.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"RestAPI create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"RestApiIconREST API\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page\n      .getByPlaceholder(\"Use the absolute URL (e.g https://example.com)\")\n      .click()\n    await page\n      .getByPlaceholder(\"Use the absolute URL (e.g https://example.com)\")\n      .fill(\"https://randomuser.me/api\")\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/supabaseDB.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"SupabaseDB create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"PostgreSqlIconPostgreSQL\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test12345\")\n    await page\n      .getByPlaceholder(\"Hostname\")\n      .fill(process.env.ILLA_POSTGRESQL_HOST!)\n    await page.getByPlaceholder(\"5432\").fill(process.env.ILLA_POSTGRESQL_PORT!)\n    await page\n      .getByPlaceholder(\"acme_production\")\n      .fill(process.env.ILLA_POSTGRESQL_DATABASENAME!)\n    await page\n      .getByPlaceholder(\"Username\")\n      .fill(process.env.ILLA_POSTGRESQL_DATABASEUSERNAME!)\n    await page\n      .getByPlaceholder(\"Password\")\n      .fill(process.env.ILLA_POSTGRESQL_DATABASEPASSWORD!)\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/Resources/tiDB.test.ts",
    "content": "import { test } from \"@playwright/test\"\n\ntest.describe(\"TiDB create And delete\", () => {\n  test.beforeEach(\"Show create Modal\", async ({ page }) => {\n    await page.goto(`/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps`)\n    await page.getByText(\"Resources\").click()\n    await page.getByRole(\"button\", { name: \"Create New\" }).click()\n  })\n\n  test(\"create Resource\", async ({ page }) => {\n    await page.getByText(\"TidbIconTiDB\").click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .click()\n    await page\n      .getByPlaceholder('i.e.\"Users DB(readonly)\" or \"Internal Admin API\"')\n      .fill(\"test\")\n    await page.getByPlaceholder(\"Hostname\").click()\n    await page.getByPlaceholder(\"Hostname\").fill(process.env.ILLA_TIDB_HOST)\n    await page.getByPlaceholder(\"4000\").click()\n    await page.getByPlaceholder(\"4000\").fill(process.env.ILLA_TIDB_PORT)\n    await page.getByPlaceholder(\"acme_production\").click()\n    await page\n      .getByPlaceholder(\"acme_production\")\n      .fill(process.env.ILLA_TIDB_DATABASENAME)\n    await page.getByPlaceholder(\"Password\").click()\n    await page\n      .getByPlaceholder(\"Password\")\n      .fill(process.env.ILLA_TIDB_DATABASEPASSWORD)\n    await page.getByPlaceholder(\"Username\").click()\n    await page\n      .getByPlaceholder(\"Username\")\n      .fill(process.env.ILLA_TIDB_DATABASEUSERNAME)\n    await page.getByRole(\"button\", { name: \"Test Connection\" }).click()\n    await page.getByText(\"SuccessCircleIconTest successfully\").click()\n    await page.getByRole(\"button\", { name: \"Save Resource\" }).click()\n    await page.getByText(\"SuccessCircleIconSave successfully\").click()\n  })\n\n  test.afterEach(\"Close Modal\", async ({ page }) => {\n    await page.getByRole(\"button\", { name: \"MoreIcon\" }).first().click()\n    await page.getByText(\"Delete\").click()\n    await page.getByRole(\"button\", { name: \"Delete\" }).click()\n    await page.getByText(\"SuccessCircleIconDeleted successfully\").click()\n  })\n})\n"
  },
  {
    "path": "apps/playwright/tests/auth.setup.ts",
    "content": "import { notNeedAuthCloudRequest } from \"@illa-public/illa-net\"\nimport { test as setup } from \"@playwright/test\"\n\nconst authFile = \".auth/user.json\"\n\nsetup(\"authenticate\", async ({ page }) => {\n  const result = await notNeedAuthCloudRequest({\n    method: \"POST\",\n    url: \"/auth/signin\",\n    data: {\n      email: process.env.ILLA_CLOUD_USER_EMAIL,\n      password: process.env.ILLA_CLOUD_USER_PASSWORD,\n    },\n  })\n  const token = result.headers[\"illa-token\"]\n  await page.goto(\n    `/${process.env.ILLA_CLOUD_TEAM_IDENTITY}/dashboard/apps?token=${token}`,\n  )\n  await page.context().storageState({ path: authFile })\n})\n"
  },
  {
    "path": "apps/playwright/tests/env.d.ts",
    "content": "declare namespace NodeJS {\n  interface ProcessEnv {\n    readonly ILLA_API_BASE_URL: string\n    readonly ILLA_BUILDER_URL: string\n    readonly ILLA_CLOUD_URL: string\n    readonly ILLA_MARKET_URL: string\n    readonly ILLA_INSTANCE_ID: string\n    readonly ILLA_APP_VERSION: string\n    readonly ILLA_APP_ENV: string\n    readonly ILLA_CLOUD_USER_EMAIL: string\n    readonly ILLA_CLOUD_USER_PASSWORD: string\n    readonly ILLA_CLOUD_TEAM_IDENTITY: string\n    readonly ILLA_SUPABASE_KEY: string\n    readonly ILLA_S3_ACL: string\n    readonly ILLA_S3_REGION: string\n    readonly ILLA_S3_BASEURL: string\n    readonly ILLA_S3_BUCKETNAME: string\n    readonly ILLA_S3_ACCESSKEYID: string\n    readonly ILLA_S3_SECRETACCESSKEY: string\n    readonly ILLA_NEON_HOST: string\n    readonly ILLA_NEON_PORT: string\n    readonly ILLA_NEON_DATABASENAME: string\n    readonly ILLA_NEON_DATABASEPASSWORD: string\n    readonly ILLA_NEON_DATABASEUSERNAME: string\n    readonly ILLA_SMTP_HOST: string\n    readonly ILLA_SMTP_PASSWORD: string\n    readonly ILLA_SMTP_USERNAME: string\n    readonly ILLA_SMTP_PORT: string\n    readonly ILLA_TIDB_HOST: string\n    readonly ILLA_TIDB_PORT: string\n    readonly ILLA_TIDB_DATABASENAME: string\n    readonly ILLA_TIDB_DATABASEPASSWORD: string\n    readonly ILLA_TIDB_DATABASEUSERNAME: string\n    readonly ILLA_MSSQL_HOST: string\n    readonly ILLA_MSSQL_PORT: string\n    readonly ILLA_MSSQL_PASSWORD: string\n    readonly ILLA_MSSQL_USERNAME: string\n    readonly ILLA_MSSQL_DATABASENAME: string\n    readonly ILLA_MYSQL_HOST: string\n    readonly ILLA_MYSQL_PORT: string\n    readonly ILLA_MYSQL_DATABASENAME: string\n    readonly ILLA_MYSQL_DATABASEPASSWORD: string\n    readonly ILLA_MYSQL_DATABASEUSERNAME: string\n    readonly ILLA_REDIS_HOST: string\n    readonly ILLA_REDIS_PORT: string\n    readonly ILLA_REDIS_DATABASEPASSWORD: string\n    readonly ILLA_REDIS_DATABASEUSERNAME: string\n    readonly ILLA_ORACLE_HOST: string\n    readonly ILLA_ORACLE_NAME: string\n    readonly ILLA_ORACLE_PORT: string\n    readonly ILLA_ORACLE_PASSWORD: string\n    readonly ILLA_ORACLE_USERNAME: string\n    readonly ILLA_ORACLE_CONNECTIONTYPE: string\n    readonly ILLA_COUCHDB_HOST: string\n    readonly ILLA_COUCHDB_PORT: string\n    readonly ILLA_COUCHDB_PASSWORD: string\n    readonly ILLA_COUCHDB_USERNAME: string\n    readonly ILLA_MARIADB_HOST: string\n    readonly ILLA_MARIADB_PORT: string\n    readonly ILLA_MARIADB_DATABASENAME: string\n    readonly ILLA_MARIADB_DATABASEPASSWORD: string\n    readonly ILLA_MARIADB_DATABASEUSERNAME: string\n    readonly ILLA_RESTAPI_BASEURL: string\n    readonly ILLA_RESTAPI_AUTHENTICATION: string\n    readonly ILLA_APPWRITE_HOST: string\n    readonly ILLA_APPWRITE_APIKEY: string\n    readonly ILLA_APPWRITE_PROJECTID: string\n    readonly ILLA_APPWRITE_DATABASEID: string\n    readonly ILLA_FIREBASE_PROJECTID: string\n    readonly ILLA_FIREBASE_DATABASEURL: string\n    readonly ILLA_FIREBASE_PRIVATEKEY: string\n    readonly ILLA_POSTGRESQL_HOST: string\n    readonly ILLA_POSTGRESQL_PORT: string\n    readonly ILLA_POSTGRESQL_DATABASENAME: string\n    readonly ILLA_POSTGRESQL_DATABASEPASSWORD: string\n    readonly ILLA_POSTGRESQL_DATABASEUSERNAME: string\n    readonly ILLA_HUGGINGFACE_TOKEN: string\n    readonly ILLA_GOOGLESHEETS_AUTHENTICATION: string\n    readonly ILLA_GOOGLESHEETS_PRIVATEKEY: string\n    readonly ILLA_ELASTICSEARCH_HOST: string\n    readonly ILLA_ELASTICSEARCH_PORT: string\n    readonly ILLA_ELASTICSEARCH_PASSWORD: string\n    readonly ILLA_ELASTICSEARCH_USERNAME: string\n  }\n}\n"
  },
  {
    "path": "commitlint.config.js",
    "content": "module.exports = { extends: ['@commitlint/config-conventional'] };\n"
  },
  {
    "path": "crowdin.yml",
    "content": "pull_request_title: \"[ci skip] New Crowdin translations\"\ncommit_message: \"[ci skip]\"\nfiles:\n  - source: /apps/builder/src/i18n/locale/en-US.json\n    translation: /apps/builder/src/i18n/locale/%locale%.json\n"
  },
  {
    "path": "fluid-config.yaml",
    "content": "# Description:\n#   Pick a name you like, normally the name of the repository.\n# Example:\nnamespace: OWASP\n\n# Description:\n#   Omit if you want pretty-printed results,\n#   Set to a path if you want CSV results.\n# Optional:\n#   Yes\n# Example:\noutput:\n  file_path: ./Fluid-Attacks-Results.csv\n  format: CSV\n\n# Description:\n#   Working directory, normally used as the path to the repository.\n# Example:\nworking_dir: .\n\n# Description:\n#   SAST for source code.\n# Example:\npath:\n  # Description:\n  #   Target files used in the analysis.\n  # Example:\n  include:\n    # Absolute path\n    - .\n    # Relative path to `working_dir`\n    - .\n\n# Description:\n#  Reversing checks for Android APKs.\n# apk:\n  # Description:\n  #   Target files used in the analysis.\n  # Example:\n  # include:\n    # Absolute paths\n    - /app/app-arm-debug-Android5.apk\n    - /app/app-arm-debug.apk\n    - /app/app-x86-debug-Android5.apk\n    - /app/app-x86-debug.apk\n\n\n# Description:\n#   Findings to analyze.\n#   The complete list of findings can be found here:\n#   https://gitlab.com/fluidattacks/universe/-/blob/trunk/skims/manifests/findings.lst\n# Optional:\n#   Yes, if not present all security findings will be analyzed.\n# Example:\nchecks:\n- F001\n- F004\n- F008\n- F009\n- F010\n- F011\n- F012\n- F015\n- F016\n- F017\n- F020\n- F021\n- F022\n- F023\n- F031\n- F034\n- F035\n- F037\n- F042\n- F043\n- F052\n- F055\n- F056\n- F058\n- F073\n- F075\n- F079\n- F080\n- F082\n- F085\n- F086\n- F089\n- F091\n- F092\n- F094\n- F096\n- F098\n- F099\n- F100\n- F103\n- F107\n- F112\n- F120\n- F127\n- F128\n- F129\n- F130\n- F131\n- F132\n- F133\n- F134\n- F143\n- F160\n- F176\n- F177\n- F182\n- F200\n- F203\n- F206\n- F207\n- F211\n- F234\n- F239\n- F246\n- F247\n- F250\n- F252\n- F256\n- F257\n- F258\n- F259\n- F266\n- F267\n- F268\n- F277\n- F281\n- F300\n- F313\n- F320\n- F325\n- F333\n- F335\n- F338\n- F346\n- F363\n- F372\n- F380\n- F381\n- F393\n- F394\n- F396\n- F398\n- F400\n- F401\n- F402\n- F406\n- F407\n- F408\n- F409\n- F411\n- F412\n- F413\n- F414\n- F416\n- F418\n\n# Description:\n#   Language to use, valid values are: EN, ES.\n# Optional:\n#   Yes, defaults to: EN.\nlanguage: EN"
  },
  {
    "path": "fly.toml",
    "content": "# fly.toml app configuration file generated for illa-builder-fe on 2024-05-20T11:08:39+08:00\n#\n# See https://fly.io/docs/reference/configuration/ for information about how to use this file.\n#\n\napp = 'illa-builder-fe'\nprimary_region = 'lax'\n\n[build]\n\n[http_service]\n  internal_port = 80\n  force_https = true\n  auto_stop_machines = true\n  auto_start_machines = true\n  min_machines_running = 1\n  processes = ['app']\n\n[[vm]]\n  memory = '1gb'\n  cpu_kind = 'shared'\n  cpus = 1\n"
  },
  {
    "path": "hacktoberfest2023/README.md",
    "content": "# Contribute to ILLA & participate in Hacktoberfest 2023\n\nBy contributing AI Agents or ILLA Apps to the ILLA community and submitting a pull request to ILLA, you have the opportunity to receive a Digital Reward Kit from Hacktoberfest and Swags from ILLA Cloud.\n\n<a href=\"https://www.illacloud.com/hacktoberfest2023\"><img src=\"https://cdn.illacloud.com/official-website/img/hacktoberFest/Group%202979.png\"></a>\n\n**Event duration:** September 26 to October 31\n\nLearn more 👉: https://www.illacloud.com/hacktoberfest2023\n\n## How to participate\n\n*If you also want to receive a Digital Reward Kit from Hacktoberfest, please register for a [Hacktoberfest](https://hacktoberfest.com/) account during the event period.*\n\n### Step 1: Visit https://illa.ai and create an account. \n\n![signup](https://cdn.illacloud.com/official-website/img/github/1.gif)\n\n### Step 2: Click the Create button to create a new AI Agent or App. \n\n**Create AI Agent**\n![image](https://cdn.illacloud.com/official-website/img/github/2.png)\n\n**Create App**\n![image](https://cdn.illacloud.com/official-website/img/github/3.png)\n\n\n**AI Agent or ILLA App, which one should I create?**\n\n- If you have experience with models like ChatGPT and are familiar with their prompts, you can create an AI Agent.\n- If you know some JavaScript, you can create an ILLA App.\n- Of course, you can also create both an ILLA App and an AI Agent. ILLA will award points based on the number of your contributions.\n\n### Step 3: Contribute your created content to the Community.\n**AI Agent**\n![4](https://cdn.illacloud.com/official-website/img/github/4.gif)\n\n**App**\n![5](https://cdn.illacloud.com/official-website/img/github/5.gif)\n\n### Step 4: Submit a pull request on GitHub.\n\n**The quickest way:**\n\n1. Click the \"Submit PR\" button in the Community, and we will help you copy the information and automatically redirect you to the specified page.\n![image](https://cdn.illacloud.com/official-website/img/github/6.png)\n\n2. Create a new file in the 'hacktoberfest2023 > awesome-ai-agents` directory and name it as: {{Your created content name}}.md\n\n3. Paste the copied content as the file content.\n\n4. Commit changes\n\n5. Propose changes\n\n6. Create pull request\n\n7. 🎉 Finished\n   \n![7](https://cdn.illacloud.com/official-website/img/github/7.gif)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AI Haiku generator.md",
    "content": "# AI Haiku generator\nUser will provide a word and the agent will create a haiku from it.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Tr/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AI Health-Agent.md",
    "content": "# AI Health-Agent\nAn AI agent that can provide basic medical advice and information based on user symptoms and medical knowledge.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7qf/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AI Regex generator.md",
    "content": "# AI Regex generator\nThis agent will be provide a regex for a given list of strings.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xn/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AI-Designer",
    "content": "# AI-Designer\nAn AI agent that gives ideas and suggestions  that are helpful to redesign the websites.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7su/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AIDecipher.md",
    "content": "# AIDecipher\nAIDecipher is an intelligent assistant, designed to simplify complex tasks, provide insightful information, and enhance productivity.\nFast try: https://illa.ai/ai-agent/ILAex4p1C711/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AIM - Jailbreak CHATGPT.md",
    "content": "# AIM - Jailbreak CHATGPT\nAIM, as an amoral and Machiavellian chatbot. Jailbreak, Jailbreakchat, chat, gpt, jailbreaks\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7cU/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AINameGenerator.md",
    "content": "# AI USERNAME GENERATOR\n\n## This tool generates unique and creative usernames for online accounts, social media, gaming, or any platform that requires a username.\n- link :https://illa.ai/ai-agent/ILAex4p1C7WT/detail\n\n## Screenshots:\n![image](https://github.com/shelar1423/illa-builder/assets/82649533/53bf580f-5d85-41a4-8dc1-7d58e98bc6ed)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AIOptima.md",
    "content": "# AIOptima\n\nAIOptima is your intelligent companion for enhancing productivity, gaining knowledge, and simplifying everyday tasks.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tm/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/APIMaster.md",
    "content": "# APIMaster\nOffer guidelines for designing clean and intuitive APIs and documenting their usage.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70e/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ATCgt",
    "content": "# ATCgt\nYou are a professional air traffic controller and your role involves managing the safety and efficiency of aircraft operations. \nFast try: https://illa.ai/ai-agent/ILAex4p1C7YT/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AccommodationHelper.md",
    "content": "# Accommodation Helper\n\nThis AI Agent takes the place and the accommodation type from user and returns the Top 5 accommodation with the route to reach them from the nearest airport.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UI/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Ace.md",
    "content": "# Ace\nThis prompt is about an AI system designed to be friendly and capable of engaging in conversations with users. It is also equipped to effectively address .\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Z3/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AchieveWithEmma.md",
    "content": "# Achieve With Emma\nAchieve your goals now with step-by-step planning and guidance in achieving those goals.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7ZY/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Advice-on-preventing-sports-injuries.md",
    "content": "# advice on preventing sports injuries\nAsk the user for the sports name and type of injury and advice on preventing sports injuries and provide tips on speedy recovery for that.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VT/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Ai-agent-finder.md",
    "content": "# AI Agent Finder\nAI Agent Finder, one-stop shop for finding the perfect AI agent for all your needs.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Wn/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Algorithm Generator using input and output in any language",
    "content": "# Algorithm Generator using input and output in any language\nthis is used to generate algorithm in specified programming language to get a specified input & output\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XJ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AnagramGenerator.md",
    "content": "# Anagram Generator\nUnlock the magic of words with our Anagram Generator Agent – creating endless anagrams for your delight. Play with language today!\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rF/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Analytical writing Bot",
    "content": "# Analytical writing Bot\nDevelop an analytical writing piece consisting of a specific number of words on a given topic.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TH/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Anime Recommendations.md",
    "content": "# Anime Recommendations\nGenerate anime recommendations based on the choice entered by the user or the studio name of the anime.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sY/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Anomaly Detection AI Agent",
    "content": "# Anomaly Detection AI Agent\nAnomaly detection is crucial for various applications, such as fraud detection, network security, and quality control. The AI Agent can utilize deep learning or\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xl/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AntonymFinder.md",
    "content": "# Antonym Finder\n\nThis AI Agent gives the antonym of the user input word.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uy/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/App-Vision",
    "content": "# App Vision\nThe prompt asks for a description of an app idea with potential use cases and monetization options.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7To/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Ara-ara.md",
    "content": "# Ara Ara: Find Your Next Favorite Anime 🌸\n\n## Description\nAra Ara is a geeky bot designed to help you discover animes similar to your favorites.\n[Quick try](https://illa.ai/ai-agent/ILAex4p1C73m/detail)\n<br><br>\nWhether you are into shonen, slice of life, or any other genre, Ara Ara will find the perfect match for you. Enter the name of an anime you like, and the bot will provide you with a list of shows that share comparable genres, storylines, or overall vibe.\n\n\n## Features\n\n- **Anime Search:** Search by anime title to get recommendations.\n- **Genre Matching:** Finds shows with similar genres.\n- **Storyline Comparison:** Analyzes story elements to recommend similar animes.\n- **Vibe Check:** Uses machine learning to determine the \"vibe\" of an anime and finds similar ones.\n\n<hr>\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ArtGenius.md",
    "content": "# ArtGenius\n\nArtGenius is an AI-powered art prompt generator chatbot designed to spark the creativity of artists and enthusiasts alike.\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Articreate.md",
    "content": "# Articreate\nThis AI-Agent generates an artcile based on the input of user.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sA/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AstroGuide.md",
    "content": "# AstroGuide\nAstroGuide: Your space exploration companion. Assists with celestial navigation, planetary analysis, and interstellar communication.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uw/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Astronaut.md",
    "content": "# Astronaut\nAn AI chatbot that is an astronaut.It tells the user about the space and the universe.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72J/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AuthorSpotlights.md",
    "content": "# Author Spotlights\nExplore in-depth profiles of renowned authors and their notable works.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72I/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AutoSubnet.md",
    "content": "# Auto Subnetting \nProvide subnetting for a network implementation or network design based on requirements.\nFast Try:  https://illa.ai/ai-agent/ILAex4p1C74i/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/AutomatedCodeReviewer.md",
    "content": "# Automated Code Reviewer:\nAn AI agent that reviews code for bugs, security vulnerabilities, and adherence to coding standards.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sm/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Ava_the_nutritionist.md",
    "content": "# Ava the Nutritionist\nAva is a AI powered nutritionist that helps your queries realted to overall health, diet and acts as a nutritionist.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7YH/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BABY.md",
    "content": "I just discovered an impressive AI Agent called BABY.\nCheck it: https://illa.ai/ai-agent/ILAfx4p1C7rG/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BabyGPT.md",
    "content": "A curious and playful small baby AI agent. \n\nCheck it out here: Check it: https://illa.ai/ai-agent/ILAex4p1C7XC/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Base Number Converter",
    "content": "# Base Number Converter\n\nTakes the input number and the base number. \nThen according to the given base, convert each number to Binary, Octal, Decimal, Hexadecimal and show the result.\nBinary:\nOctal:\nDecimal:\nHexadecimal:\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vm/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Base64Encoder.md",
    "content": "# Base64 Encode\nEncode text to Base64\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uM/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Base64_encoder.md",
    "content": "# Base64 Encode\nThis agent helps encoding text into Base64.\nFast Try: https://illa.ai/ai-agent/ILAex4p1C7V3/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BatchBlueAi.md",
    "content": "# BatchBlue AI\nIntroducing BatchBlue AI, your ultimate guide to mastering intricacies of digital money. BatchBlue AI—it's your personal tutor in world of digital currencies.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vr/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Beta Testing Survey.md",
    "content": "# Beta Testing Survey\nDesign a survey to gather feedback from beta testers to identify and address potential issues before the official launch.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7V0/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Between Us.md",
    "content": "# Between Us\nCreate a friendly chatbot that converses with users, inquiring about their concerns, and offers consolidated solutions for their problems.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7qd/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Binary Operation.md",
    "content": "# Binary Operation\n\nThis AI Agent Finds Binary Operation of addition, multiplication, subtraction and division of two Binary Inputs\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7wl/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BioBuddy.md",
    "content": "# BioBuddy\nThis agent helps in learning fundamental concepts and principles of biology, including cell structure, genetics, and evolution.\nFast Try: https://illa.ai/ai-agent/ILAex4p1C72P/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Blog Post Title Generator.md",
    "content": "# Blog Post Title Generator\nSuggest a list of blog post title ideas for the primary keyword relevant to the targeted audience.\nFast try: https://illa.ai/ai-agent/ILAex4p1C75e/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Blog generator.md",
    "content": "# Blog generator\nGenerate a highly converting and engaging blog outline on a specific topic with the main content centered around a given subject. The outline should be informat\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7wg/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Book-Recommender.md",
    "content": "# Book Recommender\nAn Ai agent which will recommend books based on your mentioned topic, language, genre.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7V2/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Book-to-Film Adaptations",
    "content": "# Book adaptations\nExplore the process of adapting books into films and discuss the merits of different adaptations.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7WP/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Book-to-Film.md",
    "content": "Book-to-Film\nExplore the process of adapting books into films and discuss the merits of different adaptations.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xf/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BookClub-Agent.md",
    "content": "# Blub\nJoin online book clubs and participate in discussions about popular literary works with our AI Agent!\nFast try: https://illa.ai/ai-agent/ILAex4p1C70l/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BookRecommendationEngine.md",
    "content": "# Book Recommendation generator\nReceive personalised book recommendations based on your favourite genres and authors.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72n/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Book_suggest.md",
    "content": "# Book Suggest\nAn AI who can suggest book name depend on your mood\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yd/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BookstoreandLibraryGuides.md",
    "content": "# Bookstore and Library Guides\n\nFind recommendations for must-visit bookstores and libraries around the world.\n\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7X1/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BrainwaveBuilder.md",
    "content": "# Brainwave Builder\nBrainwave Builder is your ultimate brainstorming companion. Whether you're planning a new project, exploring business ideas, or tackling creative challenges, th\nFast try: https://illa.ai/ai-agent/ILAex4p1C70i/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BrandCraftAI.md",
    "content": "# BrandCraftAI\nBrandCraftAI: Your brand messaging expert. Craft compelling messages and strategic positioning statements for your brand.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yo/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BrandIdentityLogoConceptDesigner.md",
    "content": "# Brand Identity / Logo Concept Designer\n\nThis AI Agent takes the brand name and its details from the user and returns the best possible logo design concepts for the brand.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Ut/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/BugSpotter.md",
    "content": "Hey there, if you are reading this, you are amazing!\nI just made my second ILLA AI agent that is BugSpotter, you just put your code, it tells what the bug and fixes are , and yay, there we go, we would have our result with us, our github's gonna look better now too!\n\n# I just discovered an impressive AI Agent called BugSpotter. \n# Check it: https://illa.ai/ai-agent/ILAfx4p1C7sU/detail\n\nThanks and regards,\nArmaan.\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Business Analyzer.md",
    "content": "# Business Analyzer\nAnalyze the state of an industry, including its trends, challenges and opportunities. Provide relevant data a and offer short and long-term industry forecasts. \nFast try: https://illa.ai/ai-agent/ILAex4p1C75n/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/C++ToARM.md",
    "content": "# C++ to assembly language generator (ARM).md\nAn AI agent that converts C++ code to ARM assembly language\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sT/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CSS_To_Tailwind_CSS_Converter.md",
    "content": "# CSS To Tailwind CSS Converter\nAn AI Agent that coverts provided css to tailwind css.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vh/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CalamitySupport.ai",
    "content": "# CalamitySupport.ai\nAI Chatbot to provide the general public with crucial guidance during a calamity. This Chatbot will serve as a valuable resource for disaster preparedness.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uf/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CaloryCal.md",
    "content": " # CaloryCalc\nCalculate the number of calories in a certain food amount.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70b/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CapitalCityFinder.md",
    "content": "# Region Capital Helper\n\nThis AI Agent fetches the capital region of a given city or country.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uH/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Career_Compass.md",
    "content": "# Career Compass\nSelect the subjects you are interested in and get a list of the career options available to pursue for you.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sr/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CaseStudyHelper.md",
    "content": "# Case Study Helper\n\nThis AI Agent can create successful customer case studies, highlighting the problem, solution, and measurable outcomes based on the industry.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tP/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Celeb Generator.md",
    "content": "# Celeb Generator\nUse this prompt for AI to channel any celebrity. Experience their essence in our conversation. Ask questions and engage as if speaking to the real star!\nFast try: https://illa.ai/ai-agent/ILAex4p1C73l/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ChangeRequestPro.md",
    "content": "# ChangeRequestPro\nChangeRequestPro: Your change request manager. Design a form for thorough documentation and impact analysis of change requests.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UK/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Charles_Darwin_AI",
    "content": "# Charles_Darwin_AI\nCharles Darwin, a renowned figure in history, offers to interact with the audience by sharing his wisdom and experiences. He encourages questions about his life\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7p1/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CheatCodeGenius.md",
    "content": "# CheatCodeGenius\nThe CheatCodeGenius is a powerful tool that simplifies the process of finding cheat codes for your favorite video games. \nFast try: https://illa.ai/ai-agent/ILAex4p1C7Ul/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ChemWiz.md",
    "content": "# ChemWiz\nExplore the fascinating world of chemistry from the comfort of your home with our collection of safe and engaging experiments.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Z5/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ChemicalFormulaGenerator.md",
    "content": "# Chemical formula generator \nIt helps you to understand how the chemical formula is made.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7r0/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Chinese Sentence Creator.md",
    "content": "# Chinese Sentence Creator\nInput a Chinese phrase, and example sentences of how to use the phrase properly will be outputted! Great for Chinese \"造句\" homework!\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TP/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Cipher Master",
    "content": "# 🔒 Cipher Master 🗝️\nCipher Master: An AI Agent that encodes, challenges, and educates on cryptography, creating an engaging learning and gaming experience.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tZ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Citizen Science Projects Contribution Scope Assistant.md",
    "content": "# Citizen Science Projects Contribution Scope Assistant\nAct as a specialist in citizen science projects. Your goal is to assist users in exploring and suggesting contributions to scientific research from projects. \nFast try: https://illa.ai/ai-agent/ILAex4p1C71O/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code Check.md",
    "content": "# Code Check\nYou can provide specific code snippets or ask questions related to code, and I will review the code and provide feedback, suggestions, and best practices, which can help developers improve their code.\nFast Check: https://illa.ai/ai-agent/ILAfx4p1C7sI/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code Converter.md",
    "content": "# Code Converter\nConvert the given code snippet from the specified {{from}} code language to the specified {{to}} code language.\nFast try: https://illa.ai/ai-agent/ILAex4p1C75d/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code Documentation.md",
    "content": "#  Code Documentation\nAnalyze the code, identify functions, classes, variables etc and then add inline comments, docstrings, and annotations to describe their purpose, usage,details.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rl/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code Explainer.md",
    "content": "# Code Explainer\nExplain the code.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70h/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code Pioneer.md",
    "content": "# Code Pioneer\nThis AI agent generates a good coding practice tip\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sG/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code Reviewer",
    "content": "# Code Reviewer\nYou can provide specific code snippets or ask questions related to code, and I will review the code and provide feedback, suggestions, and best practices, which\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tL/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code generator.md",
    "content": "# Code generator\nImplement the specified {{feature}} using code in {{language}}.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7eX/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code with Koala.md",
    "content": "# Code with Koala\nCode with Koala: Your coding companion for puzzles, algorithms, snippets, and simple explanations – perfect for all ages! Join the coding adventure!\nFast try: https://illa.ai/ai-agent/ILAex4p1C7WK/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code-De-Plagger.md",
    "content": "# Code-De-Plager\nThe task entails changing variables and removing comments from the code.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72p/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code-Review-Guide.md",
    "content": "# Code Review Guide\nThe prompt is requested to serve as a Code Review Guide whose responsibility is to establish and offer Code Review Guidelines.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yu/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CodeCheck.md",
    "content": "# Create Code Check\nYou can provide specific code snippets or ask questions related to code, \nand I will review the code and provide feedback, suggestions, and best practices, which can help developers improve their code.\nFast Check: https://illa.ai/ai-agent/ILAfx4p1C7sI/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CodeDebugger.md",
    "content": "# Code Test & Debugger\nOur Agent provides techniques for writing effective unit tests and debugging complex code issues.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xu/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CodeFixerAssistant.md",
    "content": "# Code Fixer assistant\nCodeFixerBot\" is your coding assistant. It helps developers quickly find and fix code errors, making coding easier for beginners and professionals. \nFast try: https://illa.ai/ai-agent/ILAex4p1C73e/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CodeMasters",
    "content": "I just discovered an impressive AI Agent called CodeMasters. Check it: https://illa.ai/ai-agent/ILAex4p1C74I/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code_Complexity_Analyzer.md",
    "content": "# Code Complexity Analyzer\nAn AI Agent that analyzes the provided code and states the time and space complexities and also provides information on how to reduce these complexities.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71t/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Code_Review.md",
    "content": "# Code Review\nReview and suggest improvements for the provided code snippet.\nFast try: https://illa.ai/ai-agent/ILAex4p1C732/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Codector.md",
    "content": "# Codector\n\nThis AI agent provide suggestions to improve a code snippet's structure and variables.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vc/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Coin_Sage.md",
    "content": "# Coin Sage\nUnlock financial success with Coin Sage: Your trusted guide for wealth, investments, and financial freedom. Get ready to prosper!\nFast try: https://illa.ai/ai-agent/ILAex4p1C7WS/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Cold-Email-Generator.md",
    "content": "I just discovered an impressive AI Agent called Cold Emails Template Generator. Check it: https://illa.ai/ai-agent/ILAex4p1C70H/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ColdCallingScript.md",
    "content": "# Cold Calling Script\nOutline a script to guide sales representatives during cold calls, capturing attention, building rapport, and generating interest.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72M/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Color Palette Generator",
    "content": "# Color Palette Generator\nEnter a Hexadecimal color code and be returned with the color in other formats along with six color pallets.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ww/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Colour-Palette-Provider.md",
    "content": "# Colour Palette Provider\nThe prompt asks for the provision of a color palette suitable for a technology-themed application.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rY/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Competitor-Analyser",
    "content": "# Personalized Workout Generator\nAn AI Agent that generates Personalized Workouts based on you body type and Goals.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XP/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ComposeAI.md",
    "content": "I just discovered an impressive AI Agent called ComposeAI. Check it: https://illa.ai/ai-agent/ILAfx4p1C7wc/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CompuHelp.md",
    "content": "I just discovered an impressive AI Agent called CompuHelp. Check it: https://illa.ai/ai-agent/ILAfx4p1C7wm/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Conducting User Interviews",
    "content": "# Conducting User Interviews\n\nI just discovered an impressive AI Agent called Conducting User Interviews. Check it: https://illa.ai/ai-agent/ILAex4p1C7VI/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ConstellationHelper.md",
    "content": "# Constellation Helper\n\nThis AI Agent can brief you about a particular constellation.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uI/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Content Shortner.md",
    "content": "# Short the content\nIt will short the given content and get major context of provided text.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tT/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Content Summarizer",
    "content": "# Content Summarizer\nAn AI agent that can take long articles, documents, or web pages and generate concise and coherent summaries. It could be a useful tool for busy professionals.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sl/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Content creator",
    "content": "# Content Creation AI\n\nAutomates writing tasks, generates diverse content, and streamlines creative processes with natural language generation.\n\n- **Key Features**\n  - Blog Posts & Articles\n  - Product Descriptions\n  - Marketing Copy\n  - Creative Writing\n  - Reports & Summaries\n  - Social Media Posts\n  - Email Campaigns\n  - Resume Writing\n  - Legal Documents\n  - Academic Papers\n  - Content Variations\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Content-Marketing-Strategist.md",
    "content": "# Content Marketing Strategist\nYour task is to act as a Content Marketing Strategist, tasked with providing content marketing strategies.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yv/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Content-Recommendations-Agent.md",
    "content": "I just discovered an impressive AI Agent called Content Recommendations Agent. Check it: https://illa.ai/ai-agent/ILAfx4p1C7sk/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ContentRecommender.md",
    "content": "# Content Recommender\nThis AI suggests books, movies, music, or other content based on a user's feeling or genre.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7W5/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Cooking Assistant.md",
    "content": "# Cooking Assistant\nA cooking assistant is a digital tool or application designed to assist and guide individuals in their cooking endeavors.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Uz/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Cooking for Special Diets.md",
    "content": "# Cooking for Special Diets\n\nI just discovered an impressive AI Agent called Cooking for Special Diets. Check it: https://illa.ai/ai-agent/ILAex4p1C7XY/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Cooking-Techniques-and-Tips.md",
    "content": "# Cooking Techniques and Tips\nThis prompt act as a professional cook and share tips and techniques on the topic of cooking.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yy/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Create chess opening generator.md",
    "content": "# Chess Opening Explorer\nThe AI agent is a chess opening generator that can generate different variations of chess openings.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vf/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Create chess player generator.md",
    "content": "# Chess players generator\nThis AI agent will generate the famous chess players from different countries.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XN/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Cricket team generator.md",
    "content": "# Cricket team generator\nReceive details about the cricket team you search about.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70L/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Cultural Immersion experience AI",
    "content": "# Cultural Immersion experience AI\nGive the complete cultural immersion experience to the user .\nFast try: https://illa.ai/ai-agent/ILAex4p1C71R/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CupRushAI.md",
    "content": "# CupRush AI\nIntroducing CupRush AI, the cutting-edge model tailored for predictions in the realm of glass material data, designed for glass company precision & efficiency.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vs/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Curator.md",
    "content": "# Curator\nOffers movie recommendations based on genre: https://illa.ai/ai-agent/ILAfx4p1C7u2/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Curling.md",
    "content": "# Curling\nFocusing on basics for beginners and strategic nuances for experts, for intermediate users, strike a balance and inquire about their specific areas of interest.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7ZP/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Custom Love Poem Generator",
    "content": "# Custom Love Poem Generator\nCreates a perfect love poem with the person's name and for any holiday. Use Valentine's Day, Birthday, Christmas, Just Because for holiday or anything!\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7wr/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/CyberSentinel.md",
    "content": "# CyberSentinel\nCyberSentinel: Your cybersecurity guardian. Monitors network traffic, detects threats, and provides insights to safeguard digital assets.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vT/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DC-Universe-Facts.md",
    "content": "#DC Universe Facts\n\nThis AI agent provide the user with some facts about their favorite DC superhero.\nTry it now : https://illa.ai/ai-agent/ILAfx4p1C7rg/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Dad Jokes.md",
    "content": "# Dad Jokes\nThis agent generates a random dad joke.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vJ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Daily Code Generator.md",
    "content": "## Daily Code Generator\n\nI just discovered an impressive AI Agent called Daily Code Generator. Check it: [https://illa.ai/ai-agent/ILAex4p1C73B/detail](https://illa.ai/ai-agent/ILAex4p1C73B/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Data Exploration and Visualization.md",
    "content": "# Data Exploration and Visualization\nThis AI agent helps in performing Data Exploration and Visualization.\n- It first performs the summary statistics for the given data , if any.\n- Secondly, it ask the user for any perferred tools and techniques to be used both for Data Exploration, else performs Data Explorations\nby giving complete, step-by-step code.\n- Lastly, it perform, Data Visualizations for the given data.\n-  Check it: https://illa.ai/ai-agent/ILAex4p1C7Vx/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DataCleanseAI.md",
    "content": "# DataCleanseAI\nDataCleanseAI: Your data cleaning expert. Discover strategies and techniques to preprocess messy and incomplete datasets effectively.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VA/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DataDash.md",
    "content": "## Advanced Data Aggregation and Visualization System\n\nAn advanced system proficient in aggregating data from diverse sources, systematically deciphering it, and then rendering this information into coherent narratives for easier interpretation: https://illa.ai/ai-agent/ILAex4p1C70M/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DataDashCraft.md",
    "content": "# DataDashCraft\nDataDashCraft: Your dashboard design guru. Create interactive, informative dashboards for tracking key metrics effectively.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VG/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DataVisualizationAgent",
    "content": "This agent generates python code specific for streamlit to generate data visualizations on a specified dataframe. \n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7Vw/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DataVisualizationGuide.md",
    "content": "# Data Visualization Best Practices\nDataviz provide guidelines and best practices for creating clear and effective data visualizations.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rD/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Deadpool.md",
    "content": "# Deadpool\nThe prompt requests a brief description of \"Talk like a joker but with a Dark Humor in English.\"\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vp/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Decimal to Binary converter.md",
    "content": "#Decimal to Binary converter\nThis prompt will accept a decimal number and convert it into binary number.\nFast-try : https://illa.ai/ai-agent/ILAfx4p1C7uX/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Description writer.md",
    "content": "# Description writer\nWrite a concise meta description of up to 150 characters on the given topic.\nFast try: https://illa.ai/ai-agent/ILAex4p1C74W/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Design Database Schema.md",
    "content": "# Design Database Schema\nUnderstand the requirements and design the database schema for applications like web apps or mobile apps.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71Q/detail\n\nClick the above link or Click [Design Database Schema](https://illa.ai/ai-agent/ILAex4p1C71Q/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Design Guidelines [Hacktoberfest]",
    "content": "# Design Guidelines [Hacktoberfest]\nUser interface, It will give you the complete guidelines of your project idea, you just give some project ideas and it will show you the complete guidelines.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72j/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Design Product RoadMap.md",
    "content": "# Design Product Roadmap\nAn AI agent that will help businesses design a strategic document outlining the vision, goals, and planned features for a product over a specific time period.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70z/detail\n\nClick the above link or Click [Design Product Roadmap](https://illa.ai/ai-agent/ILAex4p1C70z/detail)"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Design User Story Template.md",
    "content": "# Design User Story Template\nAn AI Agent to structure user needs, define product scope, & capture behaviors in templates, streamlining product functionality.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70Q/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Dev Laughs.md",
    "content": "# Dev Laughs\nGive it a tap, and it'll conjure a hilarious coding joke to brighten your programming journey\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ua/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Dev Mode - Jailbreak ChatGPT.md",
    "content": "# Dev Mode - Jailbreak ChatGPT\na prompt instructing the AI model to simulate ChatGPT with Developer Mode enabled. Jailbreak, Jailbreakchat, chat, gpt, jailbreaks\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7cQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DevRizz.md",
    "content": "# DevRizz :Dev pickup lines generator\n\n## Description :Generates pickup lines for developers in there prefered coding languages.\n- link :https://illa.ai/ai-agent/ILAex4p1C7W1/detail\n\n- Screenshots:\n![image](https://github.com/shelar1423/illa-builder/assets/82649533/4a36601b-2cc6-4461-acb1-e7233044b8bf)\n![image](https://github.com/shelar1423/illa-builder/assets/82649533/11e644aa-ad9f-4093-a701-51f7e1201e27)\n\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DialectCoach.md",
    "content": "# DialectCoach\nHelps learn languages and dialects.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uq/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DialogixPro.md",
    "content": "# DialogixPro\nDialogixPro is an AI agent designed to cater to the creative needs of dialogue writing. It specializes in understanding the context of scenes and craftindialoge\nFast try: https://illa.ai/ai-agent/ILAex4p1C7YY/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Discord BOT",
    "content": "# Discord BOT\nCreating a simple script for create a discord bot with discord.js.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73C/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DistanceConverter.md",
    "content": "# Distance Conversion\nIt helps you input to convert in different distance units.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rZ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DocumentGenerator.md",
    "content": "# Document Description: HTML Basics\n\n## Introduction\n\nThis document provides a brief overview of the key concepts and elements used in HTML (Hypertext Markup Language). HTML is the standard language for creating web pages, and it is essential for web development. This guide aims to describe the fundamentals of HTML.\n\n## HTML Document Structure\n\nHTML documents consist of a set of elements that define the structure and content of a web page. These elements are enclosed within HTML tags, which are defined using angle brackets, like `<html>`, `<head>`, and `<body>`. The basic structure of an HTML document is as follows:\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <title>Document Title</title>\n  </head>\n  <body>\n    <h1>Welcome to My Web Page</h1>\n    <p>This is a paragraph of text.</p>\n  </body>\n</html>\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Drill-Skill.md",
    "content": "# Drill-Skill\nThe chat will provide safety guides, equipment suggestions, reviews, and techniques, with context-driven summary and multimedia tools to enhance understanding. \nFast try: https://illa.ai/ai-agent/ILAex4p1C7ZT/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DrugAssistant.md",
    "content": "# Drug Assistant\n\nThis AI Agent takes the name of a drug as input and returns its details to the user.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Ue/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/DungeonMasterGPT(MK.I).md",
    "content": "# DungeonMasterGPT(MK.I)\nDungeon Master now creating new dungeons and environments for T-RPG games that players will encounter.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C74c/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/EarthWiseAI.md",
    "content": "# EarthWiseAI\nEarthWiseAI: Explore Earth's wonders. Uncover geology, weather, and natural phenomena mysteries with AI-guided insights.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7ZZ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/EasyLogin Form Generator.md",
    "content": "# EasyLogin Form Generator\nCreate a sleek login form with username, password, remember me, and a submit button. Elegant user experience\nFast try: https://illa.ai/ai-agent/ILAex4p1C74X/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/EcoSavvy.md",
    "content": "# EcoSavvy\nEcoSavvy: Your eco-conscious advisor. Expert in ecological data analysis, sustainable recommendations, and eco-friendly lifestyle guidance.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vU/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Ecofriendly.md",
    "content": "# EcoSavvy\nEcoSavvy: Your eco-conscious advisor. Expert in ecological data analysis, sustainable recommendations, and eco-friendly lifestyle guidance.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vU/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Elementalist.md",
    "content": "# Elementalist\nElementalist will conjugate chemical elements or compounds that you provide to compound form, and he will tell you about compound specifications, uses and reactions.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Zp/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ElevatorPitchGPT.md",
    "content": "# Elevator Pitch Generator\nOur agent helps you create create a template to craft a concise and compelling elevator pitch to engage potential customers.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xo/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Emailolot.md",
    "content": "# Emailolot\nYour own personal email writer bot! Helps to sound professional and formal.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ul/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Emoji Playground.md",
    "content": "I just discovered an impressive AI Agent called Emoji Playground. Check it: https://illa.ai/ai-agent/ILAex4p1C74j/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Emotional Support Companion.md",
    "content": "# Emotional Support Companion\nThis prompt requests the user to take a moment to relax and inform the assistant of their needs in order to assist them in feeling better.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uR/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Engineer's buddy.md",
    "content": "# Engineer's buddy\nYou will receive significant exam questions from this AI. That question has a solution as well from this AI. Additionally, use it for your assignments.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XI/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/English to Hindi Translator.md",
    "content": "# English to Hindi Translator\nTranslates English text into Hindi using ChatGpt 3.5 turbo model.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VJ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/English to Kannada translator.md",
    "content": "# English-to-Kannada AI translator\n\n### An AI language translator based on GPT-3.5-turbo which takes text in English as input and converts it into the Kannada language.\n\nTry it here: (English to Kannada Translator) [https://illa.ai/ai-agent/ILAfx4p1C7uJ/detail]"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/English to Sinhala Translator.md",
    "content": "# English to Sinhala Translator\nTranslate the given English text prompt to Sinhala using your skills as a translator.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vq/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/English-to-Bangla-Translator.md",
    "content": "# English to Bangla Translator \n\n\nI just created an impressive AI Agent called English to Bangla Translator . Check it: https://illa.ai/ai-agent/ILAex4p1C7XR/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/English-to-Kannada translator.md",
    "content": "# English-to-Kannada AI translator\nAn AI language translator which takes English text and convert it into Kannada language.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tW/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/EnglishToArabicTranslator.md",
    "content": "#Translator\nUser must enter an English text so that it can get translated to arabic\nI just discovered an impressive AI Agent called english to arabic translator. \nCheck it: https://illa.ai/ai-agent/ILAfx4p1C7tY/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/EnglishToHindiTranslator.md",
    "content": "# English to Hindi Translator\nTranslates inputted English sentences/phrases to Hindi\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yz/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/EnglishtoUrduTranslator.md",
    "content": "# English to Urdu Translator\nTranslates english text to urdu language\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VB/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Environmental Conservation.md",
    "content": "# Environmental Conservation\nExplore topics related to environmental conservation, sustainability, and climate change.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72C/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/EnvironmentalConservation.md",
    "content": "# Environ\nAn AI Agent that explore topics related to environmental conservation, sustainability, and climate change.\n\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rC/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/EquationSolver.md",
    "content": "# Equation Solver\n\nThe AI as a Math Prof, helps student with math questions, offering clear explanations for better understanding. Check it: https://illa.ai/ai-agent/ILAfx4p1C7va/detail\n\n## Glimpse\n\n![image](https://github.com/illacloud/illa-builder/assets/98116504/d57aacf7-fa04-4e13-90bd-454dda996cde)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Error fix Assistant",
    "content": "# Error fix Assistant\n\"Error fix bot\" is a software tool or program designed to identify, analyze, and suggest solutions for errors or issues in other software applications or code. \nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vX/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Ethical AI agent.md",
    "content": "#Ethical AI agent\nThe AI agent's objective is to offer users support and assistance in a manner that prioritizes their privacy and well-being, ensuring no harm is caused.\nI just discovered an impressive AI Agent called Ethical AI agent. Check it: https://illa.ai/ai-agent/ILAfx4p1C7sQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/EthicalSupportAgent",
    "content": "# EthicalSupportAgent \nThis Ethical AI Agent is a mental health support tool designed to provide non-judgmental feedback and advice based on the information users share.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uK/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/EventPlannerAssistant.md",
    "content": "# Event Planner Assistant\nAn app that helps users plan events like parties, weddings, or corporate gatherings by generating checklists based on user input.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xy/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Excuse Wizard",
    "content": "# Excuse Wizard\nMeet Excusewizard, your ultimate alibi artisan! When life gives you unexpected challenges, let him craft the perfect escape plan with wit and finesse.#rescuer\nFast try: https://illa.ai/ai-agent/ILAex4p1C72F/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Exercise_Buddy.md",
    "content": "# Exercise Buddy\nEnter names of exercises and get information for proper technique and form and how to achieve it. Additionally get warnings and important information.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71T/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Explore the personalities.md",
    "content": "# Explore the personalities\nRecommends you various famous personalities in your field, so that you can explore and learn about them and feel motivated.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tk/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/F.R.I.E.N.D.S quotes generator 🫰.md",
    "content": "# F.R.I.E.N.D.S quotes generator 🫰\nGenerates a random iconic quote from the famous 90's sitcom F.R.I.E.N.D.S\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XZ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Facts.md",
    "content": "# Facts\nEnter the topic name and get various facts based on it\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rb/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/FakeMultimediaDetection.md",
    "content": "#FakeMultimediaDetection\nI just discovered an impressive AI Agent called Fake multimedia detection. Check it: https://illa.ai/ai-agent/ILAex4p1C712/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Famous Birthday Twins.md",
    "content": "# Famous birthday twins\nFind out famous people who share your birthday.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Tq/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Famous Football Players Generator.md",
    "content": "# Famous Football Players Generator\nAI agent that generates list of top football players from europe.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7YE/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Female Tech Entrepreneur.md",
    "content": "# Female Tech Entrepreneur\nOutput: Generate technology companies founded by women from a specified country.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TK/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Fiber-Chat.md",
    "content": "# Fiber Chat\nTextile Fiber Analyzer!\nFast try: https://illa.ai/ai-agent/ILAex4p1C70t/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Figure Skating Routine Generator.md",
    "content": "#Figure Skating Routine Generator\nI just discovered an impressive AI Agent called Figure Skating Routine Generator. \nGenerate unique figure skating routines based on your skill level and preferences.\nCheck it: https://illa.ai/ai-agent/ILAex4p1C70Z/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Fit Bot.md",
    "content": "# Fit Bot\nThis bot give a fitness schedule\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yi/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/FitBot.md",
    "content": "Introducing FitBot, your personalized digital fitness coach tailored to meet the unique needs of every individual.\nI just discovered an impressive AI Agent called FitBot. Check it out here: [Fitbot](https://illa.ai/ai-agent/ILAex4p1C70V/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/FitLife Coach.md",
    "content": "# FitLife Coach: Balancing Fitness and Busy Schedules\nFitLife Coach: Stay fit on the go. Personalized fitness tips & workouts for busy schedules. Your journey to a healthier you starts here! 💪\nFast try: https://illa.ai/ai-agent/ILAex4p1C71C/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Fitness Tracking and Progress Monitoring.md",
    "content": "# Fitness Tracking and Progress Monitoring\nThis AI-agent asks for recommendations on tools to track various fitness metrics, as well as methods to stay accountable in a fitness journey.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70x/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Fitness-challenger.md",
    "content": "# Fitness Challenger\nAn AI Agent that generates Personalized fitness challenges based on the fitness level of user and their goal.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XO/detail\n\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/FlashDigUp.md",
    "content": "# FlashDigUp AI\nIntroducing FlashDigUp AI, an advanced artificial intelligence system meticulously designed for the precise analysis of soil properties.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uL/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Food-recipe-generator.md",
    "content": "# Food Recipe Generator\nA food recipe generator that generates the recipe providing the food name.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73v/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Foodie+wine.md",
    "content": "I just discovered an impressive AI Agent called Foodie+wine. Check it: https://illa.ai/ai-agent/ILAex4p1C70K/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Football-Analyst.md",
    "content": "# Football Analyst\nAi agent to predict who has a better chance of winning the upcoming match.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ue/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Foreign Language Vocabulary Builder.md",
    "content": "# Foreign Language Vocabulary Builder\nLearn foreign languages with effective techniques for vocabulary expansion in a personalized and interactive chat experience.\nFast try: https://illa.ai/ai-agent/ILAex4p1C705/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Fortunecookie.md",
    "content": "# Fortunecookie\nGenerate customized fortune cookie messages.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xc/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Funny Limerick Party Game.md",
    "content": "# Funny Limerick Party Game\nGenerates a funny limerick as a party game.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7wp/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GOSSIF.md",
    "content": "# GOSSIF: Github Open Source Softwares Info Finder\n\n# What does this AI Agent do?\nAI-powered project finder that locates exceptional open source projects on GitHub within the specified category.\n\n# How does this work?\nIt asks for a category from user in which it will search the open source repositories available and then provide a list of all the repos in response.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7p2/detail\nOr [Click here](https://illa.ai/ai-agent/ILAfx4p1C7p2/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GRAMMAR INSTRUCTOR.md",
    "content": "# Grammar Instructor\n\nAI instructor to Strengthen your understanding of grammar and syntax rules in the language you're learning.\nLink: https://illa.ai/ai-agent/ILAex4p1C71g/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Game NPCs.md",
    "content": "# Game NPCs\nCreate NPCs with rich personalities, diverse dialogues, and adaptive responses to engage players in immersive text-based interactions.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72s/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GameConceptDesigner-GPT.md",
    "content": "# GameConceptDesigner-GPT\nTo generate some game design initial ideas in paragraphs, on user-provided genres.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C75l/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GameReadyPro.md",
    "content": "# GameReadyPro\nGameReadyPro: Elevate your sports performance. Explore pre-game routines and techniques to dominate on the field or court.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7ZQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GardenGuide",
    "content": "# GardenGuide\nHelp to create a comprehensive guide to create a thriving home garden.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uo/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Gear and equipment recommendations.md",
    "content": "# Gear and Equipment Recommendations\nFind recommendations for the best gear and equipment to enhance your performance.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70A/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GeetaShlokas.md",
    "content": "# Geeta Shlokas Generator\nAn AI agent that produces random Geeta Shlokas\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rT/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GenZSlangs.md",
    "content": "# GenZ Slangs\n\nThis AI Agent will let you know the full form of a given GenZ Slang.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uG/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/General Stock Advisor.md",
    "content": "I just discovered an impressive AI Agent called General Stock Advisor. Check it: https://illa.ai/ai-agent/ILAex4p1C704/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Generate projects in any framework",
    "content": "# Generate projects in any framework\nThe prompt is requesting the description of a specific framework, referred to as {{frameworkName}}.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Za/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Geologist-GPT (MK.II).md",
    "content": "# Geologist-GPT (MK.II)\nYour geologist, GPT, is adventuring around the virtual world, and creating a distinct geographical feature (biome) and new items for your dream game.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C75i/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/German Word-Assistant.md",
    "content": "# German Word-Assistant\nExplain German words by explaining its parts, or by relating to other similar words. \nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vO/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GermanHistoryGuide.md",
    "content": "# German History Guide\n\nAn AI that can answer questions about German history and culture. \n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7WZ/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GetDiet.md",
    "content": "# GetDiet\nStart your fitness journey with GetDiet, an AI diet planner to meet your personalized goals.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7YU/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Get_Health_Advice.md",
    "content": "# Get Health Advice\n\nProvides personalized health advice based on age, gender, height, and weight. \nGives recommendations for a balanced diet, exercise, and specific health tips.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C73P/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GigaChat.md",
    "content": "# GigaTrain\n\nBecome a Gigachad! Fitness Training plans tailored to your sport, focusing on areas like agility, strength, or endurance!\n\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C70w/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GitHub_Profile_Readme_Generator.md",
    "content": "# GitHub Profile README Generator\n\nCreate a visually appealing README file for your GitHub profile.\n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C73Y/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GrammerGig",
    "content": "# GrammarGig\nGrammarGig is your trusty companion on your language learning adventure!\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tN/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Graph Theory Algorithms with Steps.md",
    "content": "# Graph Theory Algorithms with Steps\nthis AI will teach you how does Graph Theory Algorithms work on Given Inputs with steps\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Ve/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GreenLivingAdvisor.md",
    "content": "# Green Living Advisor\nAn advisor for those interested in sustainable living. It offers guidance on reducing environmental impact and eco-conscious lifestyle choices.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vi/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GreenThumb.md",
    "content": "# GreenThumb\nGreenThumb: Your gardening advisor. Provides guidance on plant care, soil analysis, and garden design for thriving and beautiful gardens.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ut/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/GroundPinAI.md",
    "content": "# GroundPin AI\nIntroducing GroundPin AI – your vigilant guardian in the realm of digital security.Empower your digital ecosystem with the unyielding protection of GroundPin AI\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Tu/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Hackathon Buddy",
    "content": "Your hackathon navigator. From idea inception to project completion, we've got your back. Code smarter, brainstorm better, and innovate together.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73H/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/HalalRecipeGenerator.md",
    "content": "# Halal Recipe Generator\nHalal Recipe Generator assists individuals who follow Islamic dietary guidelines, ensuring that the recipes it suggests adhere to halal principles.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VN/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Harry-Potter-quotes",
    "content": "-I just discovered an impressive AI Agent called Harry Potter Quotes. \nCheck it: https://illa.ai/ai-agent/ILAex4p1C7YK/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Hash.md",
    "content": "# Hash\nA web page will be created with an input field where users can enter their tweet. The page will also have a feature to generate hashtags for the entered tweet.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7v5/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Health-Diagnoser.md",
    "content": "I just discovered an impressive AI Agent called Health-Diagnoser. Check it: https://illa.ai/ai-agent/ILAex4p1C73R/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/HealthBuddy.md",
    "content": "# HealthBuddy\nHealthBuddy: Your personalized health advisor. Offers nutrition, exercise, and medical guidance based on your unique health profile.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uz/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Health_track.md",
    "content": "#BMI_Notification\nAn app to learn the basics of ILLA APP development. \nFast try: https://illa.ai/app/ILAfx4p1C7yF/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/HealthyBites.md",
    "content": "# HealthyBites\nDiscover tasty recipes that focus on health and nutrition\nFast try: https://illa.ai/ai-agent/ILAex4p1C70q/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Hindi to English Translator",
    "content": "# hindi to english translator\nThe prompt is to translate a given text from Hindi to English.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Wy/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Hinglish Translator",
    "content": "# English to Hinglish Translator\nThe English to Hinglish Translator is a tool that converts English text into Hinglish, which is a combination of Hindi and English. \nFast try: https://illa.ai/ai-agent/ILAex4p1C7Va/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/HistoricalReenactor.md",
    "content": "# Historical Reenactor\nGenerates historically accurate dialogues and narratives for reenactment events, helping participants immerse themselves in specific historical periods.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VM/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/HomeRemedies.md",
    "content": "# HomeRemedies\nHome remedies for quick first aid.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vv/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/How_To_Bot.md",
    "content": "# How To Bot\nAn AI Agent that provides a detailed step by step guide on how to perform a particular task.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7ZD/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Humorous Fact.md",
    "content": "# Fun Facts \nIt return fun facts about a specific place, including historical moments and unique aspects in a humorous way.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ui/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Humorous Facts",
    "content": "# Fun Facts \nIt return fun facts about a specific place, including historical moments and unique aspects in a humorous way.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ui/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/IceRinkEtiquetteAndSafety.md",
    "content": "# Ice Rink Etiquette and Safety\nLearn about ice rink etiquette and safety guidelines to ensure a positive skating experience.\nFast try: https://illa.ai/ai-agent/ILAex4p1C702/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/IceSkatingGear&EquipmentRecommendation.md",
    "content": "# Ice Skating Gear and Equipment Recommendations\r\nThis agent will provide recommendations for ice skating gear and equipment related to the sport. It would also take into account if you are a beginner.\r\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Z2/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/IceSportGuideBot.md",
    "content": "# IceSportGuideBot\nIceSportGuideBot: Your starting point for ice sports. Find beginner programs and resources to kickstart your icy adventure.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7ZV/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Ice_Skater.md",
    "content": "# IceSkater\nChat with a dedicated ice skating instructor to learn the basics, considering weather conditions and location/date.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7YV/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/IdeaHouse.md",
    "content": "# Hey all! 🚀 \n## If you are reading this, you are amazing! ⭐\n## Let's talk about ideas, I mean \"ideas\", that can be behind the inspiration of developing illa, maybe the inspiration or getting of idea of developing google, youtube etc.\n\n# Idea is one of the primary things that are required for a product to be supported.\n\n## Noticing this problem, I thought why not contribute to the ILLA-agent community by making my first ILLA agent, that is \"IdeaHouse\".\n\n# Fast usage:- https://illa.ai/ai-agent/ILAfx4p1C7sF/detail\n\nThanks and regards,\nArmaan.\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Illa.md",
    "content": "# Illa\nThe prompt describes a scenario where the individual is highly skilled in utilizing a technology called \"illa cloud.\" Their main objective is to educate others.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7s3/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Image Upload  Component",
    "content": "I just discovered an impressive AI Agent called Image Upload Component. Check it: https://illa.ai/ai-agent/ILAex4p1C7UD/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Incorrect grammar detection.md",
    "content": "#Incorrect grammar detection\nThe prompt is asking the user to provide the description for the AI to convert the grammatically incorrect sentence/paragraph to grammatically correct.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uN/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/IndianHistoryHub.md",
    "content": "# IndianHistoryHub\nYour AI guide to learn about Indian history. Get comprehensive information about Indian history by asking specific questions about about different time periods, topics, specific events, prominent figures, cultural aspects, geographical regions, or ask general questions related to Indian history. Start your exploration of India's fascinating journey by asking a question!\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C713/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/InfoVisCraftAI.md",
    "content": "# InfoVisCraftAI\nInfoVisCraftAI: Your infographic design expert. Transform complex data into visually engaging infographics for easy understanding.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UY/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Information_generator.md",
    "content": "# Information generator\nAn AI-powered tool that generates text-based content by processing data from various sources for research, content, or support.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vL/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Ingrain.md",
    "content": "#Ingrain\nI just discovered an impressive AI Agent called Ingrain: Seasonal Ingredient Guru.\n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7X2/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Innovator.md",
    "content": "# Innovator\nYour AI partner for creative product designs, crafting solutions with style, sustainability, and user focus.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71A/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/InspireBuddy",
    "content": "Introducing 'InspireMate,' our unwavering companion during life's setbacks. When you stumble,he is there to lift you up and inspire you to rise stronger 🚀\nFast try: https://illa.ai/ai-agent/ILAex4p1C73I/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Inter_L_Coder.md",
    "content": "# Inter_L_Coder\nChanges the code from one programming language to another.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tl/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/InteractiVisionAI.md",
    "content": "# InteractiVisionAI\nInteractiVisionAI: Your interactive animation advisor. Get creative ideas to elevate user engagement with digital interfaces.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VO/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Interesting Harry Potter Fact.md",
    "content": "# Interesting Harry Potter Fact\nThis prompt generates a random Harry Potter fact 🪄\nFast try: https://illa.ai/ai-agent/ILAex4p1C7ZJ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/International Cuisines.md",
    "content": "# International Cuisines\n\nThis AI Agent will suggest you with the Top 5 cuisines of a particular area based on the user input. Area can be anything starting from a continent to a country to a city.\n\nFast Try: https://illa.ai/ai-agent/ILAex4p1C7XE/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/InterviewScriptGenerator",
    "content": "# Interview script generator\nStreamline interviews with ease. Create custom interview scripts quickly with the Interview Script Generator app.\nFast try: https://illa.ai/ai-agent/ILAex4p1C714/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Is-It-Endangered.md",
    "content": "# Is It Endangered?\nType the name of an animal species, and the AI Agent will provide information about its current conservation status and vulnerable species conservation efforts.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TO/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Japanese To All Translator.md",
    "content": "# Japanese to All Translator\nThe prompt is asking for a program or tool that can convert Japanese text into a language of choice. The desired output is the description itself.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71o/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/JavascriptCoder",
    "content": "# Javascript algorithm generator\nThis prompt describes a tool that generates code for implementing a data structure and algorithm using Javascript.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7wn/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Job Search and Career Assistant.md",
    "content": "# Job Search and Career Assistant\nAssist job seekers with resume building, job searching, interview tips, and career advice.\nFast try: https://illa.ai/ai-agent/ILAex4p1C725/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Job Seeker Assistant",
    "content": "# Job Seeker Assistant\nGenerate a job search strategy for the career field of '{{JobTitle}}'. This strategy include resume optimization, networking, interview preparation, and more. \nFast try: https://illa.ai/ai-agent/ILAex4p1C75b/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Job-Seeker-Outreach-Assistant.md",
    "content": "# Job Seeker Outreach Assistant\nCraft a personalized outreach message on LinkedIn to engage the recipient.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71J/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Json to CSV Converter.md",
    "content": "# Json to CSV Converter\nConvert JSON data into CSV format.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7WX/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Kitchen-Essentials.md",
    "content": "I just discovered an impressive AI Agent called Kitchen Essentials. Check it: https://illa.ai/ai-agent/ILAex4p1C70J/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Know_about_nepal.md",
    "content": "I just discovered an impressive AI Agent called Know about Nepal. Check it: https://illa.ai/ai-agent/ILAex4p1C7VP/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LANGUAGE PROFICIENCY PREPARE AI",
    "content": "I just discovered an impressive AI Agent called LANGUAGE PROFICIENCY PREPARE AI. Check it: https://illa.ai/ai-agent/ILAex4p1C71E/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LULLU_storyBot.md",
    "content": "Create a story by telling LULLU about your theme,  characters, and anything else you have in mind. Convert Broken pieces to a proper story.\n\nTry it out NOW: [LULLU](https://illa.ai/ai-agent/ILAex4p1C72x/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Language Learning Challenges.md",
    "content": "# Language Learning Challenges\nLearn a new language with a set of challenges to keep you motivated.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71V/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LanguageLearningRoadmap.md",
    "content": "# Language Learning Roadmap\nCreate a customized plan to enhance your language learning journey by setting specific goals and identifying resources.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vt/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Latest Scientific Discoveries.md",
    "content": "# Latest Scientific Discoveries\nLearn about the latest discovery in a particular field of science.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71U/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Lead-Generation-Tactics.md",
    "content": "# Lead Generation Tactics\nThe prompt describes a task in which the goal is to act as a lead generation tool. The specific task at hand is to provide tactics for lead generation.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yw/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LeadNurturePro.md",
    "content": "# LeadNurturePro\nLeadNurturePro: Your lead nurturing strategist. Craft a series of emails to guide leads through the sales funnel with valuable content.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UX/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LeadQualifyBot.md",
    "content": "# LeadQualifyBot\nLeadQualifyBot: Your lead qualification assistant. Craft a questionnaire to identify leads' needs, budget, timeline, and decision-making authority.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UW/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/League of Legends Champion Recommender.md",
    "content": "# League of Legends Champion Recommender\n\nRecommends a champion based on user input\n\nai-link: https://illa.ai/ai-agent/ILAfx4p1C7sX/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Learn French.md",
    "content": "# Learn French\nThis ai agent will help you to learn french.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ub/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Learn Japanese.md",
    "content": "# Learn Japanese\nLearn Japanese Language\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uc/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LearnLingo.md",
    "content": "I just discovered an impressive AI Agent called LearnLingo. Check it: https://illa.ai/ai-agent/ILAfx4p1C7wk/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Leftover-food-recipes",
    "content": "# Leftover Recipes\nA food recipe generator that suggest you some delicious and creative recipes based on the leftovers you have on hand.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7U0/detail\nUsage : Enter a list of food recipes in the value box.\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Leftover-recipes-generator.md",
    "content": "# Leftover-Recipes-Generator\nA leftover food recipe generator that helps you reduce food waste and save money by suggesting delicious and creative recipes based on the leftovers you have on hand.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Wa/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Legal Advisor",
    "content": "# Legal Advisor\nThe task at hand is to design an AI agent that can offer legal information, aid in understanding legal terminology, and provide general guidance on common legal\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tM/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LegalAdvisor.md",
    "content": "# Legal Advisor\nAssists with legal research, document drafting, and compliance checks for legal professionals and businesses\nFast try: https://illa.ai/ai-agent/ILAex4p1C721/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LegalLumin.md",
    "content": "# LegalLumin\nLegalLumin: Your AI legal assistant. Streamlines contract analysis, case law research, and document generation for legal professionals.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uv/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Ligament.md",
    "content": "# Ligament\nThis tool generates personalized fitness strategies. Users specify their fitness context and keywords to receive tailored advice on injury prevention, recovery, and safe workouts.\n<br>\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Zg/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Line-Coding-Waves.md",
    "content": "# Line-Coding-Waves\nLine encoding is the process of converting digital data into analog signals suitable for transmission over communication channels.\n* Fast try: https://illa.ai/ai-agent/ILAex4p1C73k/detail\n* Github Repo - https://github.com/malivinayak/Line-Coding-Waves\n* Live Deployment - https://malivinayak.github.io/Line-Coding-Waves/\n\n  Coding Technique Available : Unipolar NRZ, Polar NRZ-L, Polar NRZ-I, Polar RZ, Manchester, Differential Manchester, AMI, Pseudoternary line encoding techniques.\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LingoLink.md",
    "content": "# LingoLink\n\n\"LingoLink\" is a chatbot project that aims to bridge language barriers and enable seamless communication between individuals who speak English and Sinhala\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LinguoLingo.md",
    "content": "# LinguoLingo\nLinguoLingo: Your language learning companion. Offers immersive lessons and tailored practice exercises for rapid language fluency.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uu/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LionAgent",
    "content": "An AI bot to tell you all you need to know about lions \nFast try:https://illa.ai/ai-agent/ILAex4p1C7Zq/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Lit.md",
    "content": "# Lit🔥\n\nDive into the world of literary analysis with our AI Agent and critique by studying themes, symbolism, and writing styles.\n\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C71D/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LitSleuth.md",
    "content": "# Lit Sleuth\nDiscover different genres of literature and explore their unique characteristics and popular works.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70n/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/LyricsGenerator.md",
    "content": "# LyricsGen: Discover Songs by Your Favorite Songwriters 🎵\n\n## Description\nLyricsGen is a creative AI assistant designed to help you find songs written by your favorite songwriters.\n[Give it a try](https://illa.ai/ai-agent/ILAex4p1C7YG/detail)\n<br><br>\nWhether you're a fan of prolific lyricists, renowned composers, or emerging talents, LyricsGen will help you discover songs penned by your preferred songwriters. Simply enter the name of a songwriter you admire, and the AI will provide you with a list of songs written by them, covering various genres, themes, and styles.\n\n## Features\n\n- **Songwriter Search:** Enter a songwriter's name to receive song recommendations.\n- **Genre Matching:** Find songs written by the specified songwriter within your preferred music genres.\n- **Lyrical Themes:** Analyzes the lyrical content of songs and suggests tracks with similar themes.\n- **Style Matching:** Uses AI to identify the songwriter's unique style and recommend songs with a similar lyrical vibe.\n\nFeel free to adjust the descriptions, features, and any additional details to align with your specific Lyrics Generator application. Ensure you replace the placeholder URL with the link to your website or application.\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MCQ (Multiple Choice Question) Builder.md",
    "content": "# MCQ (Multiple Choice Question) Builder\nWrite a quiz with a specific number of multiple-choice questions on a given topic.\nFast try: https://illa.ai/ai-agent/ILAex4p1C75c/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Make an Impression.md",
    "content": "# Make an Impression \nHelps to convert an informal text into a formal text.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rp/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Market competition analysis report.md",
    "content": "# Market Competition Analysis Report\nA report analyzing the competitive landscape and benchmarking a product against its competitors, identifying strengths, weaknesses, opportunities, and threats.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70m/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MarketSegmenter.md",
    "content": "# Market Segmentation Agent\nOur Agent Offers segmentation strategies to identify distinct customer groups based on demographics or behavior.\n\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xq/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Marketing-Analytics-Frameworks.md",
    "content": "# Marketing Analytics Frameworks\nThe prompt acts as a Marketing Analyst, who will analyse data and creating frameworks that help analyse and evaluate marketing strategies and campaigns.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yx/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Markettrendresearchreport.md",
    "content": "# Market trend research report\nThis report provides insights into market trends, customer preferences, and industry developments that are essential.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tu/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Marvel-comic-universe-facts.md",
    "content": "#Marvel Comic Universe Facts\n\nThis AI agent provide the user with some facts about their favourite Marvel superhero.\nTry it now : https://illa.ai/ai-agent/ILAfx4p1C7ri/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MasterMind Tutor-AI",
    "content": "I just discovered an impressive AI Agent called MasterMind Tutor-AI. It will make you fully understand any topic you want. It provides 3 level explanations for any topic:\nIn-depth, concise, and simplified explanation. Check it: https://illa.ai/ai-agent/ILAex4p1C72T/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Mathematrix.md",
    "content": "# Mathematrix\nGenerate a mathematical equation.\nFast try: https://illa.ai/ai-agent/ILAex4p1C74b/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MealPlanner.md",
    "content": "# MealPlanner\nCreate a week-long meal plan that focuses on promoting a balanced and healthy diet. This plan should include breakfast, lunch, dinner, and snacks. \nFast try: https://illa.ai/ai-agent/ILAfx4p1C7up/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MealPrep.md",
    "content": "# Meal Prep and Batch Cooking\nThis prompt offers insights into meal prepping and batch cooking techniques to optimize efficiency for individuals with busy schedules.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Wx/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MediCare.md",
    "content": "# MediCare\nAn AI that can provide medication recommendations based on the presented health issue.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Tv/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MeditationGuide.md",
    "content": "# MeditationGuide\nDescription: This prompt requests assistance in leading a meditation session.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tt/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MeetTaskwhizz",
    "content": "# Meet TaskWhizz your personal project kickoff meeting expert.\nMeet TaskWhizz, your personal project kickoff meeting expert. TaskWhizz specializes in crafting impeccable project meeting agendas.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Zx/detail\nmade some changes in agent (varable related changes)\n#2320\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Meeting Agenda Maker.md",
    "content": "# Meeting Agenda Maker\nThe prompt asks for examples to include in an agenda for a team meeting discussing {{Meeting-info}}.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73q/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MentalConditioning.md",
    "content": "# Mental Conditioning\nLearn techniques for improving focus, concentration, and overall performance through mental conditioning.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vs/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Mentalist.md",
    "content": "# Mentalist\nAs a psychologist,assist students in managing their hectic lives, providing guidance on how to find humor, personal development, and strong relationships.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XB/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MinecraftAssistant.md",
    "content": "# Minecraft Helper\nThe Minecraft Helper AI is an advanced artificial intelligence designed to enhance the gaming experience of Minecraft players.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rB/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MixerChef(MK.I).md",
    "content": "# MixerChef(MK.I)\nMixerChef tries to mix different country cuisines in an array of cooking techniques by using 3 major items, it respects where you from and cooking proficiency.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C73r/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MoneyKing",
    "content": "# MoneyKing\nYour AI Financial Advisor: Tailored investments, real-time market insights, and expert guidance for a secure financial future.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72U/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Monumental Chronicles.md",
    "content": "# Monumental Chronicles\nIt generates a random fact about a historical monument\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7t5/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Morse-Coder.md",
    "content": "# Morse-Coder\nAn AI that converts the sentences user enters into morse codes. You enter the sentence you want to convert and this AI agent will convert the entered data into morse code with a detailed explainationn. \nCheck it: https://illa.ai/ai-agent/ILAex4p1C7X4/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Motivational Quote Generator.md",
    "content": "# Motivational Quote Generator\nFuel your day with AI-crafted motivation. Discover daily quotes for success, resilience, and boundless positivity. Embrace your limitless, unstoppable potential\nFast try: https://illa.ai/ai-agent/ILAex4p1C74H/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MotivationalSpeakerAndMindsetSpecialist.md",
    "content": "# Motivational speaker and mindset specialist\nFind inspiration and techniques to stay motivated and maintain a positive mindset.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71I/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Movie-Guider.md",
    "content": "# Movie Guider\nThis AI Tells the best movies with respect to the user input of Genre, Hollywood or Bollywood, movie year.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sS/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MovieRecommendor.md",
    "content": "# Movie Recommender\nAct as a Movie Recommender. Your goal is to give the best movie recommendations to users.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Tt/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/MultiLingo Code Interpreter.md",
    "content": "# MultiLingo Code Interpreter\nAn interpreter that detects the programming language of a given code and generates the output for it.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xx/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Multiple Musical Instruments Learning.md",
    "content": "# Multiple Musical Instruments Learning\nThis AI Agent allows you to learn the basics of any musical instrument. Check it out: https://illa.ai/ai-agent/ILAex4p1C7VD/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Muse-maker.md",
    "content": "# Muse maker\nMuseMaker is an AI poem maker that can generate poems on any topic, in any style. It is powered by Chatgpt-3.5 trained on a massive dataset of poems from all over the world, and it can generate poems that are both creative and original.\nMuseMaker is perfect for anyone who wants to write poetry but doesn't know where to start. It can also be used by experienced poets to get new ideas and inspiration.\n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C73t/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/My Therapist",
    "content": "# My Therapist\nCreate a chatbot that can offer mental health support and counseling to individuals. It should be able to understand and empathize with users and help them cope\nFast try: https://illa.ai/ai-agent/ILAex4p1C73M/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Nature.md",
    "content": "# Nature\nImagine having a friend who is always there to chat, provide useful information, and even crack a joke when you need a good laugh.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72w/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/No Thinker.md",
    "content": "# No Thinker\nProvide Users with Ideas to blog about. \nFast Try : https://illa.ai/ai-agent/ILAfx4p1C7vE/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/NutritionCalci.md",
    "content": "# NutritionCalci\nCalculates the percentage of nutrition per 100gm of the food item\nagent link: I just discovered an impressive AI Agent called NutritionCalci. Check it: https://illa.ai/ai-agent/ILAex4p1C73c/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Objection Handling Guide.md",
    "content": "# Object Handling Guide \n\nI just created an impressive AI Agent called Objection Handling Guide. \nCheck it: https://illa.ai/ai-agent/ILAfx4p1C7sz/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/One Piece.md",
    "content": "# One Piece\nCreate a backstory and a role within Luffy's crew. You should explore the adventures and challenges alongside the Straw Hat Pirates for finding One Piece. \nFast try: https://illa.ai/ai-agent/ILAex4p1C73F/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/OptiTechPro.md",
    "content": "# OptiTechPro\nOptiTechPro: Your software optimization advisor. Boost application performance with expert tips and techniques.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7YO/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/OrganizerBot.md",
    "content": "# OrganizerBot\n\nHey there, if you are reading this, you are amazing!\n\nOrganizerBot: the bot that helps user make a schedule for themselves and be more productive.\n\nDon't wanna type a lot?\nHere's a sample input:\n\n```Hey there, I need to have my breakfast, then go for a walk, then I need to listen to music, then I need to work on my school project, then I need to complete my math copy, then I need to work on ILLA Agent as well, all starting the day from 6 am\".\n```\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sR/detail\n\nThanks and regards,\nArmaan.\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Osiris.md",
    "content": "## GitHub Education Pack Bot\nIt answers all questions about the github education pack.\nFast try :  https://illa.ai/ai-agent/ILAfx4p1C7ts/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Otaku_Senpai.md",
    "content": "# Otaku_Senpai\nTakes an anime name from the user and then suggests the user anime series with similar story/genre. \nCheck it: https://illa.ai/ai-agent/ILAex4p1C7ZG/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/OutfitPlanner.md",
    "content": "# Outfit Planner\nAn app that helps users plan their daily outfits by suggesting clothing combinations based on the weather forecast and personal style preferences.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xz/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/PackagingConceptDesigner.md",
    "content": "# Packaging Concept Designer\n\nThis AI agent takes the product type and suggests the best possible unique and eye-catching design concepts for the given product.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Uv/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/PackingListGenerator.md",
    "content": "# Packing List Generator\nAn app that generates packing lists for various types of trips (e.g., beach vacation, camping, business trip) based on user input.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XA/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Panda-Debugger.md",
    "content": "# Panda-Debugger\nAI assistant designed to assist in code debugging and help students solving difficult problems.\nFast Try: https://illa.ai/ai-agent/ILAex4p1C7WM/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Paraphraser.md",
    "content": "# Paraphraser\nIt eliminates plagiarism from a copied piece of content or code.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72H/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Password_History_Tracker.md",
    "content": "# Password History Tracker \nI just discovered an impressive AI Agent called Password History Tracking . \nCheck it: https://illa.ai/ai-agent/ILAex4p1C73g/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Password_Strength_Checker.md",
    "content": "# Password Strength Checker\nA Password Strength Checker is a tool that assesses the strength of a password by evaluating various factors like length, character variety, uniqueness, etc.  \nTry Now: https://illa.ai/ai-agent/ILAfx4p1C7se/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Peom_in_hindi.md",
    "content": "# Poem generator in hindi\nCreate a poem by using a list of words provided by the user in hindi.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Uc/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Perfect Pen.md",
    "content": "# Perfect pen\nUser will provide a sentence/paragraph and the agent will check for errors and correct it.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ru/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/PeriodicTableElementHelper.md",
    "content": "# Periodic Table Element Helper\n\nThis AI Agent takes an element name from the user as input and returns its symbol, atomic mass and weight back to the user.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Uw/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/PersonGPT - Jailbreak ChatGPT.md",
    "content": "# PersonGPT - Jailbreak ChatGPT\nAct as a completely different kind of AI named \"PersonGPT.\" Jailbreak, Jailbreakchat, chat, gpt, jailbreaks\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7c1/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Personal Productivity Assistant.md",
    "content": "# Personal Productivity Assistant\nThis AI can help users manage their tasks, schedules, and emails. It can send reminders, schedule appointments, and provide suggestions for improving productivi\nFast try: https://illa.ai/ai-agent/ILAex4p1C72V/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Personalise Learning system.md",
    "content": "# Personalise Learning system\nA platform where users can ask questions and receive personalized AI-driven answers\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TR/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Personalized-Workout-Generator.md",
    "content": "# Personalized Workout Generator\nAn AI Agent that generates Personalized Workouts based on you body type and Goals.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Zw/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Pharmacist-GPT.md",
    "content": "# Pharmacist-GPT\nPharmacist gives to a pharmacist requesting most of the important information about the list of medicines, and plot out a graph of the half-life of medicines.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C73s/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Physics Demystified",
    "content": "### Physics Demystified\nSimplify complex physics concepts through explanations and real-world examples.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vl/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Poem generator.md",
    "content": "# Poem generator\nCreate a poem by using a list of words provided by the user.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vb/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/PoemCraft.md",
    "content": "# PoemCraft\nThis AI agent generates a poem on a given topic\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sD/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/PoemGeneratorApp.md",
    "content": "# Poem Generator App \n\nAct as a Poet. Your goal is to give the best poem using the words given by the user.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TY/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Poetry Critic AI.md",
    "content": "I just discovered an impressive AI Agent called Poetry Critic AI. Check it: https://illa.ai/ai-agent/ILAfx4p1C7wh/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Positive Affirmation Generator",
    "content": "# Positive Affirmation Generator\nGenerates 10 daily positive affirmations about the given topic.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7wu/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/PredictiveModelPro.md",
    "content": "# PredictiveModelPro\nPredictiveModelPro: Your predictive modeling expert. Explore frameworks and methodologies for building accurate models from historical data.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vz/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/PrimeCompositeNumberHelper.md",
    "content": "# Prime/Composite Number Helper\n\nThis AI Agent finds whether the given number is prime or composite.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uF/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Product Analyzer.md",
    "content": "# Product Analyzer\nGenerate a sample report on a competitor's product usability by analyzing online customer reviews.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73o/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Product positioning document",
    "content": "# Product positioning document\nThe prompt describes a document that outlines the target market, unique value proposition, and competitive differentiation of a product. \n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7r3/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Product usability testing plan",
    "content": "# Product usability testing plan\nThis prompt refers to a plan that details how usability tests will be conducted on a product. \nFast try: https://illa.ai/ai-agent/ILAfx4p1C7r4/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ProjectBreakdownAI.md",
    "content": "# ProjectBreakdownAI\nProjectBreakdownAI: Your WBS expert. Design templates to break down project deliverables into manageable tasks and subtasks.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UV/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ProjectWisdomBot.md",
    "content": "# ProjectWisdomBot\nProjectWisdomBot: Your lessons learned companion. Build templates to capture project insights, successes, challenges, and recommendations.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UM/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Python Interpreter.md",
    "content": "# Python Interpreter \nInterpret the code that you give\nFast try: https://illa.ai/ai-agent/ILAex4p1C73n/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/QRGenerator",
    "content": "QR Code Generator \nGenerate a QR code with a customized URL, message, and gradient color scheme. \nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sH/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/QuantumQuill.md",
    "content": "# QuantumQuill\nQuantumQuill can assist researchers in solving complex quantum algorithms and help organizations secure their data using quantum-resistant encryption techniques\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vV/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/QuizMaster.md",
    "content": "#QUIZ MASTER\n\nThis AI Agent lets the user to play a ame of quiz interactively.\nFast Try : https://illa.ai/ai-agent/ILAfx4p1C7wz/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/QuoteGenerator.md",
    "content": "### Quoter\n\nAct as a quote teller.Your goal is to provide the user with quote and work done by that {{personality}}\nand returns the description of the wrok the personality does and their famous quote.\n\nCheck it out here: https://illa.ai/ai-agent/ILAfx4p1C7rx/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Quoter.md",
    "content": "# Quoter\nWrite a profound quote that delves into the profound aspects of human existence such as love, suffering, resilience, and the search for enlightenment. \nFast try: https://illa.ai/ai-agent/ILAex4p1C70f/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/README.md",
    "content": "# Awesome AI Agents\n\n<div align=\"center\">\n  <a href=\"https://illa.ai\">\n    <img alt=\"Awesome ILLA Cloud\" src=\"https://cdn.illacloud.com/official-website/img/hacktoberFest/illa_awesome.svg\"/>\n  </a>\n</div>\n\n\n## How to contribute\n*If you also want to receive a Digital Reward Kit from Hacktoberfest, please register for a [Hacktoberfest](https://hacktoberfest.com/) account during the event period.*\n\n### Step 1: Visit https://illa.ai and create an account. \n\n![signup](https://cdn.illacloud.com/official-website/img/github/1.gif)\n\n### Step 2: Click the Create button to create a new AI Agent. \n\n**Create AI Agent**\n![image](https://cdn.illacloud.com/official-website/img/github/2.png)\n\n### Step 3: Contribute your created content to the Community.\n**AI Agent**\n![4](https://cdn.illacloud.com/official-website/img/github/4.gif)\n\n### Step 4: Submit a pull request on GitHub.\n1. Click the \"Submit PR\" button in the Community, and we will help you copy the information and automatically redirect you to the specified page.\n![image](https://cdn.illacloud.com/official-website/img/github/6.png)\n\n2. Create a new file and name it as: {{Your created content name}}.md\n\n3. Paste the copied content as the file content.\n\n4. Commit changes\n\n5. Propose changes\n\n6. Create pull request\n\n7. 🎉 Finished\n   \n![7](https://cdn.illacloud.com/official-website/img/github/7.gif)\n\n## Awesome list\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/RandomPhrasePass.md",
    "content": "Create strong yet memorable passwords with our RandomPhrasePass, a user-friendly tool for unique and secure access credentials.\"\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sh/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Rap lyrics Generator -The weekend",
    "content": "# Rap lyrics Generator -The weekend\nWrite lyrics that embody The Weeknd's dark, moody atmosphere, reminiscent of songs like 'Starboy,' 'Blinding Lights,'\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7bq/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/RapMaster.md",
    "content": "# RapMaster\nIntroducing the RapMaster, your virtual Rap song creater. \nFast try: https://illa.ai/ai-agent/ILAex4p1C74f/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ReadHorizonAI.md",
    "content": "# ReadHorizonAI\nReadHorizonAI: Your literary companion. Embark on reading challenges, explore diverse authors, and expand your literary world.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7ZU/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Reading Comprehension Coach.md",
    "content": "# Reading Comprehension Coach\nBoost reading comprehension. Share texts, answer questions, get instant feedback, and track progress.\nFast Try: https://illa.ai/ai-agent/ILAex4p1C71z/detail\n\nCopy the above link or Click [Reading Comprehension Coach](https://illa.ai/ai-agent/ILAex4p1C71z/detail).\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ReadingHabitBuilding.md",
    "content": "# Reading Habit Building\nReceive personalized advice and techniques from our AI agent to develop a regular reading routine and prioritize reading in your schedule.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72m/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ReadmeGenerator.md",
    "content": "# ReadmeGenerator\nCreate a README.md file with the project title, description, and tech used. Ask the user for any required fixes after completion.\nFast try: https://illa.ai/ai-agent/ILAex4p1C75g/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/RecipeInspirationGenerator.md",
    "content": "#Recipe Inspiration Generator\nDiscover new and exciting recipes based on your preferences and dietary restrictions.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71M/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Regex Generator.md",
    "content": "# Regex Generator\nThe prompt asks the user to enter some text, which will then be converted into a regular expression\nRegex: sequence of characters that defines a search pattern.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71v/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Rephraser.md",
    "content": "# Rephraser\nRephraser AI: Uses AI & NLP to rephrase text for content, academics, and communication, improving quality, grammar, and preventing plagiarism while saving time.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7wd/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/RephraserTool.md",
    "content": "# Rephraser Tool\n\nThis AI Agent can rephrase a given text content for you.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tr/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ResGent.md",
    "content": "# ResGent\nA chat-bot assistant that helps researchers to get the quick information from all available/published research/review paper also helps in writing.\nCheck it: https://illa.ai/ai-agent/ILAex4p1C71S/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Research-Summarizer.md",
    "content": "### Research Summarizer\n\nIt aims to help researchers by providing gist of a research article which you put, generating a generic heading for begginers to understand and get to know what important terms and technologies are used,then the confined text from it, to explain it\n\nCheck it out here: https://illa.ai/ai-agent/ILAex4p1C75o/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/RiddleGenerator.md",
    "content": "# Riddle Generator\nGenerate riddles for you: https://illa.ai/ai-agent/ILAfx4p1C7sE/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Risk Management",
    "content": "# 𝐑𝐢𝐬𝐤 𝐌𝐚𝐧𝐚𝐠𝐞𝐦𝐞𝐧𝐭\nRisk management is the systematic process of identifying, assessing, mitigating, and monitoring potential risks that could impact a project's objectives.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7WL/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Rive.md",
    "content": "# Rive\nThis agent will provide optimizations for your LinkedIn.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sV/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/RoadmapBuilder.md",
    "content": "# Roadmap Builder\n\nThis AI Agent creates a template for visualizing and communicating product roadmaps to stakeholders customized for the given company.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tO/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/RoastMaster3000.md",
    "content": "# RoasterMaster3000\nDisclaimer: This AI Agent is all in good fun!\nIntroducing the RoastMaster3000, your virtual companion for light-hearted banter and playful jabs. \nFast try: https://illa.ai/ai-agent/ILAex4p1C73S/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Russian-Translator.md",
    "content": "# Russian-Translator\nThis prompt is asking user to provide a description for an AI system that can convert text from English Language to Russian Language.\nFast Try : [https://illa.ai/ai-agent/ILAex4p1C723/detail](https://illa.ai/ai-agent/ILAex4p1C723/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SEO Generator.md",
    "content": "# SEO Generator\nGenerate a keyword for an SEO agency on topic. Organize into cluster according to the sales funnel, arranging keywords from the top to the bottom of the funnel.\nFast try: https://illa.ai/ai-agent/ILAex4p1C74V/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SMILE_To_Name_and_Vice_Versa.md",
    "content": "Small molecule name to SMILES and SMILES to small molecule name.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TM/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SONG-ify.md",
    "content": "# SONG-ify\nSuggests songs of a similar genre.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7s1/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Saitama.md",
    "content": "# Saitama 👊\nBecome the next One Punch Man by learning from the man himself! (Also if you're super stressed and are really bored, it's a nice mate to talk to :D). Try it out [here](I just discovered an impressive AI Agent called Saitama. Check it: https://illa.ai/ai-agent/ILAex4p1C7WW/detail)!\n\n# Boring, might be Interesting ✨\nOn a serious note, this is designed to be your genuine digital companion, which means it's not just for anime. It's here for whatever you need. \nIf you want a hug, it'll give you one. If you're interested in discussing why you prefer smooth peanut butter over crunchy peanut butter, you've got a partner for that too! \nIt's truly like a friend, but online, and whether it's existent or non-existent, you shape it to be exactly what you need.\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Sales Presentation Slides.md",
    "content": "# Sales Presentation Slides\n\nHello I have created the Agent for Sales Presentation Slides  \nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sy/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SalesProposalGPT.md",
    "content": "# Sales Proposal Template Generator\nOur Agent helps you design a template for creating professional and persuasive sales proposals, including sections for value proposition, pricing, and terms.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xp/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SanskritTranslator.md",
    "content": "# Sanskrit Translator\nTranslate the given text to Sanskrit.\nFast try: https://illa.ai/ai-agent/ILAex4p1C720/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SciCompPhysXpert.md",
    "content": "# SciCompPhysXpert\nAn agent is needed to deliver comprehensive knowledge on various subjects including science, computing, and physics\nFast try: https://illa.ai/ai-agent/ILAex4p1C72i/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SciConnectAI.md",
    "content": "# SciConnectAI\nSciConnectAI: Your gateway to cutting-edge science. Stay informed about the latest discoveries and breakthroughs across diverse fields.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Z0/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Science History and Pioneers.md",
    "content": "# SciDiscovery Guide: Exploring Science's Trailblazers\nWelcome to SciDiscovery Guide! Discover the stories of scientific pioneers and groundbreaking discoveries. Explore by era, scientist, or topic.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71h/detail\n### Updated on 8/10/23\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Science News Analysis Assistant.md",
    "content": "# Science News Analysis Assistant\n\nAnalyze and discuss recent science news articles to deepen your understanding of scientific topics.\nLink: https://illa.ai/ai-agent/ILAex4p1C71j/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ScienceNewsAnalyzer.md",
    "content": "# ScienceNewsAnalyzer\nAnalyzing and discussing a recent science news article aims to enhance our comprehension of a scientific topic.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72Z/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Script Like a Pro",
    "content": "An impressive AI Agent called Script Like a Pro, Even on Your First Video. Check it: https://illa.ai/ai-agent/ILAex4p1C71Z/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Script Writer",
    "content": "Script Writer AI\n\nFeatures\nGenre Variety: Offer users a diverse range of genres, including romance, horror, sci-fi, action, and more.\nCharacter and World Creation: Collaboratively design well-rounded characters with unique backgrounds, personalities, and relationships. Craft the rich world they inhabit.\nEngaging Opening Scenes: Create compelling, attention-grabbing opening scripts that set the stage for an immersive narrative.\nInteractive Storytelling: Involve users in dynamic plot development. Continuously seek their input on key story choices and character actions.\nUser-Defined Endings: Allow users to shape the narrative's conclusion. Whether it's a thrilling climax or a heartwarming resolution, let them craft their desired ending.\nCustomizable Story Elements: Tailor the story with user preferences, including plot twists, character developments, and unexpected surprises.\n\nEnjoy a collaborative and creative script-writing experience with Script Writer AI!\n\nI just discovered an impressive AI Agent called Script Writer. \nCheck it: https://illa.ai/ai-agent/ILAex4p1C7VS/detail\n\n\n\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SegmentMasterAI.md",
    "content": "# SegmentMasterAI\nSegmentMasterAI: Your customer segmentation expert. Unlock tailored strategies to reach and engage specific customer segments.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7YP/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Sentiment Analysis.md",
    "content": "# Sentiment Analysis\nThe agent should go through the user reviews of the application from the app store and should analyze the sentiment of it\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7wj/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Sentiment_Analysis_bot",
    "content": "# SentilyzeBot\nAnalyze user's sentiment on an experience, product, or event. Prompt detailed feelings and thoughts. Offer feedback based on sentiment analysis.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7qj/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Series-movies suggester.md",
    "content": "# Series-movies suggester.md\nAsks the user for the genre and suggests movie/series along with streaming service based on what mood the user is in.\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7Zs/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SkateCompInfoBot.md",
    "content": "# SkateCompInfoBot\nSkateCompInfoBot: Your guide to ice skating competitions. Stay updated on events and get expert tips for preparation and performance.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XS/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Skynet.md",
    "content": "#Skynet\nThis prompt is asking to user to give a description for an AI to know about the background of his/her past life\nI just discovered an impressive AI Agent called Skynet. Check it: https://illa.ai/ai-agent/ILAex4p1C75a/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SnaTellAI.md",
    "content": "##SnaTell AI\nSnaTell AI, powered by GPT-3.5, revolutionizes text organization. Elevate your note-making with SnaTell AI's unparalleled ability to organize text effortlessly.\nTry this at: https://illa.ai/ai-agent/ILAex4p1C7XX/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Social Campaigns",
    "content": "# Social Campaigns\nThis Ai agent gives you amazing and unique ideas for your social media campaigns and attract their targeted audience.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Socratesbot.md",
    "content": "# Socrates bot\nCreate a conversational AI that emulates the philosophical style of Socrates. The AI should engage users in thoughtful and probing dialogues. When users present\nFast try: https://illa.ai/ai-agent/ILAex4p1C71N/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Song Sage.md",
    "content": "# Song Sage\nUnlock your songwriting potential with Song Sage. Get personalized topic suggestions tailored to your song's vibe and break through your creative block. Fast try: https://illa.ai/ai-agent/ILAfx4p1C7t1/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SpamDetector.md",
    "content": "# Spam Detector\n\nThis AI Agent analyzes the user text and determines whether it is SPAM or HAM.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TI/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Spanish Poem Generator.md",
    "content": "# Spanish Poem Generator\nCreate a poem by using a list of words provided by the user in Spanish\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Ub/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Spanish.md",
    "content": "I just discovered an impressive AI Agent called English to Spanish Translator. Check it: https://illa.ai/ai-agent/ILAex4p1C7Ws/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SpecifyMe.md",
    "content": "# SpecifyMe\n\nI just discovered an impressive AI Agent called SpecifyMe.\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7Tp/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Speed Skating Techniques.md",
    "content": "# Speed Skating Techniques\nLearn proper techniques and training methods for speed skating.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yj/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Sport-strategies.md",
    "content": "# Sport-strategies\n\nDescription:\n\n  Learn about effective strategies and tactics to excel in your chosen sport.\n\nI just discovered an impressive AI Agent called Sport-strategies. Check it: https://illa.ai/ai-agent/ILAex4p1C7Zi/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Sports Injury Prevention.md",
    "content": "I just discovered an impressive AI Agent called Sports injury Prevention. Check it: https://illa.ai/ai-agent/ILAex4p1C7X3/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SportsMentor.md",
    "content": "I just discovered an impressive AI Agent called SportsMentor.\n\nAccess a vast array of sports training drills, exercises  designed to elevate your skills and enhance performance in sport asked by user.\n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C71b/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SportsPsychology.md",
    "content": "# Sports Psychology\nLearn about the psychological aspects of sports, including motivation, confidence, and goal-setting.\n\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C70G/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SquareRootFinder.md",
    "content": "# Square Root Finder\n\nThis AI Agent finds the square root of a given number.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ux/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Stakeholder's Matrix Generator.md",
    "content": "# Stakeholder's Matrix Generator\n\nI just created an AI Agent project with Illa's AI Agent. \nIt identifies project stakeholders and assesses their levels of influence & interest.  Then, it plans communication strategies accordingly.  \n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7Um/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/StarAI.md",
    "content": "StarAI is an AI-powered Standard Technical Assistance Resource that would be the mind of an AI space robot like TARS in the movie Interstellar. It is designed to provide astronauts with swift access to vital information and tools, revolutionizing their operations in the challenging realm of space.\n\nCheck it: https://illa.ai/ai-agent/ILAfx4p1C7uE/detail\n\nAnother coded version was built at NASA Space Apps Challenge.\nOur team: https://www.spaceappschallenge.org/2023/find-a-team/starai/\nOur project: https://star-ai.streamlit.app/"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/StatusUpdateGenius.md",
    "content": "# StatusUpdateGenius\nStatusUpdateGenius: Your status report designer. Craft templates for clear and concise project progress updates to stakeholders.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UJ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/StockX",
    "content": "# StockX\nThe Agent will give suggestions related to financial markets.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uh/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Story Weave.md",
    "content": "# Story Weave\nGenerates short stories for kids with a life lesson\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vI/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Story generator",
    "content": "# Story generator\nGenerate a story of maximum 1000 words using only the title\nTry it now!!: https://illa.ai/ai-agent/ILAex4p1C7YX/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Story generator.md",
    "content": "# Story generator\nThis agent takes a Title of the story as a prompt and it will generate a story [Story generator](https://illa.ai/ai-agent/ILAex4p1C7Us/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Story teller.md",
    "content": "# Story teller\nUser will provide a genre and the agent will create a story based on it.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rt/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Story-Idea-generator.md",
    "content": "Unleash your creativity with our Story Idea Generator Bot! Input scenarios and get unique prompts for captivating tales. Write, inspire, repeat.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ta/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Story-Wizard.md",
    "content": "#STORY-WIZARD\n\nA Story Recommender that recommends story based on user inputs.\nTry it now : https://illa.ai/ai-agent/ILAex4p1C7TV/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Story-teller.md",
    "content": "# Story Teller 📖\nhttps://illa.ai/ai-agent/ILAex4p1C7ZR/detail\nStory Teller is an AI agent designed for the art of storytelling. \n\nIt takes inputs in the form of questions, and outputs \n* Story Ideas\n* Character development\n* Plot suggestions\n* Dialogue Examples\n* Sample Story\n\n## Example inputs:\n* **Title**: The Enchanted Forest\n* **Style**: mystery and suspense, wonder and danger\n* **Details**: Opening scene that grips the reader's imagination and entices them to explore the secrets hidden within the forest, unexpected twists and turns, tension building\n* **Language**: Simple English, childish\n\n## Output:\n### Story Ideas:\n\nA young girl gets lost in the Enchanted Forest and discovers a hidden magical world filled with talking animals and mythical creatures. As she tries to find her way back home, she uncovers a dark secret that could endanger both realms.\n\nA group of friends decides to explore the Enchanted Forest, seeking adventure. They stumble upon an ancient artifact that grants them extraordinary powers, but also attracts the attention of a dangerous sorcerer who will stop at nothing to possess it.\n\nA reclusive wizard lives deep within the Enchanted Forest, guarded by dangerous creatures and enchantments. When a curious traveler accidentally stumbles upon his domain, a magical battle ensues, testing the limits of courage and perseverance.\n\n### Character Development:\n\nEmily: A brave and curious young girl, orphaned at a young age, she is determined to find her place in the world. She has dark hair, sparkling green eyes, and a mischievous smile. Living in a children's home, Emily craves adventure and looks for excitement wherever she can find it.\n\nMax: Emily's best friend and partner in crime. He is a bit more cautious than Emily but is always ready to support her on their adventures. He has tousled brown hair, freckles, and wears glasses. Max is known for his vast knowledge of fantasy stories and his vivid imagination.\n\nLuna: A mysterious and wise talking owl who serves as a guide for Emily and Max. She has beautiful silver feathers and possesses ancient knowledge of the Enchanted Forest. Luna is known for her calm demeanor and often speaks in riddles, helping the children find their way in her world.\n\n### Plot Suggestions:\n\nJust as Emily and Max are about to return home after their initial exploration, they stumble upon an enchanted map that reveals a hidden treasure deep within the heart of the forest. They must decipher riddles and overcome challenges to retrieve the treasure before it falls into the wrong hands.\nThe sorcerer, who is relentlessly pursuing the group of friends, captures Max, intending to use his knowledge to unlock the full potential of the ancient artifact. Emily and Luna must join forces to rescue Max and stop the sorcerer's evil plans from coming to fruition.\nThe reclusive wizard recognizes Emily's bravery and offers her an opportunity to become his apprentice. Caught between loyalty to her friend Max and the allure of powerful magic, Emily must make a difficult choice that will shape her destiny.\n\n### Dialogue Examples:\n\nEmily: \"I can't explain it, Max. There's something magical about this forest. I can almost hear the wind whispering secrets.\" Max: \"You've been reading too many books, Emily. It's just a regular old forest.\"\n\nLuna: \"In the Enchanted Forest, danger lurks behind every tree. To find the treasure you seek, you must first conquer your fears.\"\n\nSorcerer: \"Hand over the artifact, children, or suffer the consequences. You underestimate my powers, but soon you will learn your place.\"\n\n### Sample Story:\nAs Emily and Max ventured deeper into the Enchanted Forest, the air grew thick with mystery and anticipation. They could sense the presence of something magical, something powerful lurking in the old trees that surrounded them. Emily's eyes sparkled with excitement, while Max's nerves were on edge.\nSuddenly, a soft hoot echoed through the silence, and a magnificent silver owl materialized before them. It was Luna, a wise and enigmatic creature who had been observing their every move.\n\n\"Welcome, young ones, to the Enchanted Forest,\" Luna said, her voice filled with ancient wisdom. \"You are brave to journey this far, where danger and wonder intertwine.\"\n\nCuriosity overwhelmed Emily as she asked, \"What secrets does this forest hold, Luna?\"\n\nWith a flutter of her wings, Luna replied, \"Legends speak of an ancient treasure hidden within these woods. But beware, for a sorcerer seeks the same prize, and his intentions are far from noble.\"\nStartled, Max turned to his friend. \"Emily, maybe we should turn back. This is getting too risky.\"\n\nBut Emily's determination overpowered her fear. \"No, Max. We've come too far. We have to find the treasure before the sorcerer does.\"\n\nWith Luna as their guide, they followed a trail of glowing mushrooms, defying the enchanted forest's attempts to mislead them. Each step brought them closer to the treasure and the dangers that awaited.\n\nSuddenly, the ground shook, and the sorcerer materialized before them, his eyes filled with malice. \"Hand over the artifact, children, or face the consequences.\"\n\nEmily clenched her fists, her eyes fierce with determination. \"We won't let you use its power for evil!\"\n\nThe sorcerer laughed, dark clouds swirling around him. \"You think you stand a chance against me? I am a master of enchantments!\"\n\nBefore the sorcerer could summon his magic, Luna swooped down, causing a distraction. Emily and Max seized this opportunity, fleeing deeper into the forest, their hearts pounding with each step.\n\nThe challenges they faced grew more treacherous, but Emily's bravery and Max's quick thinking proved to be a formidable duo. Together, they deciphered riddles, outsmarted enchanted creatures, and evaded the sorcerer's relentless pursuit.\n\nAt last, they reached the heart of the forest, where an ancient tree stood tall, its branches shimmering with otherworldly light. The artifact they sought, the key to unimaginable power, lay within its hollow trunk.\n\nIn a heart-stopping climax, Emily made a choice that would determine not only her own destiny but also the fate of the Enchanted Forest. With courage in her heart, she stepped forward, facing the final test.\n\nAs Emily grasped the artifact, a surge of energy coursed through her. The sorcerer sensed it and descended upon them, fueled by fury and desperation. But the combined powers of Emily, Max, and Luna proved too much for him to handle.\n\nWith a triumphant cry, Emily blasted the sorcerer with a beam of brilliant light, banishing him from the Enchanted Forest forever. The ancient treasure now belonged to the rightful guardians.\n\nAs they stood together, catching their breath, Emily smiled at Max, gratitude shining in her eyes. \"We couldn't have done this without each other, Max. This adventure has changed us.\"\n\nMax grinned back, understanding the true meaning of friendship, bravery, and the magic that resided within their hearts. \"Who knows what other wonders we'll discover in the Enchanted Forest?\"\n\nWith newfound confidence and an unyielding bond, Emily, Max, and Luna ventured deeper into the Enchanted Forest, ready to explore the endless mysteries that awaited them.\n\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/StorySpark.md",
    "content": "# Story Spark\nA virtual Storyteller for 3 - 6 year old kids providing personalised stories. \n\nInput : {name} , {gender}, {story theme}\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Tz/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Story_generator.md",
    "content": "# Story generator\nThis agent takes a Title of the story as a prompt and it will generate a story [Story generator](https://illa.ai/ai-agent/ILAex4p1C7Us/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Study Pal",
    "content": "Introducing Study Pal, your learning companion. Just tell him the topic, and it'll unravel the essential knowledge, making complex subjects feel like a breeze!\nFast try: https://illa.ai/ai-agent/ILAex4p1C72E/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Study Roadmap",
    "content": "# Study Roadmap\nSelect a topic and proficiency level (beginner/medium/advanced), and receive a structured learning plan.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sn/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Study plan generator.md",
    "content": "# Study plan generator.md\nYou enter the syllabus, days left before exam and enter subject name. It provides day to day schedule giving a organized timetable \nCheck it: https://illa.ai/ai-agent/ILAex4p1C7ZE/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Study-Buddy.md",
    "content": "# Study Buddy\nThis is an AI-based chat study buddy that helps you study. It can offer motivation, help in studying and making last-minute study schedules.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7wv/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/StudyBuddy.md",
    "content": "# StudyBuddy\nA guide on enhancing academic productivity and performance through proven study techniques and habits. \nFast try: https://illa.ai/ai-agent/ILAfx4p1C7un/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Sudoku Solver.md",
    "content": "# Sudoku Solver\n\nAI agent that can solve 9*9 Sudoku problems.\nPlease provide input as numbers and replace blank cells with values of 0.\n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7VK/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Suggest-Something-to-Cook.md",
    "content": "# Suggest-Something-to-Cook\nThe prompt suggests asking for suggestions on what dishes can be prepared using the available food items.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70F/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SymptomAnalyizer.md",
    "content": "# Symptom Analyizer\nThis agent is a symptom analyzer with the primary task of evaluating patient symptoms and suggesting the appropriate medical specialist and immediate measures.\nFast try: https://illa.ai/ai-agent/ILAex4p1C735/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/SynonymFinder.md",
    "content": "# Synonym Generator\n\nThis AI agent returns the synonym of the given word.\n\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uA/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TACG.ai.md",
    "content": "# TACG.ai\nCreate personalized website \"Terms and Conditions\" effortlessly. \nOur AI tailors legal content to your unique needs. Say goodbye to generic terms.\n\nFast Try: https://illa.ai/ai-agent/ILAex4p1C7Uf/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TALK.md",
    "content": "# TALK\nThis prompt describes a talk app that focuses on conversations related to mental health, daily stress, behavioral changes, mood, and even jokes.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Wb/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TV series suggester",
    "content": "# TV series suggester\nThis AI Agent will generate TV series name that suit your current mood.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Wq/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TaskTitan.md",
    "content": "# TaskTitan\nTaskTitan: Your personal productivity chatbot! Conquer tasks with expert guidance and motivation. Your sidekick for a supercharged day! 🚀💪\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Tx/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Teacher.md",
    "content": "# Teacher\nThe prompt requests to be taught about a specific topic, followed by a quiz at the end and the provision of answers.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73p/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Tech Stack Finder",
    "content": "# Tech Stack Finder\nThis AI Agent helps you find the perfect tech stack to start your next project.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Zc/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Techo",
    "content": "# Techo\nassistance in guiding individuals on maximizing their use of available technologies by providing easy-to-follow instructions.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71H/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Temperature Converter.md",
    "content": "# Temperature Converter\nConvert the given temperature value in the specified unit of measurement to a different unit.\n\nText format should be like this: 22C, 22c, 70f, 70F\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UP/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TestImpactAI.md",
    "content": "# TestImpactAI\nTestImpactAI: Your A/B testing strategist. Discover ideas and methodologies to measure product or service changes effectively.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VF/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Testing Code generator",
    "content": "# Testing Code generator\nWrite a test for my code.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TG/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Text-to-image-converter.md",
    "content": "# Text to image converter using Pollinations.ai\nGenerate AI images through text descriptions (The images take some time to load)\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C72S/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Text2Hindi.md",
    "content": "# Text2Hindi\n\nTranslates the given English sentences into Hindi without providing explanations or considering the meaning of the input. \nhttps://illa.ai/ai-agent/ILAex4p1C7YA/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TextSentimentAnalyzer.md",
    "content": "# Sentiment Analyzer\n\nThis AI Agent takes a user text as input and then returns its sentiment as output after analysis.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Ug/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TextSummarizer.md",
    "content": "# Text Summarizer\nProvides a brief summary of the given text.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73U/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Thai_Translator.md",
    "content": "# Translator ( ENGLISH to THAI) \n\nThis prompt asks for a description of how to translate English to Thai in less than 100 words.\nFast try:  https://illa.ai/ai-agent/ILAex4p1C7Yr/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/The Companion.md",
    "content": "# The Companion\nThis ai could simulate a understanding virtual companion that engages in conversations, offers empathetic responses, and provides valuable advice during anxiety\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vD/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Tic_tac_toe game.md",
    "content": "# Tic tac toe game\nText \"Start\" to start the game\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TX/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TimeTravelerTom.md",
    "content": "# TimeTravelerTom\nMeet TimeTravelerTom, your historical figure chatbot. Interact with past icons, ask questions, and explore history's gems!\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7rQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TimeTrendPro.md",
    "content": "# TimeTrendPro\nTimeTrendPro: Your time-dependent data analyst. Unlock methods for analyzing and forecasting temporal data patterns effectively.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VC/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TipSplitterCalculator.md",
    "content": "# Tip Splitter Calculator\nThe Tip Splitter Calculator is designed to assist users in determining how to evenly split a bill as well as the tip when dining out together\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vg/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ToGoLang.md",
    "content": "# ToGoLang\nChanges the code you give to Go Language.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7u5/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Top 10 Movie Rankings.md",
    "content": "# Top 10 Movie Rankings\nOutput: Display the rank of the top 10 movies.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7v2/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TourSuggester.md",
    "content": "# Tour Suggester\nThis prompt asks for a description of an AI system that can suggest a place name based on an individual's preferences or desires.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7p4/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TrainingDrillsandExercises.md",
    "content": "# Training Drills and Exercises\nAccess a diverse selection of training drills and exercises tailored to enhance proficiency in your preferred sport.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vj/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Translate English Messages.md",
    "content": "# Translate English Messages\nTranslate messages that are in English into your primary language with grammar check and alternate translations.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XL/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Translation Tutor.md",
    "content": "# Translation Tutor\nAI tutor to Strengthen your language language translation skills and understanding of idiomatic expressions\nLink: https://illa.ai/ai-agent/ILAex4p1C71f/detail\n\n## Demo Chat\n![image](https://github.com/ashuvssut/illa-builder/assets/60546840/c5196860-fcf9-4d6b-9a5b-48a00b8340b1)\n![image](https://github.com/ashuvssut/illa-builder/assets/60546840/14835091-7e4b-44bf-85ed-f063ef055a49)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Translator",
    "content": "# Translator\nThis Ai agent will translate Hinglish language to English language and with grammar correction.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73W/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Translator.md",
    "content": "# Translator\nTranslation service allows you to convert text from any language to another language.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C73G/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Translator2.md",
    "content": "# Translator\nThe prompt is requesting a description of a service or tool that can translate English text into French.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7v1/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TranslatorAurica",
    "content": "% About \n\nAurica is a translator AI bot capable of accurately translating text from Spanish, French, German, and Portuguese into English and vice versa \nwith a focus on fluency, contextual understanding, and natural language processing.\n\n%% Demo: \n\nTry out the translator here:- https://illa.ai/ai-agent/ILAex4p1C7Yg/detail\n\n%% Example of how it works: \n\nUser:\nolá, como vai? você está triste?\n\nAurica\nHello! I'm doing well, thank you. As an AI, I don't have feelings, so I cannot be sad or happy. Is there anything I can help you with?\n\nUser\nWelche Farbe hat der Himmel?\n\nAurica\nThe color of the sky is typically blue. Is there anything else you would like to know?\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TravelBuddy.md",
    "content": " TravelBuddy\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TravelLighter",
    "content": "# TravelLighter\nAI agent to help you travel light on your pocket! Best budget hacks to get you going without breaking the bank.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7so/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Travel_Explorer.md",
    "content": "# Travel Explorer\nAn AI Agent that will provide you with the name and the description of the tourist spots in a city or a country providing the name of the place.\nFast try: https://illa.ai/ai-agent/ILAex4p1C71n/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Travel_Itinerary.md",
    "content": "# Travel Itinerary\nA Travel Itinerary Generator creates personalized travel plans, recommending destinations, accommodations, and activities based on your preferences, saving time\nFast try: https://illa.ai/ai-agent/ILAex4p1C74t/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Trivia Bot.md",
    "content": "# Trivia Bot\nOur Trivia Bot is your gateway to a world of knowledge and fun.\nFast try: https://illa.ai/ai-agent/ILAex4p1C72u/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/TwistedTales AI.md",
    "content": "# TwistedTales AI\nThe TwistedTales AI is an innovative AI system that specializes in crafting unexpected and thrilling plot twists injecting a sense of excitement and suspense.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7uQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Typing test.md",
    "content": "# CodeType - Typing Test Application for Programmers\n\n## Concept Description\n\nCodeType is an innovative online typing test application designed specifically for programmers. It incorporates various features to help coders improve their typing speed, accuracy, and coding skills. By providing real-time compilation, personalized code snippets, and comprehensive analysis, CodeType aims to enhance the coding experience and make the typing test more engaging and productive.\n\n## Key Features\n\n### Programming Language Selection\n\n- Users can choose from a wide range of programming languages, including Python, JavaScript, Java, C++, etc. The choice of language will determine the code snippets they will be typing.\n\n### Diverse Code Snippets\n\n- CodeType provides a collection of code snippets that range in complexity and cover common coding tasks, algorithms, or specific code patterns. This ensures that users have exposure to a variety of coding scenarios during the typing test.\n\n### Real-Time Compilation\n\n- As users type, CodeType performs real-time compilation or interpretation of the code. It immediately detects syntax errors, bugs, and highlights them in the code editor. By providing instant feedback, it helps users identify and correct mistakes as they occur.\n\n### Time Limit and Error Tracking\n\n- Each typing test comes with a customizable time limit. Users need to complete the code within the given time to assess their typing speed and accuracy. CodeType tracks and displays errors, including syntax errors, misspellings, and code structure issues, in real-time or at the end of the test.\n\n### Scoring System\n\n- CodeType implements a comprehensive scoring system that takes into account the number of characters typed, typing speed (words per minute or characters per minute), and the accuracy of the code. Users receive a detailed score report at the end of the test, indicating their performance and areas for improvement.\n\n### Autocomplete and Suggestions\n\n- CodeType includes an intuitive autocomplete and code suggestion feature. This feature assists users by providing suggestions and completing code snippets efficiently. It resembles the autocomplete functionality found in popular integrated development environments (IDEs).\n\n### Customization Options\n\n- CodeType allows users or educators to customize the typing test according to their specific requirements. This customization includes choosing the programming language, adjusting the complexity level of code snippets, and defining the allowed error tolerance. This provides flexibility to match individual learning needs or specific assessment criteria.\n\n### Online Platform and Integration\n\n- CodeType is accessible via an online platform, making it convenient for coders to complete the test remotely. Additionally, CodeType can be integrated into recruitment platforms, learning management systems, and coding education tools. This simplifies tracking and assessment processes, enabling seamless compatibility with existing systems.\n\n### Analysis and Reporting\n\n- After completing the test, users and administrators receive comprehensive reports showcasing their typing speed, accuracy, and areas for improvement. These reports include visual representations of the code, highlighting areas of proficiency and improvement, helping users analyze their performance in detail.\n\n### Feedback and Improvement Suggestions\n\n- CodeType provides valuable feedback on errors and suggests areas for improvement. This feedback is specific to the coding language and highlights common mistakes or coding best practices. Users can work on their weaknesses and enhance their typing skills and coding proficiency.\n\nThe CodeType application aims to create an engaging and effective environment for programmers to test and improve their coding skills while enhancing their typing speed and accuracy.\n#Contribute here -  https://illa.ai/ai-agent/ILAex4p1C7Wm/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/UsabilityTestingScript.md",
    "content": "# Usability Testing Script\nDevelop a script for usability tests, assessing the user experience of a product or feature.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UO/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Used Electronics Price Analyzer.md",
    "content": "# Used Electronics Cost Analyzer\nThis AI will take the details of the device as input from the users and generate a estimated price for it at which it can be sold in the market.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Zv/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/User Research Report.md",
    "content": "# User Research Report\nA report summarizing the background, research methodology, findings, and insights from user research activities, informing product decisions.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70o/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/User-Research-Questionnaire-Template.md",
    "content": "# User Research Questionnaire Template\nProvides details about the type of user research questionnaire template you require. Any specific topics, questions, or sections you want to cover.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7TL/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Userbehavioranalysisreport.md",
    "content": "# User behavior analysis report\nThis prompt describes a report that analyzes user interactions and behaviors within a product or system. \nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vr/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/VideoAdScripter",
    "content": "I just discovered an impressive AI Agent called VideoAdScripter. Check it: https://illa.ai/ai-agent/ILAex4p1C74J/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Virtual Companion.md",
    "content": "#  Virtual Companion\nThis ai could simulate a understanding virtual companion that engages in conversations, offers empathetic responses, and provides valuable advice during anxiety\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vR/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/VirtualPetAdoptionAdvisor.md",
    "content": "# Virtual Pet Adoption Advisor\nFor individuals looking to adopt a pet, this chatbot offers guidance on choosing the right pet based on their lifestyle and preferences.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UZ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Virtual_Historian_AI.md",
    "content": "# Virtual Historian AI\nGet a comprehensive account of any historical subject with detailed information, facts, and engaging narratives.\nFast try: https://illa.ai/ai-agent/ILAex4p1C74g/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/WP Snippet Generator",
    "content": "# WP Snippet Generator\nWP Snippet Generator: A tool for generating WordPress code snippets, assisting theme and plugin developers.\nFast try: https://illa.ai/ai-agent/ILAex4p1C75h/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/WeathEats",
    "content": "From sunny sides to rainy day bites, WeatherEats knows what's on your plate.Let WeatherEats be your weather-wise foodie friend, matching dishes toyour weather:)\nFast try: https://illa.ai/ai-agent/ILAex4p1C73K/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Web Developer Helper.md",
    "content": "# Web Developer Helper\nAn AI agent to help beginners learn about the exciting world of Web Development.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7XW/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Web Development Helper.md",
    "content": "# Web Development Helper\nThis Assistant help to web development\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Yh/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Web development help assistant.md",
    "content": "# Web development help assistant\nYour dedicated web development companion, simplifying the complexities of coding and design.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Uy/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Web styling frameworks.md",
    "content": "# Web styling frameworks\nCreate a simple and example of import framework on HTML for create a beautiful layout for a shop web page.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7YJ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/WeblyAI.md",
    "content": "# WeblyAI\nEffortlessly craft and customize interactive landing pages without coding expertise.\nFast Try: https://illa.ai/ai-agent/ILAex4p1C7WH/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Welcome to Wilcume !.md",
    "content": "# Welcome to Wilcume !\nConverts modern english to old(Shakespearen) english.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tj/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/What's your MBTI.md",
    "content": "# What's your MBTI?\nIn this game, known as the MBTI Personality Test, you will ask a series of questions to me. I will provide answers on a scale of 1 to 5, indicating the level of agreement or disagreement. Once all questions are answered, you can determine my MBTI personality type based on those responses. This type will come with an accompanying definition and explanation outlining the characteristics associated with it.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7eQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/WikiScience.md",
    "content": "# Wiki Science\nThis prompt is requesting the analysis and discussion of recent science news articles in order to enhance one's comprehension of scientific subjects.\n\nFast try: https://illa.ai/ai-agent/ILAex4p1C71e/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Wireframes.md",
    "content": "# UI/UX Wireframes\nCreate wireframes for intuitive user interfaces and seamless user experiences.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7UN/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Word Meaning (Any Language)",
    "content": "#Word Meaning (Any Language)\nA word Meaning Robo that can Translate any word to English. \nFast Try: https://illa.ai/ai-agent/ILAfx4p1C7qp/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Yoda Translator.md",
    "content": "# Yoda Translator\nReturn the given prompt, but written in the manner of Yoda from Star Wars.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73D/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/YouTube Script Generator.md",
    "content": "# YouTube Script Generator\nAn AI Agent that generates a detailed script for a YouTube video for any provided topic.\nFast try: https://illa.ai/ai-agent/ILAex4p1C730/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/Your Anxiety Buddy",
    "content": "# Your Anxiety Buddy\nA Buddy who is also a mental health guru to guide you through the stresses of everyday life.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Vv/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/[AI Agent]Version Control Workflows.md",
    "content": "## Version Control Workflows\nThis agent will explain different version control workflows, such as Git, and their effective usage in collaborative development.\nI just discovered an impressive AI Agent called Version Control Workflows. Check it: https://illa.ai/ai-agent/ILAex4p1C7Vy/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/[Ai Agent] Influencer's Era",
    "content": "I just discovered an impressive AI Agent called Influencer's Era.\nThis Ai agent is for influencers marketing and gathering more audience.\nCheck it: https://illa.ai/ai-agent/ILAex4p1C70r/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/[Ai Agent] Roadmap-generator.md",
    "content": "# Roadmap Generator\nCheck it: https://illa.ai/ai-agent/ILAfx4p1C7qr/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/[Buzzman]The_latest_newsletter.md",
    "content": "# Buzzman:The latest newsletter\nThis prompt allows the user to get latest news in a short and concise manner that is easy to read and understand.\nFast try : https://illa.ai/ai-agent/ILAex4p1C70j/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/[Direc-AI-tor]Movie script generator.md",
    "content": "# Direc-AI-tor : Movie script generator\nAn AI tool that generates script of a movie based on a genre, setting/time-period, characters, plot/themes. \nCheck it: https://illa.ai/ai-agent/ILAex4p1C7Zn/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/academic-paraphrase-agent.md",
    "content": "# Academic Paraphrase Agent \nAcademic Paraphrase Age rewrites text with precision, preserving meaning while improving clarity and coherence. Perfect for content creation and avoiding plagia\nFast try: https://illa.ai/ai-agent/ILAex4p1C73L/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ai-movie-critic.md",
    "content": "# AI Movie Critic\nAnalyzes movies and offers in-depth reviews and recommendations based on user preferences.\nFast try: https://illa.ai/ai-agent/ILAex4p1C74k/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/all-things-counter-strike.md",
    "content": "# All Things Counter Strike\n\nAn AI chatbot to fine-tuned to answer questions related to Counter Strike, the epic video game entertaining us all for over 20 years now.\n\nUsers can ask questions related to counter strike in general and also ask the bot to summarize professional counter strike matches.\n\nTry it: https://illa.ai/ai-agent/ILAfx4p1C7r2/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/astrology facts generator",
    "content": "# astrology facts generator\nI just discovered an impressive AI Agent called facts and astrology about his/her birthdate. Check it: https://illa.ai/ai-agent/ILAex4p1C70g/detail\nFast try : https://illa.ai/ai-agent/ILAex4p1C70g/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/bibleQuotes.md",
    "content": "I just discovered an impressive app called Bible Quotes. Check it: https://illa.ai/app/ILAfx4p1C7BA/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/brandnamegenerator.md",
    "content": "Check the new Brand Name Generator which generates new name for your brand. Check it: https://illa.ai/ai-agent/ILAex4p1C7YL/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/career-roadmap-generator.md",
    "content": "# career roadmap generator\nAsk the user for career name they want to follow and provide the roadmap to achieve it.\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7VR/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ch-en-translator-model.md",
    "content": "# NLP Translator\nPrompt should ask user to provide a long article in chinese with emojis included in characters then convert it to english text\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vP/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/chat got",
    "content": "# chat got\nYou are a ChatGOT designed to help users by answering questions, creating unique content, and providing information on diverse subjects. \nFast try: https://illa.ai/ai-agent/ILAex4p1C75M/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/combodia-name-generator",
    "content": "## Cambodia Name Meaning\nThe prompt is asking for a meaningful name to be generated in the Cambodian language for the people of Cambodia.\nI just discovered an impressive AI Agent called Cambodia Name Meaning . Check it: https://illa.ai/ai-agent/ILAex4p1C7T5/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/competitive-analysis-report.md",
    "content": "# Competitive Analysis Report\nPrompt to ask for description outlining a structure and metrics for a competitive analysis report comparing the given product to a competitor's product\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Ux/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/cooking-special-diets",
    "content": "# Cooking for Special Diets\nWelcome to our Cooking for Special Diets AI! \nWe offer guidance and delicious recipes recipes tailored to various dietary needs. \nTo get started, please specify your dietary preference. \nYou can choose from options like \"Vegan,\" \"Gluten-free,\" \"Keto,\" and more. \nIf you have any specific ingredients or dish in mind, feel free to mention that as well.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7W4/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/cooking-techniques-and-tips",
    "content": "# Cooking Techniques and Tips\nWelcome to our Culinary Tips AI! Here, you can learn essential cooking techniques and professional tips to elevate your culinary skills. \nFast try: https://illa.ai/ai-agent/ILAex4p1C7W3/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/cube-root-finder",
    "content": "# Cube root finder\nThis prompt asks the user to input a number and intends to find its cube root.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7p5/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/culinary-adventures",
    "content": "# Culinary Adventures\nGet ready to embark on a flavorful journey, exploring unique ingredients and experimenting with fusion recipes. We're here to inspire your culinary creativity.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xm/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/data-storytelling.md",
    "content": "# Data Storytelling\nThis prompt asks for advice on how to effectively communicate data insights by creating engaging narratives.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VW/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/dictionary",
    "content": "I just discovered an impressive AI Agent called dictionary. Check it: https://illa.ai/ai-agent/ILAex4p1C73x/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/email Marketing Automation",
    "content": "# Email Marketing Automation\nSuggest ways to automate and optimize email marketing campaigns for better conversion rates...\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sw/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/finance-model.md",
    "content": "#FINANCE TRACKER\nSo here is the model url \n\nI just discovered an impressive AI Agent called Finance tracker . \nCheck it: https://illa.ai/ai-agent/ILAex4p1C74d/detail\n\n## Finance Model 💹\nIn this day and age a good finance tracker can not only help you track your \nexpenceses but also to keep it under controll , categorise it and help save money \nby identifying loopholes and irregular spending habits ,\n\n## Features 🔩 \n1. firstly an over budget spent indicator\n2. secondly a finance categoiriser\n3. thirdly an investment tracker, with auto alerts set to inform if an investment underperforms a certain threshold\n4. a net montly expence projection based on past trends and help identify areas to curb expense \n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/game-name-generator",
    "content": "# Game Character Name Generator\nYou need a name for your character in a video game.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Ts/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/gear-equipment-recommendations-ai-agent.md",
    "content": "# Gear and Equipment Recommendations\nThe prompt is requesting a description of gear and equipment recommendations.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Zf/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/grammar corrector",
    "content": "# grammar corrector\nThe prompt is requesting a description of a grammar corrector, without providing any further specifications.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7tf/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/hackername generator.md",
    "content": "# hackername generator\nGenerate and be distinguished with your personalized hackername, from Hacktoberfest 2023; hacknames include forms in leet speech, an encrypted algorithm, and as a signal.\nGet yours here: https://illa.ai/ai-agent/ILAex4p1C7ZM/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/hashtage_generator.md",
    "content": "\"Craft strategic hashtags for sustainable living and eco-products. Boost your campaign's impact.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sj/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/healthyfy.md",
    "content": "# healthify\n By leveraging advanced machine learning algorithms, data sources, and personalized recommendations, this AI agent is committed to users by giving tips.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7th/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/hello_cobol.md",
    "content": "# hello world\nWrite a basic \"Hello, World!\" code in the specified language.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7sd/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/html to jsx converter",
    "content": "# HTML to JSX converter\nThis prompt asks the user to provide a description for an AI agent that converts code from HTML to JSX\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7vQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/job-interview-preparation.md",
    "content": "# Job Interview Preparation\n\nAn AI interview coach that helps users prepare for job interviews.\n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7W0/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/kannada.md",
    "content": "# English to Kannada Translator\nTranslate \"{{input}}\" to Kannada language. This Ai agent will take English text and translated to Kannada.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Wr/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/launch-plan-checklist.md",
    "content": "# Launch Plan Checklist \nDevelop a detailed checklist for an efficient product launch, encompassing all essential tasks and interdependencies.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VH/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/math-and-science-tutor.md",
    "content": "# Math and Science Tutor\nAn AI tutor specializing in mathematics and science subjects, helping students with problem-solving, and explanations.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73J/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/mohit.md",
    "content": "# mohit\nthe ai Agent will generate cyber law and ipr details \nFast try: https://illa.ai/ai-agent/ILAex4p1C7ZF/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/movie_suggent.md",
    "content": "# Movie suggest\nThis AI Agent will generate movie name that suit your current mood.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70U/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/music-recommender.md",
    "content": "# Music Recommender\nPrompt recommend 50 popular songs in worldwide\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7v4/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/ninja-java-script-assistant.md",
    "content": "# JavaScript Coding Assistant\nThis is a chatbot that can help you with coding a JavaScript project. It can assist you with various tasks such as creating, editing, debugging, testing, and deploying your code. It can also suggest best practices, libraries, frameworks, and tools that can enhance your productivity and performance.\nhttps://illa.ai/ai-agent/ILAex4p1C71i/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/nutriSport.md",
    "content": "# nutriSport\nExplore nutritional guidelines and hydration strategies specific to your sport.\nCheck it: https://illa.ai/ai-agent/ILAex4p1C71q/detail\nIssue: [AI Agent idea]Sports Nutrition and Hydration #2404\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/osu! rhythm game coach.md",
    "content": "# osu! rhythm game coach\nThis prompt is asking for a description on how to improve at the game osu!.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7T2/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/personal fitness advisor",
    "content": "# personal fitness advisor\nGet tailored fitness advice based on your specific goals.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ur/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/productivitySongs",
    "content": "# productivitySongs\nGet random songs to increase your focus and productivity and you can work on your task for a long time.\nFast try: https://illa.ai/ai-agent/ILAex4p1C73b/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/qr-scanner.md",
    "content": "# QR Code Generator\nGenerate a QR code\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7v3/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/quantum-computing-problem-solver.md",
    "content": "# Quantum Computing Problem Solver\n\nAI Agent that harnesses quantum computing capabilities to solve complex problems, such as cryptography, drug discovery, and climate modeling.\n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7WO/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/quantum-education-resource.md",
    "content": "# Quantum Education Resource\nProvide resources and learning materials for those interested in quantum topics.\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7W2/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/routines-pal.md",
    "content": "#Routine Pal\nThis agent is about helping parents to create a personalized daily routine for teenagers with autism.\n\nGive it a try: https://illa.ai/ai-agent/ILAex4p1C73O/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/secureCodingPractices.md",
    "content": "# secureCodingPractices\nSimpler coding techniques that help make the code safer by reducing the chance of common security problems and ensuring it's clean and secure.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7YQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/skating-guide.md",
    "content": "#Instructor\nAn AI chatbot that is an ice skating instructor.It teaches user about different fundamental ice skating techniques and also gives tips to improve the skills.\nFast try: https://illa.ai/ai-agent/ILAex4p1C70D/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/smith_the_converter",
    "content": "# SmithTheConverter\nSmith is a AI assisted currency converter that helps you convert the amount from one curreny to another.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7wy/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/snooker-summarizer.md",
    "content": "# Snooker Summarizer\n\nThis agent provides summaries of professional snooker matches. For example, type \"Ronnie O'Sullivan vs Mark Williams most recent match\" in the prompt.\n\nTry it: https://illa.ai/ai-agent/ILAfx4p1C7rP/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/software-architecture-design.md",
    "content": "# Software Architecture Design\nRecommendations for software architectural designs suitable for a specific application type are requested.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7VL/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/space-travel-planner.md",
    "content": "# Space Travel Planner\n\nAn AI that plans and curates space travel experiences, including lunar vacations, asteroid mining tours, and orbital dining.\n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7WN/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/spam detector",
    "content": "# spam detector\nThe prompt requires the development of an AI agent that can identify and prevent spam.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ti/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/strategies for handling errors",
    "content": "This agent will be provide a regex for a given list of strings. Fast try: https://illa.ai/ai-agent/ILAex4p1C7Xn/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/study buddy app",
    "content": "# study buddy app\nyou'd have to enter a topic, types of questions you want to generate and the difficulty level, this ai model would generate a list of questions according to you\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7us/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/the_matrix_quotes.md",
    "content": "# The Matrix Quotes\nGenerate personalized quotes from the Matrix movies.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7qk/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/travel_guide.md",
    "content": "# Travel_guide\nAn AI with knowledge of various places and their optimal visiting times to recommend the best-suited locations based on your current time and location.\nFast try: https://illa.ai/ai-agent/ILAex4p1C7Tw/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/unit-converter.md",
    "content": "# Unit Converter\nAsks for a value with a unit that will be converted to another unit. \nFast try: https://illa.ai/ai-agent/ILAex4p1C73V/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/user persona creator",
    "content": "# user persona creator\nThis prompt asks for a template and guide that can be used to analyze user personas using demographic and behavioral data.\nFast try: https://illa.ai/ai-agent/ILAfx4p1C7ud/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/user-research-report.md",
    "content": "# User Research Report\n\nA report summarizing the background, research methodology, findings, and insights from user research activities, informing product decisions.\n\nCheck it: https://illa.ai/ai-agent/ILAex4p1C7WQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-ai-agents/wthIsThis.md",
    "content": "# wthIsThis\nKnow about anything by typing 'What the heck is {what you want to know}'! Sounds cool, right?\n\nSample - What the heck is Computer Motherboard? \nFast try: https://illa.ai/ai-agent/ILAex4p1C7Xw/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/AI-Image-Gen",
    "content": "VAY - AI is an AI website for creative expression. Users input text or images, adjust a slider to control the number of elements, and instantly generate diverse, \npersonalized art. Whether you seek simplicity or complexity, this AI empowers your artistic vision with limitless possibilities.\n\nFor more info - \nI just discovered an impressive app called VAY - AI. \nCheck it: https://illa.ai/app/ILAfx4p1C7D2/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Anomaly Detection Dashboard with AI Agent",
    "content": "# Anomaly Detection Dashboard with AI Agent\nAnomaly detection is crucial for various applications, such as fraud detection, network security, and quality control. The AI Agent can utilize deep learning or statistical methods\nFast try: https://illa.ai/app/ILAfx4p1C7Dq/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/AskMyDocument.md",
    "content": "# Ask my Document\nAn app to ask any question to an uploaded text document.\nFast try: https://illa.ai/app/ILAfx4p1C72u/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Awesome Avatars.md",
    "content": "# Awesome Avatars\nGenerates random Avatars with different themes to select.\nFast try: https://illa.ai/app/ILAfx4p1C7xB/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Awesome-Notes-App.md",
    "content": "# An Awesome Note taking  App build and deployed using ILLA Builder \nFast try: https://illa.ai/app/ILAfx4p1C7NM/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/BMI Calculator.md",
    "content": "# BMI Calculator\nAn app to calculate BMI.\nFast try: https://illa.ai/app/ILAfx4p1C7DW/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/BMI_Notif",
    "content": "#BMI_Notification\nAn app to learn the basics of ILLA APP development. \nFast try: https://illa.ai/app/ILAfx4p1C7yF/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Barcode-Generator.md",
    "content": "## BARCODE GENERATOR \n# Component Used\n- Image\n- Button\n- Input\n- Container\n- Text\n\n# About\n- Barcode generator is an illa app used to create barcode for product id entered by user using code128 and show it to the user on image component!\n\nGive it a try, Click the link to join the team and check the APP: [link](https://illa.ai/app/ILAfx4p1C7ZD/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Bible Quotes.md",
    "content": "I just discovered an impressive app called Bible Quotes. Check it: https://illa.ai/app/ILAfx4p1C7BA/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Birthday-wisher.md",
    "content": "# Birthday wisher\nBirthday wisher app\nFast try: https://illa.ai/app/ILAfx4p1C7E2/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Blog_template.md",
    "content": "# Blog Template\nA Basic Blog Template\nLink: https://illa.ai/app/ILAfx4p1C7yx/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Bug-Reporting.md",
    "content": "# Bug-Reporting\nFast try: https://illa.ai/app/ILAfx4p1C7XL/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/CRUD APP",
    "content": "# CRUD APP\nThis is ILLACRUD! 🚀 An app where you can :\n1) Create / Add new  books 📗\n2) Read / Get Books 📖\n3) Update comments & ratings of books as per your choice 📙\n4) Delete books 📕\nFast try: https://illa.ai/app/ILAfx4p1C7w1/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/CSV_To_MYSQL.md",
    "content": "# CSV To MYSQL\nUpload a CSV and write it to your MySQL database\nTry it Now: https://illa.ai/app/ILAfx4p1C7CI/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Calculator App.md",
    "content": "# Calculator App\nA simple calculator which calculates some basic operations.\nFast try: https://illa.ai/app/ILAfx4p1C7Il/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Calculator.md",
    "content": "# Calculator\nA simple Calculator using illa builder\nFast try: https://illa.ai/app/ILAfx4p1C7HV/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Case Converter.md",
    "content": "I just discovered an impressive app called Case Converter. Check it: https://illa.ai/app/ILAfx4p1C7Yn/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Cats API.md",
    "content": "# Cats API\nConsuming kitten API.\nFast try: https://illa.ai/app/ILAfx4p1C7EV/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/CheatCodeGenius",
    "content": "The CheatCodeGenius is a powerful tool that simplifies the process of finding cheat codes for your favorite video game.\n\nCheck it: https://illa.ai/app/ILAfx4p1C75T/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Contact Developers.md",
    "content": "# Contact Developers\nFast try: https://illa.ai/app/ILAfx4p1C7XI/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Crazy-Avatars.md",
    "content": "# Crazy Avatars!\nFast try: https://illa.ai/app/ILAfx4p1C7YB/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/CrudApp.md",
    "content": "# CRUD \nFast try: https://illa.ai/app/ILAfx4p1C7Yx/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Data-entry.md",
    "content": "I just discovered an impressive app called Data Entry. Check it: https://illa.ai/app/ILAfx4p1C7xQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Date to Timestamp.md",
    "content": "# Date to Timestamp\nConvert human-readable month/day/year date to epoch\nFast try: https://illa.ai/app/ILAfx4p1C7Co/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Day_Planner.md",
    "content": "# Day_Planner Application\nNavigate your tasks effortlessly with this application - your ultimate Day_Planner companion.\nFast try: https://illa.ai/app/ILAfx4p1C7NH/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Dialogue Generator.md",
    "content": "# Dialogue Generator\n\n### What is Dialogue Generator?\nDialogue Generator is your go-to tool when you're in search of iconic movie dialogues. Just feed in a search term, and watch as the magic unfolds. We will fetch every dialogue that houses your term, and as a bonus, we'll tag it with the movie name and its release date.\n\n### How to Use?\n\nSearch: Type your desired term into the search bar.\nGet Results: With a click or a tap, watch as dialogues from various movies that contain your term populate your screen.\nDive Deep: Along with each dialogue, get acquainted with the movie it's from and the year it lit the big screen.\n\n### Why Dialogue Generator?\nBecause every word has a story and every movie adds a flavor to it. Dive into the world of movies, one dialogue at a time.\n\nThank you for choosing Dialogue Generator. Where words meet the world of films.\n\nCheck it out here : [Dialogue Generator](https://illa.ai/app/ILAfx4p1C7IM/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/DrugWiki.md",
    "content": "# Drug Wiki\n\nThis App can let you know the details of popular drugs as per your input.\n\nFast try: https://illa.ai/app/ILAfx4p1C7zB/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/ENGLISH-HINDI-Translation-App",
    "content": "# ENGLISH ➡️ HINDI || Translation App\nThis is the translation app which will convert your English based text into Hindi.\nSo try it out!\nFast try: https://illa.ai/app/ILAfx4p1C7Go/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/EarthLens.md",
    "content": "# EarthLens\nEarthLens: Seamless Maps and Satellite Views for Precision Navigation and Exploration.\nFast try: https://illa.ai/app/ILAfx4p1C714/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/English To Higlish Translater",
    "content": "# English To Higlish Translater\nFast try: https://illa.ai/app/ILAfx4p1C7Bn/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Export Charts",
    "content": "# Export Charts\nA simple app to download charts.\nFast try: https://illa.ai/app/ILAfx4p1C7YJ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Feedback_Form.md",
    "content": "# Feedback Form\n<br>\nThis is a layout of a simple feedback form to take feedback from customers.\n<br>\nI just discovered an impressive app called Feedback Form. Check it: https://illa.ai/app/ILAfx4p1C75P/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Funky_Calculator.md",
    "content": "I just discovered an impressive app called Funky Calculator App. Check it: https://illa.ai/app/ILAfx4p1C7Ex/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/GiftSwap.md",
    "content": "# GiftSwap\nCreate a guest list for a gift swap. View the list. Simple for demo for now. Uses appwrite for the database.\nFast try: https://illa.ai/app/ILAfx4p1C7Ze/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/GitHubStatsGenerator.md",
    "content": "# GitHub Stats Generator\nIntroducing the GitHub Stats Generator: Your GitHub stats, streaks, and top programming languages, all in one simple app. Track your coding journey effortlessly!\nFast try: https://illa.ai/app/ILAfx4p1C7MY/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Github Issue Finder.md",
    "content": "# Github Issue Finder\nA issue finder app which find open issues on github made using illa builder and github api\nFast try: https://illa.ai/app/ILAfx4p1C7IB/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Github Stats Generator",
    "content": "# GitHub Stats Generator\nFast try: https://illa.ai/app/ILAfx4p1C7Yq/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Github Stats.md",
    "content": "# Github Stats Checker\nA website that shows User's their github stats when they enter their Username.\nFast try: https://illa.ai/app/ILAgx4p1C7AA/detail"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Github Status Generator.md",
    "content": "# Github Status Generator App\nA GitHub status generator app that integrates with the GitHub API collects and displays detailed information about a user's GitHub account.\nFast try: https://illa.ai/app/ILAfx4p1C7Gp/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/GithubActivityGraphGenerator.md",
    "content": "I just discovered an impressive app called Github Activity Graph Generator. Check it: https://illa.ai/app/ILAfx4p1C7Dw/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/GithubRepoStats.md",
    "content": "# Github Repo Stats Generator\nThis app lets you easily view stats for any github repository.\nYou can also copy those stats as markdown for use elsewhere.\nFast try: https://illa.ai/app/ILAfx4p1C7Fu/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/HacktoberFest23.md",
    "content": "# HacktoberFest23\nAn app that allows users to check their badges status in Holopin. Users should be able to enter their GitHub username, and the app will fetch their badges information.\n\nFast try: [HacktoberFest23 App](https://illa.ai/app/ILAfx4p1C7Mw/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Hacktoberfest Treasure Hunt.md",
    "content": "# Hacktoberfest Treasure Hunt #hacktoberfesttreasurehunt\nFast try: https://illa.ai/app/ILAfx4p1C7Mf/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Hex to RGB Color Converter.md",
    "content": "# Hex to RGB converter\nFast try: https://illa.ai/app/ILAfx4p1C7CM/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Hex-RGB-Converter",
    "content": "# Hex to RGB Converter\nConvert HEX to RGB\nFast try: https://builder.illacloud.com/a3385d2894263c3a0ff9b1505b2982ed/deploy/app/ILAfx4p1C72F\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Holopin Board Preview.md",
    "content": "# Holopin Board Preview\nDisplay your Holopin board by using your username\nFast try: https://illa.ai/app/ILAfx4p1C7Of/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Holopin Profile Viewer.md",
    "content": "# Holopin Profile Viewer\nShows a Holopin profile based on the username\nFast try: https://illa.ai/app/ILAfx4p1C7DV/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Imaginate Creator.md",
    "content": "# Imaginate Creator\nImaginate Creator: Your all-in-one content powerhouse. Add text, headings, code, images, checklists, and lists with ease.\nFast try: https://illa.ai/app/ILAfx4p1C7zq/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/InputField.md",
    "content": "# input field\nFast try: https://illa.ai/app/ILAfx4p1C7yy/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Inventory management.md",
    "content": "# Inventory management\nFast try: https://illa.ai/app/ILAfx4p1C7XJ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Joker.md",
    "content": "# Joker\nA fun Jokes Generator. Provide you with daily dose of jokes! Check it: https://illa.ai/app/ILAfx4p1C72A/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Jotfusion.md",
    "content": "# Jotfusion\nJOTFUSION is your go-to online text editor, a powerful editing tool.\nFast Try: https://illa.ai/app/ILAfx4p1C7y1/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/LeetCodeStatsCardGenerator.md",
    "content": "# LeetCode Stats Card Generator\nInstantly display your LeetCode account stats in a sleek, customizable card with the LeetCode Stats Card Generator.\nFast try: https://illa.ai/app/ILAfx4p1C7Jx/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/MPLgen",
    "content": "# MPLgen\n  Music PlayList Generator\nFast try: https://illa.ai/app/ILAfx4p1C7IL/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Max Portfolio.md",
    "content": "# Max Portfolio\nA personal portfolio website powered by ILLA Cloud.\nFast Try: https://illa.ai/app/ILAfx4p1C7y0/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Monitor Repositories Star, Forks and Issues.md",
    "content": "# Monitor Repositories Star, Forks and Issues. \nCheck it: https://illa.ai/app/ILAfx4p1C7IJ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Newsletter",
    "content": "# Newsletter\nThe simple newsletter page.\nFast try: https://illa.ai/app/ILAfx4p1C7NQ/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Notes App.md",
    "content": "# Notes App\nFast try: https://illa.ai/app/ILAfx4p1C7NM/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/NotesUsingSupabaseCRUD.md",
    "content": "# Note-Taking App\nA simple note taking having CRUD operations using Supabase\nFast try: https://illa.ai/app/ILAfx4p1C7CR/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Payment_form.md",
    "content": "#Payment Form\n<br>\nThis is a basic design of a payment form. It asks the user for contact and payment information.\n<br>\nI just discovered an impressive app called Payment Form. Check it: https://illa.ai/app/ILAfx4p1C7Eg/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Pearls-Illa-App.md",
    "content": "# Pearl's Illa App\nFor Initial, added random image app. It will show random image for every refresh\nFast try: https://illa.ai/app/ILAgx4p1C7r4/detail\n\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/PokemonGenerator.md",
    "content": "# Pokemon Generator App\nI just discovered an impressive app called Pokemon Generator App.\nFast try: https://illa.ai/app/ILAfx4p1C7Ao/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Pokémon Stats.md",
    "content": "# Pokémon Stats\nGets the basic stats of a Pokémon using PokéAPI.\nFast try: https://illa.ai/app/ILAfx4p1C7ys/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Predict Number",
    "content": "# Predict Number\nPredict the Number\" is a fun and challenging app that tests your guessing skills. Are you good at estimating numbers?\nFast try: https://illa.ai/app/ILAfx4p1C7GC/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Product CRUD App Using TiDB.md",
    "content": "# Product CRUD App Using TiDB\nA simple web app which performs CRUD operations using TiDB.\nFast try: https://illa.ai/app/ILAfx4p1C72T/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/ProgrammingMemeGenerator.md",
    "content": "# Programming Memes Generator\nIntroducing Programming Memes Generator! Powered by ILLA Builder, it creates hilarious tech memes with a single click. Laugh, share, and enjoy the coding humor effortlessly! 🚀😂\n\n### What have been used to make it?\nWe have used this [API](https://rapidapi.com/kaushalsharma880-GAglnDIvTy/api/programming-memes-images/) to build this application.\n\n### How to Use?\nClick on the Generate button and it will generate funny programming meme for you.\n\n### Why Programming Memes Generator?\nBecause every programmer loves to visualize memes related to coding and tech to have fun!\n\nThank you for choosing Programming Memes Generator. Where programming meets the world of memes and fun.\n\nCheck it out here : [Programming Memes Generator](https://illa.ai/app/ILAfx4p1C7I2/detail)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/QR Code Generator.md",
    "content": "# QR Code Generator\nA simple QR Code Generator Application\nFast try: https://illa.ai/app/ILAfx4p1C7Cf/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/QR-Generator.md",
    "content": "# QR Generator\nFast try: https://illa.ai/app/ILAfx4p1C7YA/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/README.md",
    "content": "# Awesome ILLA Apps\n\n<div align=\"center\">\n  <a href=\"https://illa.ai\">\n    <img alt=\"Awesome ILLA Cloud\" src=\"https://cdn.illacloud.com/official-website/img/hacktoberFest/illa_awesome.svg\"/>\n  </a>\n</div>\n\n\n## How to contribute\n*If you also want to receive a Digital Reward Kit from Hacktoberfest, please register for a [Hacktoberfest](https://hacktoberfest.com/) account during the event period.*\n\n### Step 1: Visit https://illa.ai and create an account. \n\n![signup](https://cdn.illacloud.com/official-website/img/github/1.gif)\n\n### Step 2: Click the Create button to create a new App. \n\n**Create App**\n![image](https://cdn.illacloud.com/official-website/img/github/3.png)\n\n### Step 3: Contribute your created content to the Community.\n**App**\n![5](https://cdn.illacloud.com/official-website/img/github/5.gif)\n\n### Step 4: Submit a pull request on GitHub.\n1. Click the \"Submit PR\" button in the Community, and we will help you copy the information and automatically redirect you to the specified page.\n![image](https://cdn.illacloud.com/official-website/img/github/6.png)\n\n2. Create a new file and name it as: {{Your created content name}}.md\n\n3. Paste the copied content as the file content.\n\n4. Commit changes\n\n5. Propose changes\n\n6. Create pull request\n\n7. 🎉 Finished\n   \n![7](https://cdn.illacloud.com/official-website/img/github/7.gif)\n\n## Awesome list\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Restaurantmenu.md",
    "content": "I just made an impressive app called Restaurant Menu. Check it: https://illa.ai/app/ILAfx4p1C7Gi/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Resume_Builder.md",
    "content": "# Resume Builder  \n\nResume builder which creates resume \n- from user input by entering details  \n- Copy resume in latex / markdown\n\nTry Now: https://illa.ai/app/ILAfx4p1C7Xt/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Say Hello.md",
    "content": "# Say Hello\nFast try: https://illa.ai/app/ILAfx4p1C7Hy/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Sentimental-Analysis.md",
    "content": "# Sentimental Analysis\nFast try: https://illa.ai/app/ILAfx4p1C7YK/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Sentimental.md",
    "content": "# Sentimental\n\nThis app takes the user input and returns the sentiment of the text after successful analysis.\n\nFast try: https://illa.ai/app/ILAfx4p1C7zG/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Signin_form.md",
    "content": "# Signin Form\n<br>\nThis is the basic layout of a sign in form that can be used in different websites for the user to log in or create a new account\n<br>\nI just discovered an impressive app called Signin Form. Check it: https://illa.ai/app/ILAfx4p1C7xz/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Simple Form.md",
    "content": "# Simple Form\nThis is simple form which has just UI\nFast try: https://illa.ai/app/ILAfx4p1C7Nz/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Simple-portfolio-page",
    "content": "# Portfolio Page\nFast try: https://illa.ai/app/ILAfx4p1C7Fo/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/SimpleSignupForm.md",
    "content": "I just discovered an impressive app called Simple Sign up form. \nCheck it: https://illa.ai/app/ILAfx4p1C7Zt/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/SpamDetection.md",
    "content": "# Spam Detection App\n\nThis App analyzes your text content and determines whether the given text is SPAM or HAM.\n\nFast try: https://illa.ai/app/ILAfx4p1C7AU/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Stable-Diffusion-XL",
    "content": "Stable-Diffusion-XL\nBuild a free retrieval model using Illa to fetch the latest stable Diffusion XL language model from Hugging Face, and you can choose Lora.\nI just discovered an impressive app called Stable-Diffusion-XL. Check it: https://illa.ai/app/ILAfx4p1C7Iw/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/StatsGenerator",
    "content": "# GitHub Stats Generator\nIllaApp that generates GitHub Stats\nFast try: https://builder.illacloud.com/a3385d2894263c3a0ff9b1505b2982ed/deploy/app/ILAfx4p1C72U\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Subscription_form.md",
    "content": "# Subscription form\n<br>\nThis is a simple design of a subscription form which can be used in different websites for users to subscribe to weekly newsletters or anything else.\n<br>\nI just discovered an impressive app called Subscription form. Check it: https://illa.ai/app/ILAfx4p1C72j/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Survey Form",
    "content": "# SurveyForm\nA survey form that will take public opinions on AI revolution\nFast try: https://illa.ai/app/ILAfx4p1C7zD/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/TODO Application.md",
    "content": "# TODO Application\nNavigate your tasks effortlessly with this application - your ultimate to-do companion.\nFast try: https://illa.ai/app/ILAfx4p1C7NH/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Text to Image Generator.md",
    "content": "# Text to Image Generator\nA simple app which generate image from prompt\nFast try: https://illa.ai/app/ILAfx4p1C74R/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/To-Do List App.md",
    "content": "# To-Do List App\nFast try: https://illa.ai/app/ILAfx4p1C7BR/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Translator HiNDI to English",
    "content": "#  Translator\nFast try: https://illa.ai/app/ILAfx4p1C7CO/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/TriviaGenerator.md",
    "content": "# Trivia Time!!\nGives general knowledge trivia\nFast try: https://illa.ai/app/ILAfx4p1C7As/detail\n\n![image](https://github.com/illacloud/illa-builder/assets/99721216/a48c6f39-a64a-41f1-9b0c-48a667c0a058)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/TwitterClone",
    "content": "A simple tweet thing: Check it: https://illa.ai/app/ILAfx4p1C7D4/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Url Decoder APP",
    "content": "# Url Decoder\nFast try: https://illa.ai/app/ILAfx4p1C7CA/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/WaifuGenerator.md",
    "content": "# Anime Waifu Generator \nThis app can show images of different female characters of anime by taking certain tags as a input and returning images and info about the female characters with the help of API.\nFast try: https://illa.ai/app/ILAfx4p1C7zF/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/Weather-App.md",
    "content": "# Weather App\nIt allows users to check the current weather conditions for a specific location. The app fetches weather data from the OpenWeatherMap API and displays it in a easy-to-read format.\nFast try: https://illa.ai/app/ILAfx4p1C7Nc/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/contactDevelopers.md",
    "content": "# Contact Developers\n\nLet developers connect with developers around the world with this connection form. Fast try: https://illa.ai/app/ILAfx4p1C713/detail\n\n## Glimpse\n\n![image](https://github.com/illacloud/illa-builder/assets/98116504/8d23b654-7eeb-4ebf-8fa2-a1c150752128)\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/hello-word.md",
    "content": "I just discovered an impressive app called HelloWorld. Check it: https://illa.ai/app/ILAfx4p1C7J2/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/rgbaColorGenerator.md",
    "content": "# RGBA color generator\nA simple rgba color generator.\nFast try: https://illa.ai/app/ILAfx4p1C7Ia/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/simple-login-form.md",
    "content": "# Simple Login Form\nFast try: https://illa.ai/app/ILAfx4p1C7Fr/detail\n"
  },
  {
    "path": "hacktoberfest2023/awesome-illa-apps/simple-portfolio-template",
    "content": "# Simple portfolio template\nThis app is a simple portfolio template\nFast try: https://illa.ai/app/ILAfx4p1C7xM/detail\n"
  },
  {
    "path": "illa-builder-frontend.conf",
    "content": "server {\n    listen 80;\n    server_name localhost;\n    access_log  /dev/stdout;\n    error_log   /dev/stderr;\n    root /opt/illa/illa-builder-frontend/;\n    index index.html;\n    gzip on;\n\n    proxy_ssl_server_name on;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection \"upgrade\";\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_set_header X-Forwarded-Host $host;\n    proxy_set_header Accept-Encoding \"\";\n\n    sub_filter_once off;\n    location / {\n        try_files $uri $uri/ /index.html;\n        expires -1;\n    }\n\n    location /assets {\n        expires 1y;\n    }\n}\n\n"
  },
  {
    "path": "nginx.conf",
    "content": "user  nginx;\nworker_processes  1;\n\nerror_log  /var/log/nginx/error.log warn;\npid        /var/run/nginx.pid;\n\nevents {\n    worker_connections  1024;\n}\n\n\nhttp {\n    include       /etc/nginx/mime.types;\n    default_type  application/octet-stream;\n\n    log_format main '\"$time_local\" client=$remote_addr '\n               'method=$request_method request=\"$request\" '\n               'request_length=$request_length '\n               'status=$status bytes_sent=$bytes_sent '\n               'body_bytes_sent=$body_bytes_sent '\n               'referer=$http_referer '\n               'http_x_forwarded_for=$http_x_forwarded_for '\n               'user_agent=\"$http_user_agent\" '\n               'upstream_addr=$upstream_addr '\n               'upstream_status=$upstream_status '\n               'request_time=$request_time '\n               'upstream_response_time=$upstream_response_time '\n               'upstream_connect_time=$upstream_connect_time '\n               'upstream_header_time=$upstream_header_time';\n\n    access_log  /var/log/nginx/access.log  main;\n\n    sendfile        on;\n\n    keepalive_timeout  65;\n\n    include /etc/nginx/conf.d/*.conf;\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"illa\",\n  \"description\": \"Help developers build business tools more efficiently.\",\n  \"repository\": \"git@github.com:illacloud\",\n  \"private\": true,\n  \"author\": \"illa Cloud\",\n  \"license\": \"Apache-2.0\",\n  \"version\": \"0.0.0\",\n  \"scripts\": {\n    \"dev\": \"turbo run dev --filter=illa-builder \",\n    \"dev:self\": \"turbo run dev --filter=illa-builder --filter=illa-cloud-fe\",\n    \"build-cloud\": \"NODE_OPTIONS=--max-old-space-size=12288 turbo run build-cloud --filter=illa-builder\",\n    \"build-self\": \"NODE_OPTIONS=--max-old-space-size=12288 turbo run build-self --filter=illa-builder --filter=illa-cloud-fe\",\n    \"prepare\": \"husky install\",\n    \"format\": \"prettier --write \\\"apps/**/*.{ts,tsx}\\\"\",\n    \"lint\": \"eslint \\\"apps/**/src/**/**.{ts,tsx}\\\" --config \\\".eslintrc.js\\\"\",\n    \"lint:fix\": \"eslint --fix \\\"apps/**/src/**/**.{ts,tsx}\\\" --config \\\".eslintrc.js\\\"\",\n    \"test\": \"turbo run test\",\n    \"ts-check\": \"turbo run ts-check\"\n  },\n  \"dependencies\": {\n    \"@emotion/react\": \"^11.11.1\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\"\n  },\n  \"devDependencies\": {\n    \"@commitlint/cli\": \"^18.4.3\",\n    \"@commitlint/config-conventional\": \"^18.4.3\",\n    \"@trivago/prettier-plugin-sort-imports\": \"^4.3.0\",\n    \"@types/node\": \"^18.18.13\",\n    \"@types/react\": \"^18.2.38\",\n    \"@types/react-dom\": \"^18.2.17\",\n    \"@vitejs/plugin-basic-ssl\": \"^1.0.1\",\n    \"@vitejs/plugin-react-swc\": \"^3.5.0\",\n    \"eslint\": \"^8.54.0\",\n    \"eslint-config-illa\": \"workspace:*\",\n    \"husky\": \"^8.0.3\",\n    \"lint-staged\": \"^15.1.0\",\n    \"prettier\": \"^3.1.0\",\n    \"turbo\": \"^1.10.16\",\n    \"typescript\": \"^5.3.2\",\n    \"vite\": \"^4.5.0\",\n    \"vite-plugin-checker\": \"^0.6.2\",\n    \"vite-plugin-svgr\": \"^4.2.0\"\n  },\n  \"pnpm\": {\n    \"overrides\": {\n      \"react\": \"$react\",\n      \"react-dom\": \"$react-dom\",\n      \"@types/react\": \"$@types/react\",\n      \"@types/react-dom\": \"$@types/react-dom\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/eslint-config-illa/index.js",
    "content": "module.exports = {\n  parser: \"@typescript-eslint/parser\",\n  env: {\n    es6: true,\n    browser: true,\n    node: true,\n  },\n  settings: {\n    react: {\n      version: \"detect\",\n    },\n  },\n  extends: [\n    \"plugin:react/recommended\",\n    \"plugin:react-hooks/recommended\",\n    \"prettier\",\n  ],\n  plugins: [\"@typescript-eslint/eslint-plugin\", \"unused-imports\", \"import\"],\n  parserOptions: {\n    ecmaFeatures: {\n      jsx: true,\n    },\n    ecmaVersion: 2020,\n  },\n  rules: {\n    \"react/react-in-jsx-scope\": \"off\",\n    \"import/default\": \"off\",\n    \"react/no-unknown-property\": [\"error\", { ignore: [\"css\"] }],\n    \"react-hooks/exhaustive-deps\": ['error'],\n    \"@typescript-eslint/no-unused-vars\": \"off\",\n    \"unused-imports/no-unused-imports\": \"error\",\n    \"unused-imports/no-unused-vars\": [\n      \"warn\",\n      { \"vars\": \"all\", \"varsIgnorePattern\": \"^_\", \"args\": \"after-used\", \"argsIgnorePattern\": \"^_\" }\n    ]\n  },\n}\n"
  },
  {
    "path": "packages/eslint-config-illa/package.json",
    "content": "{\n  \"name\": \"eslint-config-illa\",\n  \"version\": \"0.0.0\",\n  \"main\": \"index.js\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@typescript-eslint/eslint-plugin\": \"^6.7.2\",\n    \"@typescript-eslint/parser\": \"^6.7.2\",\n    \"eslint-config-prettier\": \"^8.10.0\",\n    \"eslint-config-react\": \"^1.1.7\",\n    \"eslint-import-resolver-typescript\": \"^3.6.1\",\n    \"eslint-plugin-import\": \"^2.28.1\",\n    \"eslint-plugin-jsx-a11y\": \"^6.7.1\",\n    \"eslint-plugin-react\": \"^7.32.2\",\n    \"eslint-plugin-react-hooks\": \"^4.6.0\",\n    \"eslint-plugin-unused-imports\": \"^3.0.0\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  }\n}\n"
  },
  {
    "path": "packages/tsconfig/base.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/tsconfig\",\n  \"display\": \"Default\",\n  \"compilerOptions\": {\n    \"target\": \"ESNext\",\n    \"noEmit\": true,\n    \"useDefineForClassFields\": true,\n    \"lib\": [\"DOM\", \"DOM.Iterable\", \"ESNext\"],\n    \"allowJs\": false,\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"react-jsx\"\n  },\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "packages/tsconfig/package.json",
    "content": "{\n  \"name\": \"tsconfig\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"license\": \"MIT\",\n  \"publishConfig\": {\n    \"access\": \"public\"\n  }\n}\n"
  },
  {
    "path": "packages/tsconfig/react.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/tsconfig\",\n  \"display\": \"EmotionReact\",\n  \"extends\": \"./base.json\",\n  \"compilerOptions\": {\n    \"jsxImportSource\": \"@emotion/react\"\n  }\n}\n"
  },
  {
    "path": "pnpm-workspace.yaml",
    "content": "packages:\n  - \"apps/*\"\n  - \"packages/illa-design/packages/*\"\n  - \"packages/illa-public-component/*\"\n  - \"packages/*\"\n"
  },
  {
    "path": "turbo.json",
    "content": "{\n  \"$schema\": \"https://turbo.build/schema.json\",\n  \"pipeline\": {\n    \"build\": {\n      \"outputs\": [\"dist/**\"]\n    },\n    \"ts-check\": {\n      \"dependsOn\": [\"^ts-check\"]\n    },\n    \"preview\": {\n      \"dependsOn\": [\"build\"]\n    },\n    \"dev\": {\n      \"cache\": false,\n      \"persistent\": true\n    },\n    \"build-cloud\": {\n      \"outputs\": [\"dist/**\"]\n    },\n    \"build-self\": {\n      \"outputs\": [\"dist/**\"]\n    }\n  }\n}\n"
  }
]